You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/10/10 23:25:00 UTC

svn commit: r1531115 - in /tomcat/trunk: conf/web.xml java/org/apache/catalina/servlets/DefaultServlet.java test/org/apache/catalina/servlets/TestDefaultServlet.java test/webapp/index.html.gz webapps/docs/changelog.xml webapps/docs/default-servlet.xml

Author: markt
Date: Thu Oct 10 21:24:59 2013
New Revision: 1531115

URL: http://svn.apache.org/r1531115
Log:
Fix https://issues.apache.org/bugzilla/show_bug.cgi?id=54095
Add support to the Default Servlet for serving gzipped versions of static resources directly from disk as an alternative to Tomcat compressing them on each request. Patch by Philippe Marschall.

Added:
    tomcat/trunk/test/webapp/index.html.gz   (with props)
Modified:
    tomcat/trunk/conf/web.xml
    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/conf/web.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/conf/web.xml?rev=1531115&r1=1531114&r2=1531115&view=diff
==============================================================================
--- tomcat/trunk/conf/web.xml (original)
+++ tomcat/trunk/conf/web.xml Thu Oct 10 21:24:59 2013
@@ -104,6 +104,10 @@
             <param-name>listings</param-name>
             <param-value>false</param-value>
         </init-param>
+        <init-param>
+            <param-name>gzip</param-name>
+            <param-value>true</param-value>
+        </init-param>
         <load-on-startup>1</load-on-startup>
     </servlet>
 

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=1531115&r1=1531114&r2=1531115&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java (original)
+++ tomcat/trunk/java/org/apache/catalina/servlets/DefaultServlet.java Thu Oct 10 21:24:59 2013
@@ -32,6 +32,7 @@ import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.StringTokenizer;
 
@@ -140,6 +141,12 @@ public class DefaultServlet
 
 
     /**
+     * Should be serve gzip versions of files. By default, it's set to true.
+     */
+    protected boolean gzip = true;
+
+
+    /**
      * The output buffer size to use when serving resources.
      */
     protected int output = 2048;
@@ -277,6 +284,9 @@ public class DefaultServlet
         if (getServletConfig().getInitParameter("readonly") != null)
             readOnly = Boolean.parseBoolean(getServletConfig().getInitParameter("readonly"));
 
+        if (getServletConfig().getInitParameter("gzip") != null)
+            gzip = Boolean.parseBoolean(getServletConfig().getInitParameter("gzip"));
+
         if (getServletConfig().getInitParameter("sendfileSize") != null)
             sendfileSize =
                 Integer.parseInt(getServletConfig().getInitParameter("sendfileSize")) * 1024;
@@ -754,6 +764,19 @@ public class DefaultServlet
             resource.setMimeType(contentType);
         }
 
+        // Serve a gzipped version of the file if present
+        if (gzip
+                && checkIfGzip(request)
+                && resource.isFile()
+                && !path.endsWith(".gz")) {
+            WebResource gzipResource = resources.getResource(path + ".gz");
+            if (gzipResource.exists() && gzipResource.isFile()) {
+                gzipResource.setMimeType(contentType);
+                response.addHeader("Content-Encoding", "gzip");
+                resource = gzipResource;
+            }
+        }
+
         ArrayList<Range> ranges = null;
         long contentLength = -1L;
 
@@ -1681,6 +1704,24 @@ public class DefaultServlet
         return true;
     }
 
