Author: markt Date: Tue Apr 12 19:17:59 2016 New Revision: 1738856 URL: http://svn.apache.org/viewvc?rev=1738856&view=rev Log: Add the ability to express a server side preference order for pre-compessed formats. Based on a patch by gmokki. This closes #30
Modified: tomcat/tc8.5.x/trunk/ (props changed) tomcat/tc8.5.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java tomcat/tc8.5.x/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml tomcat/tc8.5.x/trunk/webapps/docs/default-servlet.xml Propchange: tomcat/tc8.5.x/trunk/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Tue Apr 12 19:17:59 2016 @@ -1 +1 @@ -/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850 +/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855 Modified: tomcat/tc8.5.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java?rev=1738856&r1=1738855&r2=1738856&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java (original) +++ tomcat/tc8.5.x/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Tue Apr 12 19:17:59 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/tc8.5.x/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java?rev=1738856&r1=1738855&r2=1738856&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java (original) +++ tomcat/tc8.5.x/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java Tue Apr 12 19:17:59 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/tc8.5.x/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1738856&r1=1738855&r2=1738856&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original) +++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Tue Apr 12 19:17:59 2016 @@ -123,6 +123,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/tc8.5.x/trunk/webapps/docs/default-servlet.xml URL: http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/default-servlet.xml?rev=1738856&r1=1738855&r2=1738856&view=diff ============================================================================== --- tomcat/tc8.5.x/trunk/webapps/docs/default-servlet.xml (original) +++ tomcat/tc8.5.x/trunk/webapps/docs/default-servlet.xml Tue Apr 12 19:17:59 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