【问题标题】:gzip compression of chunked encoding response?gzip压缩分块编码响应?
【发布时间】:2011-07-13 22:20:36
【问题描述】:

我正在尝试让我的网络服务器正确地 gzip 一个块编码的 http 响应。

我对非 gzip 响应的理解是它看起来像这样:

<the response headers>

然后对于每个块,

<chunk length in hex>\r\n<chunk>\r\n

最后是一个零长度的块:

0\r\n\r\n

我试图让 gzip 压缩工作,我可以使用一些帮助来确定实际应该返回什么。该文档暗示应该压缩整个响应,而不是压缩每个块:

HTTP servers sometimes use compression (gzip) or deflate methods to optimize transmission.
Chunked transfer encoding can be used to delimit parts of the compressed object.
In this case the chunks are not individually compressed. Instead, the complete payload 
is compressed and the output of the compression process is chunk encoded.

我尝试对整个内容进行 gzip 压缩并返回响应,即使没有分块,但它不起作用。我尝试将 Content-Encoding 标头设置为“gzip”。有人可以解释必须对上述方案进行哪些更改以支持块的 gzip 压缩吗?谢谢。

【问题讨论】:

    标签: http gzip chunked-encoding


    【解决方案1】:

    如果其他答案不够清楚:

    首先,您使用 zlib 压缩正文(这可以在流中完成,因此您不需要一次将整个内容存储在内存中,这就是分块的重点)。

    然后你以块的形式发送压缩体(可能是由 gzip 流提供的,用块头来声明它的长度),带有 Content-Encoding: gzip 和 Transfer-Encoding: chunked headers(并且没有内容长度标头)。

    如果您使用 gzip 或 zcat 或一些此类实用程序进行压缩,它可能无法正常工作。需要是zlib。如果您正在创建块然后压缩它们,那肯定是行不通的。如果您认为自己做对了,但它不起作用,您可以尝试进行数据包跟踪,并根据该信息和收到的任何错误消息提出问题。

    【讨论】:

    【解决方案2】:

    您 gzip 内容,然后才应用分块编码:

    “由于“分块”是 HTTP/1.1 接收者需要理解的唯一传输编码,它在分隔持久连接上的消息方面起着至关重要的作用。每当将传输编码应用于有效负载主体时请求,应用的最终传输编码必须是“分块”的。如果将传输编码应用于响应有效负载主体,那么应用的最终传输编码必须是“分块”,或者必须通过关闭连接来终止消息. 当使用“分块”传输编码时,它必须是用于形成消息体的最后一个传输编码。“分块”传输编码不得在消息体中多次应用。"

    (HTTPbis Part1, Section 6.2.1)

    【讨论】:

    • 这里的第一句话真的很混乱。我认为它应该改变......你压缩每个块的主体(我刚刚实现它,它就像一个魅力)。你不 gzip 整个内容然后应用分块编码。您 gzip 每个主体并将块大小标记为压缩字节数组大小。
    • HTTP/1.1 定义了三种方法来区分一个消息在哪里结束和下一个消息开始(HTTP 管道、持久连接):内容长度标头、传输编码标头和最低优先级(如果都没有)以上都是关闭的连接。
    【解决方案3】:

    您可能并未真正发送经过适当压缩的响应。

    尝试在 zlib 中将 window bits 设置为 31。并使用deflateInit2()

    【讨论】:

    • 这对实现做了一些假设。如果要返回压缩文件,他只是使用“gzip”命令压缩文件并在设置 Content-Encoding: gzip 标头时返回该文件怎么办?输出是否相同?
    • HTTP 标准确实需要使用 zlib 库。 gzip 命令将输出更多标头,但应该与大多数其他 HTTP 客户端/服务器中使用的 zlib 兼容。
    • 发帖者更有可能没有设置Content-Length 标头或发送块响应不正确。或者忘记了一些基本的东西,比如标题后面的换行符。
    • 如果他发送的是分块的,那么不应该有 Content-Length 标头。当然,在他发送非分块并且“不起作用”的情况下,则需要 Content-Length。 OP 可能对他遇到的问题更有帮助,因为他的理解至少看起来是正确的。鉴于问题是在 3 月份,他可能很早就开始工作或放弃了。我最近不得不实际实现这一点,我认为用 gzip 压缩文件并传输它不起作用。您关于在 zlib 中将窗口位设置为 31 的建议非常有帮助,谢谢。
    猜你喜欢
    • 2012-12-02
    • 1970-01-01
    • 2012-02-12
    • 2014-02-20
    • 1970-01-01
    • 2011-12-06
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    相关资源
    最近更新 更多