Class GzipHandler

java.lang.Object
All Implemented Interfaces:
Handler, GzipFactory, HandlerContainer, Container, Destroyable, Dumpable, Dumpable.DumpableContainer, LifeCycle

public class GzipHandler extends HandlerWrapper implements GzipFactory
A Handler that can dynamically GZIP uncompress requests, and compress responses.

The GzipHandler can be applied to the entire server (a gzip.mod is included in the jetty-home) or it may be applied to individual contexts.

Both Request uncompress and Response compress are gated by a configurable DispatcherType check on the GzipHandler. (This is similar in behavior to a Filter configuration you would find in a Servlet Descriptor file (WEB-INF/web.xml)
(Default: DispatcherType.REQUEST).

Requests with a Content-Encoding header with the value gzip will be uncompressed by a GzipHttpInputInterceptor for any API that uses ServletRequest.getInputStream() or ServletRequest.getReader().

Response compression has a number of checks before GzipHandler will perform compression.

  1. Does the request contain a Accept-Encoding header that specifies gzip value?
  2. Is the HttpServletRequest.getMethod() allowed by the configured HTTP Method Filter.
    (Default: GET)
  3. Is the incoming Path allowed by the configured Path Specs filters?
    (Default: all paths are allowed)
  4. Is the Request User-Agent allowed by the configured User-Agent filters?
    (Default: MSIE 6 is excluded)
  5. Is the Response Content-Length header present, and does its value meet the minimum gzip size requirements (default 32 bytes)?
  6. Is the Request Accept header present and does it contain the required gzip value?

When you encounter a configurable filter in the GzipHandler (method, paths, user-agent, mime-types, etc) that has both Included and Excluded values, note that the Included values always win over the Excluded values.

Important note about Default Values: It is important to note that the GzipHandler will automatically configure itself from the MimeType present on the Server, System, and Contexts and the ultimate set of default values for the various filters (paths, methods, mime-types, etc) can be influenced by the available mime types to work with.

ETag (or Entity Tag) information: any Request headers for If-None-Match or If-Match will be evaluated by the GzipHandler to determine if it was involved in compression of the response earlier. This is usually present as a --gzip suffix on the ETag that the Client User-Agent is tracking and handed to the Jetty server. The special --gzip suffix on the ETag is how GzipHandler knows that the content passed through itself, and this suffix will be stripped from the Request header values before the request is sent onwards to the specific webapp / servlet endpoint for handling. If a ETag is present in the Response headers, and GzipHandler is compressing the contents, it will add the --gzip suffix before the Response headers are committed and sent to the User Agent. Note that the suffix used is determined by CompressedContentFormat.ETAG_SEPARATOR

This implementation relies on an Jetty internal HttpOutput.Interceptor mechanism to allow for effective and efficient compression of the response on all Output API usages:

  • ServletOutputStream - Obtained from ServletResponse.getOutputStream() using the traditional Blocking I/O techniques
  • WriteListener - Provided to ServletOutputStream.setWriteListener(javax.servlet.WriteListener) using the new (since Servlet 3.1) Async I/O techniques
  • PrintWriter - Obtained from ServletResponse.getWriter() using Blocking I/O techniques

Historically the compression of responses were accomplished via Servlet Filters (eg: GzipFilter) and usage of HttpServletResponseWrapper. Since the introduction of Async I/O in Servlet 3.1, this older form of Gzip support in web applications has been problematic and bug ridden.