Search code examples
gzipdropwizardgzipinputstream

EOFException: null while applying gzip to dropwizard along with Filter


We are facing exception using dropwizard-core:1.1.2 while trying to add gzip content-encoding at service response headers. The details are as follows:

GzipFilter.class

public class GzipFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Content-Encoding", "gzip");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
    }

    public void destroy() {
    }
}

Service.class

@Override
public void run(DocumentServiceConfig config, Environment environment) throws Exception {
    Injector injector = createInjector(config, environment);



environment.jersey().register(injector.getInstance(SomeResource.class));
     environment.servlets().addFilter("Gzip-Filter", GzipFilter.class).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "/*");

config.yml

gzip:
  enabled: true
  minimumEntitySize: 256B
    bufferSize: 32KB

Exception stack trace for 500 API response -

WARN  [2017-08-04 00:48:20,713] org.eclipse.jetty.server.HttpChannel: /clients/v2
! java.io.EOFException: null
! at java.util.zip.GZIPInputStream.readUByte(GZIPInputStream.java:268)
! at java.util.zip.GZIPInputStream.readUShort(GZIPInputStream.java:258)
! at java.util.zip.GZIPInputStream.readHeader(GZIPInputStream.java:164)
! at java.util.zip.GZIPInputStream.<init>(GZIPInputStream.java:79)
! at io.dropwizard.jetty.BiDiGzipHandler.wrapGzippedRequest(BiDiGzipHandler.java:100)
! at io.dropwizard.jetty.BiDiGzipHandler.handle(BiDiGzipHandler.java:64)
! at org.eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:56)
! at org.eclipse.jetty.server.handler.StatisticsHandler.handle(StatisticsHandler.java:169)
! at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132)
! at org.eclipse.jetty.server.Server.handle(Server.java:564)
! at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
! at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251)
! at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279)
! at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110)
! at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124)
! at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:122)
! at org.eclipse.jetty.util.thread.strategy.ExecutingExecutionStrategy.invoke(ExecutingExecutionStrategy.java:58)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:201)
! at org.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:133)
! at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672)
! at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590)
! at java.lang.Thread.run(Thread.java:745)

Solution

  • Confused though whether or not I should answer this myself. Yet, since the details for the update are semi resolving the issue hence answering this myself.

    Went ahead describing the same to Dropwizard#Issues#2126

    Quoting @arteam here to provide the solution to the current implementation.

    I believe Dropwizard does gzip compression automatically. The support for gzip is enabled by default (see http://www.dropwizard.io/1.1.2/docs/manual/configuration.html#gzip). So, if the client supports decompression by sending a request with the Accept-Encoding:gzip header, org.eclipse.jetty.server.handler.gzip.GzipHandler will compress the response and add the Content-Encoding: gzip header.

    Well the question still remains though, for which I am still not marking this as an answer to this question:

    Why your custom filter doesn't work is not clear, maybe your filter is executed before the Jersey servlet and it rewrites the header.

    So all that was needed was to implement the service.yml changes as:

    gzip:
      enabled: true
      minimumEntitySize: 256B
        bufferSize: 32KB
    

    and not implement any CustomFilter which ends up overriding the current implementation and not just override but result in the titled exception.

    Another point to note is, that this shall be tested against the response size of both more and less than the minimumEntitySize as specified in the configuration.