我正在尝试实现一个http服务器(使用netty),它不仅提供“常规”html页面,而且还提供大文件。因此,我想在我的管道中使用ChunkedWriteHandlerHttpContentCompressor
当前,此管道初始化如下:

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字节),一切正常。但一旦请求的文件变大(我的测试文件大约350MB),浏览器(在chrome和firefox中测试)就会报告接收到的正文的编码部分出现问题。chrome说ERR_CONTENT_DECODING_FAILED,firefox说类似source file could not be read
我做错了什么吗?我必须在飞行中操纵管道吗?在此提前感谢您的帮助!

最佳答案

由于httpcontentcompressor无法理解bytebuf实例,因此需要将写入的块包装成defaulthttpcontent。
所以只需在channelpipeline中放置一个特殊的httpcontentcompressor,它知道如何处理bytebuf实例。像这样的:
https://github.com/eclipse/vert.x/blob/compress/vertx-core/src/main/java/org/vertx/java/core/http/impl/HttpChunkContentCompressor.java
一定要把它放在chunkedwritehandler之前。

09-15 11:36