传输编码:gzip与内容编码:gzip

时间:2012-07-25 02:36:08

标签: http gzip content-encoding transfer-encoding

关于是否做

的当前状况是什么
Transfer-Encoding: gzip

Content-Encoding: gzip

当我想允许客户时,例如有限的带宽表明他们愿意接受压缩的响应,而服务器最终决定是否压缩

后者是例如Apache的mod_deflate和IIS,如果你让它来处理压缩。根据要压缩的内容的大小,它将执行额外的Transfer-Encoding: chunked

它还会包含一个Vary: Accept-Encoding,它已经暗示了这个问题。 Content-Encoding似乎是实体的一部分,因此将Content-Encoding数量更改为实体的更改,即不同的Accept-Encoding标题表示例如缓存不能使用其他相同实体的缓存版本。

我是否已经错过了一个明确的答案(并没有将其隐藏在某个apache新闻组的长线程中的消息中)?

我目前的印象是:

  • 传输编码实际上是通过现有服务器和客户端实现进行内容编码主要完成操作的正确方法
  • Content-Encoding由于其语义含义,带来了一些问题(服务器在透明地压缩响应时应该对ETag做什么?)
  • 原因是鸡蛋没法:浏览器不支持它,因为服务器没有,因为浏览器没有

所以我假设正确的方式是Transfer-Encoding: gzip(或者,如果我另外对身体进行分块,那么would become Transfer-Encoding: gzip, chunked)。在这种情况下没有理由触及VaryETag或任何其他标题,因为它是传输级别的东西。

现在我并不太关心Transfer-Encoding的'逐跳',这是其他人似乎首先关注的事情,因为代理可能会解压缩并转发到未压缩的客户端。但是,如果原始请求具有正确的Accept-Encoding标头,则代理可能也会按原样转发(压缩),如果我知道的所有浏览器都是给定的。

是的,这个问题至少有十年之久,例如, https://bugzilla.mozilla.org/show_bug.cgi?id=68517

对此有任何澄清将不胜感激。无论是在符合标准的还是被认为是实用的方面。例如,仅支持透明“内容编码”的HTTP客户端库将成为反对实用性的论据。

2 个答案:

答案 0 :(得分:33)

引用 Roy T. Fielding ,RFC 2616的作者之一:

  

以不一致的方式即时更改内容编码   (既不“永远”也不“总是”使得后来的请求无法实现   关于要处理的内容(例如,PUT或条件GET)   正确。当然,这就是为什么要在飞行中进行表演   内容编码是一个愚蠢的想法,为什么我添加了Transfer-Encoding   将HTTP作为在不改变的情况下进行动态编码的正确方法   资源。

来源:https://issues.apache.org/bugzilla/show_bug.cgi?id=39727#c31

换句话说:不要动态 Content-Encoding,改为使用Transfer-Encoding!

修改:,除非您要向仅了解内容编码的客户提供gzip压缩内容。遗憾的是,这似乎是其中的大多数。但请注意,您离开规范领域并可能遇到问题,例如Fielding和其他人提到的问题,例如当涉及缓存代理时。

答案 1 :(得分:24)

正确用法,如RFC 2616中定义的并且实际上是在野外实现的,用于客户端发送Accept-Encoding请求标头(客户端可以指定多个编码)。然后,服务器可以并且然后仅根据客户端支持的编码对响应进行编码(如果文件数据尚未存储在该编码中),则在Content-Encoding响应头中指示正在使用哪种编码。然后,客户端可以根据Transfer-Encoding(即chunked)从套接字读取数据,然后根据Content-Encoding对其进行解码(即:gzip)。< / p>

因此,在您的情况下,客户端将发送Accept-Encoding: gzip请求标头,然后服务器可能决定压缩(如果尚未)并发送Content-Encoding: gzip和可选Transfer-Encoding: chunked响应标题。

是的,Transfer-Encoding标头可用于请求,但仅适用于HTTP 1.1,这要求客户端和服务器实现都支持双向chunked编码。

ETag唯一标识服务器上的资源数据,而不是实际传输的数据。如果给定的URL资源更改其ETag值,则表示该资源的服务器端数据已更改。