+    /**
+     * Check if the user agent supports gzip encoding.
+     *
+     * @param request   The servlet request we are processing
+     * @return boolean true if the user agent supports gzip encoding,
+     * and false if the user agent does not support gzip encoding
+     */
+    protected boolean checkIfGzip(HttpServletRequest request) {
+        Enumeration<String> headers = request.getHeaders("Accept-Encoding");
+        while (headers.hasMoreElements()) {
+            String header = headers.nextElement();
+            if (header.indexOf("gzip") != -1) {
+                return true;
+            }
+        }
+        return false;
+    }
+
 
     /**
      * Check if the if-unmodified-since condition is satisfied.

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=1531115&r1=1531114&r2=1531115&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java (original)
+++ tomcat/trunk/test/org/apache/catalina/servlets/TestDefaultServlet.java Thu Oct 10 21:24:59 2013
@@ -89,6 +89,56 @@ public class TestDefaultServlet extends 
     }
 
     /**
+     * Verify serving of gzipped resources from context root.
+     */
+    @Test
+    public void testGzippedFile() throws Exception {
+
+        Tomcat tomcat = getTomcatInstance();
+
+        File appDir =
+            new File("test/webapp");
+
+        File gzipIndex = new File(appDir, "index.html.gz");
+        long gzipSize = gzipIndex.length();
+
+        File index = new File(appDir, "index.html");
+        long indexSize = index.length();
+
+        // app dir is relative to server home
+        tomcat.addWebapp(null, "", appDir.getAbsolutePath());
+
+        tomcat.start();
+
+        TestGzipClient gzipClient = new TestGzipClient(getPort());
+
+        gzipClient.reset();
+        gzipClient.setRequest(new String[] {
+                "GET /index.html HTTP/1.1" + CRLF +
+                "Host: localhost" + CRLF +
+                "Connection: Close" + CRLF +
+                "Accept-Encoding: gzip" + CRLF + CRLF });
+        gzipClient.connect();
+        gzipClient.processRequest();
+        assertTrue(gzipClient.isResponse200());
+        List<String> responseHeaders = gzipClient.getResponseHeaders();
+        assertTrue(responseHeaders.contains("Content-Length: " + gzipSize));
+
+        gzipClient.reset();
+        gzipClient.setRequest(new String[] {
+                "GET /index.html HTTP/1.1" + CRLF +
+                "Host: localhost" + CRLF +
+                "Connection: Close" + CRLF+ CRLF });
+        gzipClient.connect();
+        gzipClient.processRequest();
+        assertTrue(gzipClient.isResponse200());
+        responseHeaders = gzipClient.getResponseHeaders();
+        assertTrue(responseHeaders.contains("Content-Type: text/html"));
+        assertFalse(responseHeaders.contains("Content-Encoding: gzip"));
+        assertTrue(responseHeaders.contains("Content-Length: " + indexSize));
+    }
+
+    /**
      * Test https://issues.apache.org/bugzilla/show_bug.cgi?id=50026
      * Verify serving of resources from context root with subpath mapping.
      */
@@ -308,4 +358,16 @@ public class TestDefaultServlet extends 
             return true;
         }
     }
+
+    private static class TestGzipClient extends SimpleHttpClient {
+
+        public TestGzipClient(int port) {
+            setPort(port);
+        }
+
+        @Override
+        public boolean isResponseBodyOK() {
+            return true;
+        }
+    }
 }

Added: tomcat/trunk/test/webapp/index.html.gz
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/webapp/index.html.gz?rev=1531115&view=auto
==============================================================================
Binary file - no diff available.

Propchange: tomcat/trunk/test/webapp/index.html.gz
------------------------------------------------------------------------------
    svn:mime-type = application/x-gzip

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1531115&r1=1531114&r2=1531115&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Oct 10 21:24:59 2013
@@ -141,6 +141,12 @@
         Port storeconfig functionality, which can persist to server.xml and
         context.xml runtime container configuration changes. (remm)
       </add>
+      <add>
+        <bug>54095</bug>: Add support to the Default Servlet for serving
+        gzipped versions of static resources directly from disk as an
+        alternative to Tomcat compressing them on each request. Patch by
+        Philippe Marschall. (markt)
+      </add>
       <fix>
         <bug>54708</bug>: Change the name of the working directory for the ROOT
         application (located under $CATALINA_BASE/work by default) from _ to

Modified: tomcat/trunk/webapps/docs/default-servlet.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/default-servlet.xml?rev=1531115&r1=1531114&r2=1531115&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/default-servlet.xml (original)
+++ tomcat/trunk/webapps/docs/default-servlet.xml Thu Oct 10 21:24:59 2013
@@ -94,6 +94,12 @@ directory listings are disabled and debu
         expensive. Multiple requests for large directory listings can consume
         significant proportions of server resources.
   </property>
+  <property name="gzip">
+        If a gzipped version of a file exists (a file with <code>.gz</code>
+        appended to the file name located alongside the original file), Tomcat
+        will serve the gzipped file if the user agent supports gzip and this
+        option is enabled. [true]
+  </property>
   <property name="readmeFile">
         If a directory listing is presented, a readme file may also
         be presented with the listing. This file is inserted as is



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