【问题标题】:missing EOF from HTTP stream without Transfer-Encoding chunked没有传输编码分块的 HTTP 流中缺少 EOF
【发布时间】:2013-09-15 04:03:47
【问题描述】:

我正在使用 Netty 4 通过 HTTP 流式传输内容。内容是动态生成的,因此无法提前知道内容长度。我现有的非网络代码写入OutputStream,所以我在OutputStream 周围编写了一个简单的包装器,它接受写入并将它们放入ByteBuf,当它已满时,它将它作为@ 的有效负载写入987654326@。在对OutputStream 进行任何写入之前,我会发送一个带有OK 状态代码的非完整HttpResponse

当对流调用关闭时,我发送本地 ByteBuf 中尚未发送的任何内容,然后发送LastHttpContent.EMPTY_LAST_CONTENT

我看到 wget 是它获取所有字节,然后坐下来等待流结束。如果我将 Transfer-Encoding: Chunked 标头放在初始响应中,则一切正常。

我可以在HttpObjectEncoder 中看到处理 LastHttpContent 消息的一些差异,这是我尝试分块传输标头的线索。我不清楚的是区别是什么以及为什么 EOF 似乎没有在没有标头的情况下发送,即使所有字节都已发送并且我正在发送LastHttpContent.EMPTY_LAST_CONTENT

编辑:

我可以通过对 Netty 4 示例中的 HttpStaticFileServerHandler 进行简单修改来重现此行为。我正在使用this class 将文件发送回客户端,this(需要 Guava)是我从HttpStaticFileServerHandler 修改的channelRead0 方法,它不是设置内容长度并将文件直接写入频道,而是通过ByteBuffHttpOutputStream 将文件复制到通道,该通道通过DefaultHttpContent 发送1 MB 的输出块,在close 上发送LastHttpContent.EMPTY_LAST_CONTENT。如果我删除 Transfer-Encoding 标头的设置: (response.headers().set(Names.TRANSFER_ENCODING, Values.CHUNKED)) 则使用 wget 获取文件永远不会完成。 afaict,我正在正确发送流,它看起来HttpObjectEncoder 应该正确处理 LastHttpContent,但还没有 EOF。

【问题讨论】:

    标签: netty


    【解决方案1】:

    我认为这只是在 master 中修复,并将成为 4.0.9.Final 的一部分

    https://github.com/netty/netty/pull/1787

    【讨论】:

    • 我认为您需要在写入 LastHttpContent 后关闭频道,因为您没有设置任何内容长度。
    • 我怀疑这会起作用,但这不是完全击败了客户端要求保持活动连接吗?
    • 除非你指定 Content-Length 并且不使用分块编码,否则知道内容结束的唯一方法是连接结束。
    • 那么keep-alive和流式内容返回客户端是相互排斥的吗?
    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 2023-03-16
    • 2013-05-08
    • 2018-02-23
    • 1970-01-01
    相关资源
    最近更新 更多