38

我试图让我的网络服务器正确地 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 压缩吗?谢谢。

4

3 回答 3

37

如果其他答案不够清楚:

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

然后你以块的形式发送压缩体(大概是由 gzip 流提供的,用块头来声明它有多长),使用 Content-Encoding: gzip 和 Transfer-Encoding: chunked headers(并且没有 Content-Length标题)。

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

于 2012-02-02T19:56:44.503 回答
27

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

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

HTTPbis 第 1 部分,第 6.2.1 节

于 2011-04-08T06:56:28.850 回答
1

您可能并没有真正发送适当的压缩响应。

尝试在 zlib 中设置window bitsto 。31并使用deflateInit2().

于 2011-04-08T05:30:07.560 回答