This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 47ec777  Don't send image/webp responses from cache to broswers that 
don't support it (#7104)
47ec777 is described below

commit 47ec777f0c41ba71a208184dbebda691037218fb
Author: Bryan Call <bc...@apache.org>
AuthorDate: Fri Aug 14 11:58:57 2020 -0700

    Don't send image/webp responses from cache to broswers that don't support 
it (#7104)
---
 proxy/http/HttpTransactCache.cc                    | 43 ++++++------
 tests/gold_tests/headers/accept_webp.test.py       | 79 ++++++++++++++++++++++
 tests/gold_tests/headers/gold/accept_webp.gold     | 16 +++++
 .../gold_tests/headers/gold/accept_webp_cache.gold | 16 +++++
 .../gold_tests/headers/gold/accept_webp_jpeg.gold  | 16 +++++
 5 files changed, 150 insertions(+), 20 deletions(-)

diff --git a/proxy/http/HttpTransactCache.cc b/proxy/http/HttpTransactCache.cc
index 8aa3169..622f801 100644
--- a/proxy/http/HttpTransactCache.cc
+++ b/proxy/http/HttpTransactCache.cc
@@ -486,13 +486,6 @@ HttpTransactCache::calculate_quality_of_match(const 
OverridableHttpConfigParams
   @return quality (-1: no match, 0..1: poor..good).
 
 */
-static inline bool
-do_content_types_match(char *type1, char *subtype1, char *type2, char 
*subtype2)
-{
-  return ((is_asterisk(type1) || is_empty(type1) || (strcasecmp(type1, type2) 
== 0)) &&
-          (is_asterisk(subtype1) || is_empty(subtype1) || 
(strcasecmp(subtype1, subtype2) == 0)));
-}
-
 float
 HttpTransactCache::calculate_quality_of_accept_match(MIMEField *accept_field, 
MIMEField *content_field)
 {
@@ -526,6 +519,9 @@ 
HttpTransactCache::calculate_quality_of_accept_match(MIMEField *accept_field, MI
   // Parse the type and subtype of the Content-Type field.
   HttpCompat::parse_mime_type(c_param->str, c_type, c_subtype, sizeof(c_type), 
sizeof(c_subtype));
 
+  // Special case for webp because Safari is has Accept: */*, but doesn't 
support webp
+  bool content_type_webp = ((strcasecmp("webp", c_subtype) == 0) && 
(strcasecmp("image", c_type) == 0));
+
   // Now loop over Accept field values.
   // TODO: Should we check the return value (count) from this?
   accept_field->value_get_comma_list(&a_values_list);
@@ -549,19 +545,25 @@ 
HttpTransactCache::calculate_quality_of_accept_match(MIMEField *accept_field, MI
     char a_type[32], a_subtype[32];
     HttpCompat::parse_mime_type(a_param->str, a_type, a_subtype, 
sizeof(a_type), sizeof(a_subtype));
 
-    //      printf("matching Content-type; '%s/%s' with Accept value 
'%s/%s'\n",
-    //             c_type,c_subtype,a_type,a_subtype);
-
-    // Is there a wildcard in the type or subtype?
-    if (is_asterisk(a_type)) {
-      wildcard_type_present = true;
-      wildcard_type_q       = 
HttpCompat::find_Q_param_in_strlist(&a_param_list);
-    } else if (is_asterisk(a_subtype) && (strcasecmp(a_type, c_type) == 0)) {
-      wildcard_subtype_present = true;
-      wildcard_subtype_q       = 
HttpCompat::find_Q_param_in_strlist(&a_param_list);
-    } else {
-      // No wildcard. Do explicit matching of accept and content values.
-      if (do_content_types_match(a_type, a_subtype, c_type, c_subtype)) {
+    Debug("http_match", "matching Content-type; '%s/%s' with Accept value 
'%s/%s'\n", c_type, c_subtype, a_type, a_subtype);
+
+    bool wildcard_found = true;
+    // Only do wildcard checks if the content type is not image/webp
+    if (content_type_webp == false) {
+      // Is there a wildcard in the type or subtype?
+      if (is_asterisk(a_type)) {
+        wildcard_type_present = true;
+        wildcard_type_q       = 
HttpCompat::find_Q_param_in_strlist(&a_param_list);
+      } else if (is_asterisk(a_subtype) && (strcasecmp(a_type, c_type) == 0)) {
+        wildcard_subtype_present = true;
+        wildcard_subtype_q       = 
HttpCompat::find_Q_param_in_strlist(&a_param_list);
+      } else {
+        wildcard_found = false;
+      }
+    }
+    if (content_type_webp == true || wildcard_found == false) {
+      // No wildcard or the content type is image/webp. Do explicit matching 
of accept and content values.
+      if ((strcasecmp(a_type, c_type) == 0) && (strcasecmp(a_subtype, 
c_subtype) == 0)) {
         float tq;
         tq = HttpCompat::find_Q_param_in_strlist(&a_param_list);
         q  = (tq > q ? tq : q);
@@ -582,6 +584,7 @@ 
HttpTransactCache::calculate_quality_of_accept_match(MIMEField *accept_field, MI
   if ((q == -1.0) && (wildcard_type_present == true)) {
     q = wildcard_type_q;
   }
+
   return (q);
 }
 
diff --git a/tests/gold_tests/headers/accept_webp.test.py 
b/tests/gold_tests/headers/accept_webp.test.py
new file mode 100644
index 0000000..26998fd
--- /dev/null
+++ b/tests/gold_tests/headers/accept_webp.test.py
@@ -0,0 +1,79 @@
+'''
+Test how we handle image/webp
+'''
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+Test.Summary = '''
+Checking that we don't serve image/webp to clients that do not support it
+'''
+
+Test.ContinueOnFail = True
+
+# Define default ATS
+ts = Test.MakeATSProcess("ts")
+server = Test.MakeOriginServer("server")
+
+testName = "accept_webp"
+request_header = {
+    "headers": "GET / HTTP/1.1\r\nHost: www.example.com\r\nAccept: 
image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5\r\n\r\n",
+    "timestamp": "1469733493.993",
+    "body": ""}
+response_header = {
+    "headers": "HTTP/1.1 200 OK\r\nConnection: close\r\nContent-Type: 
image/webp\r\nCache-Control: max-age=300\r\n",
+    "timestamp": "1469733493.993",
+    "body": "xxx"}
+server.addResponse("sessionlog.json", request_header, response_header)
+
+# ATS Configuration
+ts.Disk.records_config.update({
+    'proxy.config.diags.debug.enabled': 1,
+    'proxy.config.diags.debug.tags': 'http_match',
+    'proxy.config.http.cache.ignore_accept_mismatch': 0,
+    'proxy.config.http.insert_response_via_str': 3,
+    'proxy.config.http.cache.http': 1,
+    'proxy.config.http.wait_for_cache': 1,
+})
+
+ts.Disk.remap_config.AddLine(
+    'map http://www.example.com 
http://127.0.0.1:{0}'.format(server.Variables.Port)
+)
+
+# Test 1 - Request with image/webp support from the origin
+tr = Test.AddTestRun()
+tr.Processes.Default.StartBefore(server, 
ready=When.PortOpen(server.Variables.Port))
+tr.Processes.Default.StartBefore(Test.Processes.ts)
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H "Accept: 
image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5" -H 
"Host: www.example.com" http://localhost:{0}/'.format(
+    ts.Variables.port)
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stderr = "gold/accept_webp.gold"
+tr.StillRunningAfter = ts
+
+# Test 2 - Request with image/webp support from cache
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H "Accept: 
image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5" -H 
"Host: www.example.com" http://localhost:{0}/'.format(
+    ts.Variables.port)
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stderr = "gold/accept_webp_cache.gold"
+tr.StillRunningAfter = ts
+
+# Test 3 - Request without image/webp support going to the origin - NOTE: the 
origin can't change the content-type :(
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = 'curl -s -D - -v --ipv4 --http1.1 -H "Accept: 
image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5" -H "Host: 
www.example.com" http://localhost:{0}/'.format(
+    ts.Variables.port)
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Streams.stderr = "gold/accept_webp_jpeg.gold"
+tr.StillRunningAfter = ts
diff --git a/tests/gold_tests/headers/gold/accept_webp.gold 
b/tests/gold_tests/headers/gold/accept_webp.gold
new file mode 100644
index 0000000..9b6dcb4
--- /dev/null
+++ b/tests/gold_tests/headers/gold/accept_webp.gold
@@ -0,0 +1,16 @@
+``
+> GET /``
+> Host: www.example.com``
+> User-Agent: curl/``
+> Accept: 
image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
+``
+< HTTP/1.1 200 OK
+< Content-Type: image/webp
+< Cache-Control: max-age=300
+< Content-Length: 3
+< Date: ``
+< Age: ``
+< Connection: keep-alive
+< Via: http/1.1 `` (ApacheTrafficServer/`` [uScMsSfWpSeN:t cCMp sS])
+< Server: ATS/``
+``
diff --git a/tests/gold_tests/headers/gold/accept_webp_cache.gold 
b/tests/gold_tests/headers/gold/accept_webp_cache.gold
new file mode 100644
index 0000000..5e2cf84
--- /dev/null
+++ b/tests/gold_tests/headers/gold/accept_webp_cache.gold
@@ -0,0 +1,16 @@
+``
+> GET /``
+> Host: www.example.com``
+> User-Agent: curl/``
+> Accept: 
image/webp,image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
+``
+< HTTP/1.1 200 OK
+< Content-Type: image/webp
+< Cache-Control: max-age=300
+< Content-Length: 3
+< Date: ``
+< Age: ``
+< Connection: keep-alive
+< Via: http/1.1 `` (ApacheTrafficServer/`` [uScHs f p eN:t cCHp s ])
+< Server: ATS/``
+``
diff --git a/tests/gold_tests/headers/gold/accept_webp_jpeg.gold 
b/tests/gold_tests/headers/gold/accept_webp_jpeg.gold
new file mode 100644
index 0000000..1e76ccc
--- /dev/null
+++ b/tests/gold_tests/headers/gold/accept_webp_jpeg.gold
@@ -0,0 +1,16 @@
+``
+> GET /``
+> Host: www.example.com``
+> User-Agent: curl/``
+> Accept: image/png,image/svg+xml,image/*;q=0.8,video/*;q=0.8,*/*;q=0.5
+``
+< HTTP/1.1 200 OK
+< Content-Type: image/webp
+< Cache-Control: max-age=300
+< Content-Length: 3
+< Date: ``
+< Age: ``
+< Connection: keep-alive
+< Via: http/1.1 `` (ApacheTrafficServer/`` [uScMsSfWpSeN:t cCMp sS])
+< Server: ATS/``
+``

Reply via email to