2

我正在尝试实现一个 HTTP 服务器(使用 Netty),它不仅提供“常规”html 页面,还提供大文件。因此,我想在我的管道中使用 theChunkedWriteHandler和 the 。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.

我在做一些根本错误的事情吗?我必须即时操作管道吗?在此先感谢您的帮助!

4

2 回答 2

4

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

因此,只需将一个特殊的 HttpContentCompressor 放入知道如何处理 ByteBuf 实例的 ChannelPipeline 中。vert.x项目中的HttpChunkContentCompressor之类的东西。

确保将它放在 ChunkedWriteHandler 之前。

于 2013-09-30T05:25:06.483 回答
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

于 2014-01-07T21:58:55.860 回答