You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2020/06/23 20:04:09 UTC

[trafficserver] 01/03: Make compress plugin normalization of Accept-Encoding header compatible with normalization in core TS.

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

zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 907a43b6d607a9c727e4c72b82f5c0e80ae9dce4
Author: Walter Karas <wk...@verizonmedia.com>
AuthorDate: Fri Aug 23 19:28:19 2019 -0500

    Make compress plugin normalization of Accept-Encoding header compatible with normalization in core TS.
    
    Specifically, remove parameters on values, but if there is a valid q parameter which is equal to 0.0,
    remove the associated value from the value list.
    
    (cherry picked from commit 15a6890366ff9a791afec71580b0c03f6baccf5e)
---
 plugins/compress/misc.cc                           |  76 ++++++---
 tests/gold_tests/pluginTest/compress/compress.gold | 183 ++++-----------------
 .../pluginTest/compress/compress.test.py           | 139 +++++++++-------
 .../pluginTest/compress/compress_userver.gold      |  21 +++
 4 files changed, 191 insertions(+), 228 deletions(-)

diff --git a/plugins/compress/misc.cc b/plugins/compress/misc.cc
index 4bf579c..56c3fa9 100644
--- a/plugins/compress/misc.cc
+++ b/plugins/compress/misc.cc
@@ -23,6 +23,7 @@
 
 #include "ts/ts.h"
 #include "tscore/ink_defs.h"
+#include "tscpp/util/TextView.h"
 
 #include "misc.h"
 #include <cstring>
@@ -41,40 +42,69 @@ gzip_free(voidpf /* opaque ATS_UNUSED */, voidpf address)
   TSfree(address);
 }
 
