Author: markt
Date: Tue Apr 12 19:14:11 2016
New Revision: 1738855

URL: http://svn.apache.org/viewvc?rev=1738855&view=rev
Log:
Add the ability to express a server side preference order for precompessed 
formats.

Modified:
    tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
    tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java
    tomcat/trunk/webapps/docs/changelog.xml
    tomcat/trunk/webapps/docs/default-servlet.xml

Modified: tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1738855&r1=1738854&r2=1738855&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java 
(original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Tue Apr 
12 19:14:11 2016
@@ -1098,12 +1098,10 @@ public class DefaultServlet extends Http
         Enumeration<String> headers = request.getHeaders("Accept-Encoding");
         PrecompressedResource bestResource = null;
         double bestResourceQuality = 0;
+        int bestResourcePreference = Integer.MAX_VALUE;
         while (headers.hasMoreElements()) {
             String header = headers.nextElement();
             for (String preference : header.split(",")) {
-                if (bestResourceQuality >= 1) {
-                    return bestResource;
-                }
                 double quality = 1;
                 int qualityIdx = preference.indexOf(';');
                 if (qualityIdx > 0) {
@@ -1113,7 +1111,7 @@ public class DefaultServlet extends Http
                     }
                     quality = 
Double.parseDouble(preference.substring(equalsIdx + 1).trim());
                 }
-                if (quality > bestResourceQuality) {
+                if (quality >= bestResourceQuality) {
                     String encoding = preference;
                     if (qualityIdx > 0) {
                         encoding = encoding.substring(0, qualityIdx);
@@ -1122,17 +1120,23 @@ public class DefaultServlet extends Http
                     if ("identity".equals(encoding)) {
                         bestResource = null;
                         bestResourceQuality = quality;
+                        bestResourcePreference = Integer.MAX_VALUE;
                         continue;
                     }
                     if ("*".equals(encoding)) {
                         bestResource = precompressedResources.get(0);
                         bestResourceQuality = quality;
+                        bestResourcePreference = 0;
                         continue;
                     }
-                    for (PrecompressedResource resource : 
precompressedResources) {
+                    for (int i = 0; i < precompressedResources.size(); ++i) {
+                        PrecompressedResource resource = 
precompressedResources.get(i);
                         if (encoding.equals(resource.format.encoding)) {
-                            bestResource = resource;
-                            bestResourceQuality = quality;
+                            if (quality > bestResourceQuality || i < 
bestResourcePreference) {
+                                bestResource = resource;
+                                bestResourceQuality = quality;
+                                bestResourcePreference = i;
+                            }
                             break;
                         }
                     }

Modified: tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java?rev=1738855&r1=1738854&r2=1738855&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java 
(original)
+++ tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java Tue 
Apr 12 19:14:11 2016
@@ -315,6 +315,62 @@ public class TestDefaultServlet extends
     }
 
     /*
+     * Verify preferring of brotli in default configuration for actual Firefox 
and Chrome requests.
+     */
+    @Test
+    public void testBrotliPreference() throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+
+        File appDir = new File("test/webapp");
+
+        long brSize = new File(appDir, "index.html.br").length();
+
+        // app dir is relative to server home
+        Context ctxt = tomcat.addContext("", appDir.getAbsolutePath());
+        Wrapper defaultServlet = Tomcat.addServlet(ctxt, "default",
+                DefaultServlet.class.getName());
+        defaultServlet.addInitParameter("precompressed", "true");
+
+        ctxt.addServletMapping("/", "default");
+        ctxt.addMimeMapping("html", "text/html");
+
+        tomcat.start();
+
+        TestCompressedClient client = new TestCompressedClient(getPort());
+
+        // Firefox 45 Accept-Encoding
+        client.reset();
+        client.setRequest(new String[] {
+                "GET /index.html HTTP/1.1" + CRLF +
+                        "Host: localhost" + CRLF +
+                        "Connection: Close" + CRLF +
+                        "Accept-Encoding: gzip, deflate, br" + CRLF + CRLF });
+        client.connect();
+        client.processRequest();
+        assertTrue(client.isResponse200());
+        List<String> responseHeaders = client.getResponseHeaders();
+        assertTrue(responseHeaders.contains("Content-Encoding: br"));
+        assertTrue(responseHeaders.contains("Content-Length: " + brSize));
+        assertTrue(responseHeaders.contains("Vary: accept-encoding"));
+
+        // Chrome 50 Accept-Encoding
+        client.reset();
+        client.setRequest(new String[] {
+                "GET /index.html HTTP/1.1" + CRLF +
+                        "Host: localhost" + CRLF +
+                        "Connection: Close" + CRLF +
+                        "Accept-Encoding: gzip, deflate, sdch, br" + CRLF + 
CRLF });
+        client.connect();
+        client.processRequest();
+        assertTrue(client.isResponse200());
+        responseHeaders = client.getResponseHeaders();
+        assertTrue(responseHeaders.contains("Content-Encoding: br"));
+        assertTrue(responseHeaders.contains("Content-Length: " + brSize));
+        assertTrue(responseHeaders.contains("Vary: accept-encoding"));
+    }
+
+    /*
      * Test https://bz.apache.org/bugzilla/show_bug.cgi?id=50026
      * Verify serving of resources from context root with subpath mapping.
      */

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1738855&r1=1738854&r2=1738855&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Apr 12 19:14:11 2016
@@ -128,6 +128,11 @@
         Correctly configure the base path for a resources directory provided by
         an expanded JAR file. Patch provided by hengyunabc. (markt)
       </fix>
+      <add>
+        When multiple compressed formats are available and the client does not
+        express a preference, use the server order to determine the preferred
+        format. Based on a patch by gmokki. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">

Modified: tomcat/trunk/webapps/docs/default-servlet.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/default-servlet.xml?rev=1738855&r1=1738854&r2=1738855&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/default-servlet.xml (original)
+++ tomcat/trunk/webapps/docs/default-servlet.xml Tue Apr 12 19:14:11 2016
@@ -109,7 +109,10 @@ directory listings are disabled and debu
         It is also possible to configure the list of precompressed formats.
         The syntax is comma separated list of
         <code>[content-encoding]=[file-extension]</code> pairs. For example:
-        <code>br=.br,gzip=.gz,bzip2=.bz2</code>.
+        <code>br=.br,gzip=.gz,bzip2=.bz2</code>. If multiple formats are
+        specified, the client supports more than one and the client does not
+        express a preference, the order of the list of formats will be treated
+        as the server preference order and used to select the format returned.
   </property>
   <property name="readmeFile">
         If a directory listing is presented, a readme file may also



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to