Netty - 如何将ChunkedWriteHandler与HttpContentCompressor结合使用

时间:2013-09-24 13:24:45

标签: java http netty http-compression chunked-encoding

我正在尝试实施一个HTTP服务器(使用Netty),它不仅可以提供常规的服务。 html-pages,也是大文件。因此,我想在我的管道中使用ChunkedWriteHandler以及HttpContentCompressor

目前,此管道初始化如下:

pipeline.addLast("decoder", new HttpRequestDecoder());
pipeline.addLast("aggregator", new HttpObjectAggregator(1048576));
pipeline.addLast("encoder", new HttpResponseEncoder());
pipeline.addLast("chunkedWriter", new ChunkedWriteHandler());
pipeline.addLast("deflater", new HttpContentCompressor());
pipeline.addLast(new NettyHandler());

NettyHandler遵循此方案:

@Override
public void channelRead(final ChannelHandlerContext context, final Object message) throws Exception {
    try {
        if (message instanceof HttpRequest) {
            final HttpRequest request = (HttpRequest) message;
            final HttpContext httpContext = new HttpContext(request, context);
            final ChannelFuture future = handleHttpMessage(httpContext);
            httpContext.closeOn(future);
        }
    } finally {
        ReferenceCountUtil.release(message);
    }
}


private ChannelFuture handleHttpMessage(final HttpContext context) {
    //writing to the wire via ChannelHandlerContext.write(...)
    return context.getChannelContext().writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
}

如果我请求/发送小文件(我的测试文件大约是500字节),一切正常。但是一旦请求的文件变大(我的测试文件大约为350 MB),浏览器(使用chrome和firefox进行测试)就会报告有关已接收正文的编码部分的问题。 chrome说ERR_CONTENT_DECODING_FAILED,firefox说source file could not be read

我做了一些根本错误的事吗?我是否必须动态操纵管道?提前感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

您需要将写入的块包装到DefaultHttpContent中,因为HttpContentCompressor不理解ByteBuf实例。

所以只需将一个特殊的HttpContentCompressor放入ChannelPipeline,它知道如何处理ByteBuf实例。像这样:

https://github.com/eclipse/vert.x/blob/compress/vertx-core/src/main/java/org/vertx/java/core/http/impl/HttpChunkContentCompressor.java

请确保将其放在ChunkedWriteHandler之前。

答案 1 :(得分:2)

上面的答案是完全正确的。但是,由于链接似乎已经死亡,这是另一种方法:

不是在下游发送类型为 ByteBuf 的ChunkedInput,而是使用适配器将其包装到类型为 HttpContent 的ChunkedInput。这非常简单:

实现: https://github.com/scireum/sirius/blob/develop/web/src/sirius/web/http/ChunkedInputAdapter.java

我写了一篇简短的博客文章,更深入地解释了解决方案: http://andreas.haufler.info/2014/01/making-http-content-compression-work-in.html