+namespace
+{
+// Strips parameters from value.  Returns cleared TextView if a q=f parameter present, where f is less than or equal to
+// zero.
+//
+void
+strip_ae_value(ts::TextView &value)
+{
+  ts::TextView compression{value.take_prefix_at(';')};
+  compression.trim(" \t");
+  while (value) {
+    ts::TextView param{value.take_prefix_at(';')};
+    ts::TextView name{param.take_prefix_at('=')};
+    name.trim(" \t");
+    if (strcasecmp("q", name) == 0) {
+      // If q value is valid and is zero, suppress compression types.
+      param.trim(" \t");
+      if (param) {
+        ts::TextView whole{param.take_prefix_at('.')};
+        whole.ltrim(" \t");
+        if ("0" == whole) {
+          param.trim('0');
+          if (!param) {
+            // Suppress compression type.
+            compression.clear();
+            break;
+          }
+        }
+      }
+    }
+  }
+  value = compression;
+}
+} // end anonymous namespace
+
 void
 normalize_accept_encoding(TSHttpTxn /* txnp ATS_UNUSED */, TSMBuffer reqp, TSMLoc hdr_loc)
 {
   TSMLoc field = TSMimeHdrFieldFind(reqp, hdr_loc, TS_MIME_FIELD_ACCEPT_ENCODING, TS_MIME_LEN_ACCEPT_ENCODING);
-  int deflate  = 0;
-  int gzip     = 0;
-  int br       = 0;
+  bool deflate = false;
+  bool gzip    = false;
+  bool br      = false;
   // remove the accept encoding field(s),
   // while finding out if gzip or deflate is supported.
   while (field) {
-    TSMLoc tmp;
-
-    if (!deflate && !gzip) {
-      int value_count = TSMimeHdrFieldValuesCount(reqp, hdr_loc, field);
-
-      while (value_count > 0) {
-        int val_len = 0;
-        const char *val;
-
-        --value_count;
-        val = TSMimeHdrFieldValueStringGet(reqp, hdr_loc, field, value_count, &val_len);
-
-        if (val_len == static_cast<int>(strlen("br"))) {
-          br = !strncmp(val, "br", val_len);
-        }
-        if (val_len == static_cast<int>(strlen("gzip"))) {
-          gzip = !strncmp(val, "gzip", val_len);
-        } else if (val_len == static_cast<int>(strlen("deflate"))) {
-          deflate = !strncmp(val, "deflate", val_len);
+    int val_len;
+    const char *values_ = TSMimeHdrFieldValueStringGet(reqp, hdr_loc, field, -1, &val_len);
+    if (values_ && val_len) {
+      ts::TextView values(values_, val_len);
+      while (values) {
+        ts::TextView next{values.take_prefix_at(',')};
+        strip_ae_value(next);
+        if (strcasecmp("gzip", next) == 0) {
+          gzip = true;
+        } else if (strcasecmp("br", next) == 0) {
+          br = true;
+        } else if (strcasecmp("deflate", next) == 0) {
+          deflate = true;
         }
       }
     }
 
-    tmp = TSMimeHdrFieldNextDup(reqp, hdr_loc, field);
+    TSMLoc tmp = TSMimeHdrFieldNextDup(reqp, hdr_loc, field);
     TSMimeHdrFieldDestroy(reqp, hdr_loc, field); // catch retval?
     TSHandleMLocRelease(reqp, hdr_loc, field);
     field = tmp;
diff --git a/tests/gold_tests/pluginTest/compress/compress.gold b/tests/gold_tests/pluginTest/compress/compress.gold
index af5b4f0..ff02ed6 100644
--- a/tests/gold_tests/pluginTest/compress/compress.gold
+++ b/tests/gold_tests/pluginTest/compress/compress.gold
@@ -1,5 +1,5 @@
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts/0/gzip, deflate, sdch, br
+> X-Ats-Compress-Test: 0/gzip, deflate, sdch, br
 > Accept-Encoding: gzip, deflate, sdch, br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -8,7 +8,7 @@
 < Content-Length: 46
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts/0/gzip
+> X-Ats-Compress-Test: 0/gzip
 > Accept-Encoding: gzip
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -17,7 +17,7 @@
 < Content-Length: 71
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts/0/br
+> X-Ats-Compress-Test: 0/br
 > Accept-Encoding: br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -26,14 +26,14 @@
 < Content-Length: 46
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts/0/deflate
+> X-Ats-Compress-Test: 0/deflate
 > Accept-Encoding: deflate
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Length: 1049
 
 > GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts/1/gzip, deflate, sdch, br
+> X-Ats-Compress-Test: 1/gzip, deflate, sdch, br
 > Accept-Encoding: gzip, deflate, sdch, br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -42,7 +42,7 @@
 < Content-Length: 71
 
 > GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts/1/gzip
+> X-Ats-Compress-Test: 1/gzip
 > Accept-Encoding: gzip
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -51,21 +51,21 @@
 < Content-Length: 71
 
 > GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts/1/br
+> X-Ats-Compress-Test: 1/br
 > Accept-Encoding: br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Length: 1049
 
 > GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts/1/deflate
+> X-Ats-Compress-Test: 1/deflate
 > Accept-Encoding: deflate
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Length: 1049
 
 > GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts/2/gzip, deflate, sdch, br
+> X-Ats-Compress-Test: 2/gzip, deflate, sdch, br
 > Accept-Encoding: gzip, deflate, sdch, br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -74,7 +74,7 @@
 < Content-Length: 46
 
 > GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts/2/gzip
+> X-Ats-Compress-Test: 2/gzip
 > Accept-Encoding: gzip
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -83,7 +83,7 @@
 < Content-Length: 71
 
 > GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts/2/br
+> X-Ats-Compress-Test: 2/br
 > Accept-Encoding: br
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
@@ -92,15 +92,15 @@
 < Content-Length: 46
 
 > GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts/2/deflate
+> X-Ats-Compress-Test: 2/deflate
 > Accept-Encoding: deflate
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Length: 1049
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts2/0/gzip
-> Accept-Encoding: gzip
+> X-Ats-Compress-Test: 0/gzip;q=0.666
+> Accept-Encoding: gzip;q=0.666
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
@@ -108,8 +108,8 @@
 < Content-Length: 71
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts2/0/gzip
-> Accept-Encoding: gzip
+> X-Ats-Compress-Test: 0/gzip;q=0.666x
+> Accept-Encoding: gzip;q=0.666x
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
@@ -117,97 +117,33 @@
 < Content-Length: 71
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts2/0/br
-> Accept-Encoding: br
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: br
-< Vary: Accept-Encoding
-< Content-Length: 46
-
-> GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts2/0/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts2/1/gzip
-> Accept-Encoding: gzip
+> X-Ats-Compress-Test: 0/gzip;q=#0.666
+> Accept-Encoding: gzip;q=#0.666
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
 < Vary: Accept-Encoding
 < Content-Length: 71
 
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts2/1/gzip
-> Accept-Encoding: gzip
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: gzip
-< Vary: Accept-Encoding
-< Content-Length: 71
-
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts2/1/br
-> Accept-Encoding: br
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts2/1/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts2/2/gzip
-> Accept-Encoding: gzip
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: gzip
-< Vary: Accept-Encoding
-< Content-Length: 71
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts2/2/gzip
-> Accept-Encoding: gzip
+> GET http://ae-0/obj0 HTTP/1.1
+> X-Ats-Compress-Test: 0/gzip; Q = 0.666
+> Accept-Encoding: gzip; Q = 0.666
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
 < Vary: Accept-Encoding
 < Content-Length: 71
 
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts2/2/br
-> Accept-Encoding: br
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: br
-< Vary: Accept-Encoding
-< Content-Length: 46
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts2/2/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts3/0/deflate
-> Accept-Encoding: deflate
+> X-Ats-Compress-Test: 0/gzip;q=0.0
+> Accept-Encoding: gzip;q=0.0
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Length: 1049
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts3/0/gzip
-> Accept-Encoding: gzip
+> X-Ats-Compress-Test: 0/gzip;q=-0.1
+> Accept-Encoding: gzip;q=-0.1
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
@@ -215,82 +151,29 @@
 < Content-Length: 71
 
 > GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts3/0/br
-> Accept-Encoding: br
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: br
-< Vary: Accept-Encoding
-< Content-Length: 46
-
-> GET http://ae-0/obj0 HTTP/1.1
-> X-Ats-Compress-Test: ts3/0/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts3/1/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts3/1/gzip
-> Accept-Encoding: gzip
+> X-Ats-Compress-Test: 0/aaa, gzip;q=0.666, bbb
+> Accept-Encoding: aaa, gzip;q=0.666, bbb
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
 < Vary: Accept-Encoding
 < Content-Length: 71
 
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts3/1/br
-> Accept-Encoding: br
+> GET http://ae-0/obj0 HTTP/1.1
+> X-Ats-Compress-Test: 0/ br ; q=0.666, bbb
+> Accept-Encoding:  br ; q=0.666, bbb
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: br
 < Vary: Accept-Encoding
 < Content-Length: 46
 
-> GET http://ae-1/obj1 HTTP/1.1
-> X-Ats-Compress-Test: ts3/1/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts3/2/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts3/2/gzip
-> Accept-Encoding: gzip
+> GET http://ae-0/obj0 HTTP/1.1
+> X-Ats-Compress-Test: 0/aaa, gzip;q=0.666 , 
+> Accept-Encoding: aaa, gzip;q=0.666 , 
 < HTTP/1.1 200 OK
 < Content-Type: text/javascript
 < Content-Encoding: gzip
 < Vary: Accept-Encoding
 < Content-Length: 71
 
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts3/2/br
-> Accept-Encoding: br
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Encoding: br
-< Vary: Accept-Encoding
-< Content-Length: 46
-
-> GET http://ae-2/obj2 HTTP/1.1
-> X-Ats-Compress-Test: ts3/2/deflate
-> Accept-Encoding: deflate
-< HTTP/1.1 200 OK
-< Content-Type: text/javascript
-< Content-Length: 1049
-
diff --git a/tests/gold_tests/pluginTest/compress/compress.test.py b/tests/gold_tests/pluginTest/compress/compress.test.py
index 626b74b..f93ce3d 100644
--- a/tests/gold_tests/pluginTest/compress/compress.test.py
+++ b/tests/gold_tests/pluginTest/compress/compress.test.py
@@ -30,7 +30,6 @@ Test.SkipUnless(
     Condition.HasATSFeature('TS_HAS_BROTLI')
 )
 
-
 server = Test.MakeOriginServer("server", options={'--load': '{}/compress_observer.py'.format(Test.TestDirectory)})
 
 def repeat(str, count):
@@ -62,71 +61,103 @@ for i in range(3):
     }
     server.addResponse("sessionfile.log", request_header, response_header)
 
-def curl(ts, name, idx, encodingList):
+def curl(ts, idx, encodingList):
     return (
         "curl --verbose --proxy http://127.0.0.1:{}".format(ts.Variables.port) +
-        " --header 'X-Ats-Compress-Test: {}/{}/{}'".format(name, idx, encodingList) +
+        " --header 'X-Ats-Compress-Test: {}/{}'".format(idx, encodingList) +
         " --header 'Accept-Encoding: {0}' 'http://ae-{1}/obj{1}'".format(encodingList, idx) +
         " >> {0}/compress_long.log 2>&1 ; printf '\n\n' >> {0}/compress_long.log".format(Test.RunDirectory)
     )
 
-def oneTs(name, AeHdr1='gzip, deflate, sdch, br'):
-    global waitForServer
+waitForServer = True
 
-    waitForTs = True
+waitForTs = True
 
-    ts = Test.MakeATSProcess(name)
+ts = Test.MakeATSProcess("ts")
 
-    ts.Disk.records_config.update({
-        'proxy.config.diags.debug.enabled': 0,
-        'proxy.config.diags.debug.tags': 'http|compress|cache',
-        'proxy.config.http.normalize_ae': 0,
-    })
+ts.Disk.records_config.update({
+    'proxy.config.http.cache.http': 0,
+    'proxy.config.diags.debug.enabled': 1,
+    'proxy.config.diags.debug.tags': 'compress',
+    'proxy.config.http.normalize_ae': 0,
+})
 
-    ts.Disk.remap_config.AddLine(
-        'map http://ae-0/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
-        ' @plugin=compress.so @pparam={}/compress.config'.format(Test.TestDirectory)
-    )
-    ts.Disk.remap_config.AddLine(
-        'map http://ae-1/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
-        ' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=1' +
-        ' @plugin=compress.so @pparam={}/compress.config'.format(Test.TestDirectory)
-    )
-    ts.Disk.remap_config.AddLine(
-        'map http://ae-2/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
-        ' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=2' +
-        ' @plugin=compress.so @pparam={}/compress2.config'.format(Test.TestDirectory)
-    )
+ts.Disk.remap_config.AddLine(
+    'map http://ae-0/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
+    ' @plugin=compress.so @pparam={}/compress.config'.format(Test.TestDirectory)
+)
+ts.Disk.remap_config.AddLine(
+    'map http://ae-1/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
+    ' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=1' +
+    ' @plugin=compress.so @pparam={}/compress.config'.format(Test.TestDirectory)
+)
+ts.Disk.remap_config.AddLine(
+    'map http://ae-2/ http://127.0.0.1:{}/'.format(server.Variables.Port) +
+    ' @plugin=conf_remap.so @pparam=proxy.config.http.normalize_ae=2' +
+    ' @plugin=compress.so @pparam={}/compress2.config'.format(Test.TestDirectory)
+)
 
-    for i in range(3):
+for i in range(3):
 
-        tr = Test.AddTestRun()
-        if (waitForTs):
-            tr.Processes.Default.StartBefore(ts, ready=When.PortOpen(ts.Variables.port))
-        waitForTs = False
-        if (waitForServer):
-            tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port))
-        waitForServer = False
-        tr.Processes.Default.ReturnCode = 0
-        tr.Processes.Default.Command = curl(ts, name, i, AeHdr1)
+    tr = Test.AddTestRun()
+    if (waitForTs):
+        tr.Processes.Default.StartBefore(ts, ready=When.PortOpen(ts.Variables.port))
+    waitForTs = False
+    if (waitForServer):
+        tr.Processes.Default.StartBefore(server, ready=When.PortOpen(server.Variables.Port))
+    waitForServer = False
+    tr.Processes.Default.ReturnCode = 0
+    tr.Processes.Default.Command = curl(ts, i, 'gzip, deflate, sdch, br')
 
-        tr = Test.AddTestRun()
-        tr.Processes.Default.ReturnCode = 0
-        tr.Processes.Default.Command = curl(ts, name, i, "gzip")
+    tr = Test.AddTestRun()
+    tr.Processes.Default.ReturnCode = 0
+    tr.Processes.Default.Command = curl(ts, i, "gzip")
 
-        tr = Test.AddTestRun()
-        tr.Processes.Default.ReturnCode = 0
-        tr.Processes.Default.Command = curl(ts, name, i, "br")
+    tr = Test.AddTestRun()
+    tr.Processes.Default.ReturnCode = 0
+    tr.Processes.Default.Command = curl(ts, i, "br")
 
-        tr = Test.AddTestRun()
-        tr.Processes.Default.ReturnCode = 0
-        tr.Processes.Default.Command = curl(ts, name, i, "deflate")
+    tr = Test.AddTestRun()
+    tr.Processes.Default.ReturnCode = 0
+    tr.Processes.Default.Command = curl(ts, i, "deflate")
 
-waitForServer = True
+# Test Aceept-Encoding normalization.
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip;q=0.666")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip;q=0.666x")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip;q=#0.666")
 
-oneTs("ts")
-oneTs("ts2", "gzip")
-oneTs("ts3", "deflate")
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip; Q = 0.666")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip;q=0.0")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "gzip;q=-0.1")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "aaa, gzip;q=0.666, bbb")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, " br ; q=0.666, bbb")
+
+tr = Test.AddTestRun()
+tr.Processes.Default.ReturnCode = 0
+tr.Processes.Default.Command = curl(ts, 0, "aaa, gzip;q=0.666 , ")
 
 tr = Test.AddTestRun()
 tr.Processes.Default.ReturnCode = 0
