EOFException:将 gzip 与 Filter 一起应用于 dropwizard 时为 null

EOFException: null while applying gzip to dropwizard along with Filter

我们在尝试添加 gzip content-encoding 时遇到使用 dropwizard-core:1.1.2 的异常服务响应 headers。详情如下:

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

异常堆栈跟踪 500 API 响应 -

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.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.run(QueuedThreadPool.java:590)
! at java.lang.Thread.run(Thread.java:745)

不知道我是否应该自己回答这个问题。然而,由于更新的细节是半解决问题因此我自己回答这个问题。

继续向 Dropwizard#Issues#2126

描述相同内容

这里引用@arteam 提供当前实现的解决方案。

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.

好吧,问题仍然存在,为此我仍然没有将其标记为对这个问题的回答:

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

因此,所需要的只是将 service.yml 更改实施为:

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

并且不实施任何最终覆盖当前实施的 CustomFilter,不仅覆盖而且导致标题异常。

另一点需要注意的是,这应该针对大于和小于配置中指定的 minimumEntitySize 的响应大小进行测试。