7

I'm playing with Jetty GzipHandler and it seems to work rather strangely: It only compresses already compressed files.

My whole setup is

GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setHandler(myHandler);
server.setHandler(gzipHandler);

The browser (Chromium) always sends a header containing

Accept-Encoding:gzip,deflate,sdch

so according to the documentation

GZIP Handler This handler will gzip the content of a response if:

  • The filter is mapped to a matching path
  • The response status code is >=200 and <300
  • The content length is unknown or more than the minGzipSize initParameter or the minGzipSize is 0 (default)
  • The content-type is in the comma separated list of mimeTypes set in the mimeTypes initParameter or if no mimeTypes are defined the content-type is not "application/gzip"
  • No content-encoding is specified by the resource

it should work for both. I'm only unsure about the path part, but without having specified any, I'd expect it to work for both or neither.

I used window.location.reload(true) to force reload. The headers are rather long so, I'm linking them: css and png.

I've tried to set some properties, but without any success. Should I ever find jetty-servlets-9.1.3.v20140225-sources.jar, I'll debug it. The question is: Why does GzipHandler decide to compress only compressed files? It's perfectly deterministic: jpg and png get compressed (no matter how small) and no other files do.

Update

Via setMimeTypes I could exclude the images. I debugged it and I'm still having no clue, why other static resources never get compressed. I double checked that myHandler treats them all uniformly (they all get served directly from a precomputed Map<String, byte[]>).

Cœur
  • 37,241
  • 25
  • 195
  • 267
maaartinus
  • 44,714
  • 32
  • 161
  • 320

3 Answers3

11

Here is how I configured the GzipHandler in Jetty 9.3.7:

GzipHandler gzipHandler = new GzipHandler();
gzipHandler.setIncludedMimeTypes("text/html", "text/plain", "text/xml", 
            "text/css", "application/javascript", "text/javascript");
gzipHandler.setHandler(myHandler);
handlerList.addHandler(gzipHandler);

In this case, myHandler was an instance of ResourceHandler. By default, the Gzip Handler only gzips responses to GET requests with a response code in the 200 range.

Max
  • 15,157
  • 17
  • 82
  • 127
  • And what is handlerList type? Can you post the full code and does this go in my @Configuration class? – Lucky Aug 08 '16 at 13:45
  • 1
    `handlerList` is of type `HandlerList`. Basically my code looks like this: `Server s = ...;` `HandlerList handlerList = new HandlerList();` `handlerList.add(...);` `s.setHandlerList(handlerList);` `handlerList.start();` `s.start();` I don't use `@Configuration` so I can't answer that question. – Max Aug 08 '16 at 20:52
  • Thanks. I use embedded maven jetty in my pom.xml. Is there any possibility the above code can be integrated in my embedded jetty? – Lucky Aug 09 '16 at 04:05
4

For the next person that comes along, here's how to enable request decompression, where handler is a class the extends org.eclipse.jetty.server.handler.AbstractHandler. The important parts for request decompression are includeMethods, which defaults to GET only, and the inflateBuffer, which needs to be > 0 but defaults to 0. The Code:

    //create server using given threadpool
    Server server = new Server(8080);

    GzipHandler gzipHandler = new GzipHandler();
    gzipHandler.setIncludedMethods("PUT", "POST", "GET");
    gzipHandler.setInflateBufferSize(2048);
    gzipHandler.setHandler(handler);
    server.setHandler(gzipHandler);

    server.start();
    server.join();
stringy05
  • 6,511
  • 32
  • 38
2

We could use GzipFilter and achieve this result. Jetty documentation of GzipFilter provides list of parameters supported with lot of details. To enable it programmatically, refer this question.

GzipFilter is basically a server side filter and is very efficient in handling compression needs.

Sample Filter configuration

<filter>
 <filter-name>GZipFilter</filter-name>
 <display-name>Jetty's GZip Filter</display-name>
 <description>Filter that zips all the content on-the-fly</description>
 <filter-class>org.mortbay.servlet.GzipFilter</filter-class>
 <init-param>
  <param-name>mimeTypes</param-name>
  <param-value>text/html</param-value>
 </init-param>
</filter>

<filter-mapping>
 <filter-name>GZipFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>
Community
  • 1
  • 1
Sairam Krish
  • 10,158
  • 3
  • 55
  • 67
  • I guess, you're right, but using the Filter looks like way more work that doing the compression myself (which has the disadvantage that it may be buggy). What I did so far is handling static resources by precomputed compressed data - rather simpler. – maaartinus Aug 08 '14 at 02:25
  • don't reinvent the wheel. Don't write compression logic manually. It has been solved many times. Adding a filter may look complex but it's not. I have updated my answer with filter configuration, if that helps – Sairam Krish Aug 08 '14 at 05:45
  • Actually, I've reinvented the wheel and it was probably simpler than getting the filter running (as I'm using no filters yet and no XML and whatever). I'm using it currently for prefetched resources only (this is currently enough; I keep them all both compressed and uncompressed in memory). – maaartinus Sep 04 '14 at 04:29
  • 1
    GzipFilter is deprecated in jetty >8 and GzipHandler should be used. Now I'm figuring out how .. – Karussell Apr 05 '16 at 20:49
  • 2
    Not only is GzipFilter deprecated, it's been replaced by a no-op stub that has no effect. See: https://eclipse.googlesource.com/jetty/org.eclipse.jetty.project/+/master/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/GzipFilter.java – sihil May 25 '16 at 12:19