@@ -136,9 +167,7 @@ tr.Processes.Default.Command = (
 f = tr.Disk.File("compress_short.log")
 f.Content = "compress.gold"
 
-# Have to comment this out, because caching does not seem to be consistent, which is disturbing.
-#
-# tr = Test.AddTestRun()
-# tr.Processes.Default.Command = "echo"
-# f = tr.Disk.File("compress_userver.log")
-# f.Content = "compress_userver.gold"
+tr = Test.AddTestRun()
+tr.Processes.Default.Command = "echo"
+f = tr.Disk.File("compress_userver.log")
+f.Content = "compress_userver.gold"
diff --git a/tests/gold_tests/pluginTest/compress/compress_userver.gold b/tests/gold_tests/pluginTest/compress/compress_userver.gold
new file mode 100644
index 0000000..f3253de
--- /dev/null
+++ b/tests/gold_tests/pluginTest/compress/compress_userver.gold
@@ -0,0 +1,21 @@
+0/gzip, deflate, sdch, br
+0/gzip
+0/br
+0/deflate
+1/gzip, deflate, sdch, br
+1/gzip
+1/br
+1/deflate
+2/gzip, deflate, sdch, br
+2/gzip
+2/br
+2/deflate
+0/gzip;q=0.666
+0/gzip;q=0.666x
+0/gzip;q=#0.666
+0/gzip; Q = 0.666
+0/gzip;q=0.0
+0/gzip;q=-0.1
+0/aaa, gzip;q=0.666, bbb
+0/ br ; q=0.666, bbb
+0/aaa, gzip;q=0.666 ,