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