9

HTTP/2 禁止特定于连接的标头字段。不得出现以下标头字段:“Connection”、“Keep-Alive”、“Proxy-Connection”、“Transfer-Encoding”和“Upgrade”。此外,“TE”标头字段不得包含“trailers”以外的任何值。

我想问的是,既然HTTP/2禁止了Transfer-Encoding标头,那么HTTP/2代理如何处理标头Transfer-Encoding: chunked呢?

代理是否应该始终将整个分块请求缓存在内存中并添加 Content-Length 标头,发送到 HTTP/2 服务器/客户端?

4

1 回答 1

16

在 HTTP/2 中,内容总是被“分块”,因为它是在 DATA 帧中发送的,即携带块长度的字节块以及表示该帧是否是最后一个帧的流结束标志。

在 HTTP/2 到 HTTP/1.1 代理中,代理有多种选择。

一个非常简单的情况是重新映射每个 HTTP/2 接收到的 DATA 帧并将其作为 HTTP/1.1 块发送出去。因此,代理必须将Transfer-Encoding: chunked标头添加到通信的 HTTP/1.1 端。类似地,它可以将读取的每个内容重新映射到一个 DATA 帧中(如果它很大,则与整个块的等待/缓冲区相反)。

另一种情况是缓冲接收到的一些 DATA 帧,希望其中一个设置了流结束标志。如果发生这种情况,则整个内容长度是已知的,代理可以添加Content-Length标头并立即发送整个内容。

同样在前一种情况下,当缓冲区溢出时,代理可以添加Transfer-Encoding: chunked标头并发送一个与缓冲区大小相同的块(而不是第一种情况下的 DATA 帧大小)。

当代理接收到最后一个 DATA 帧时,它将剩余的字节分块,然后发送终端块(表示块结束的零长度块)。

在另一个方向,从 HTTP/1.1 到 HTTP/2,当代理接收到分块内容时,它可以简单地丢弃Transfer-Encoding: chunked头部,从接收到的块中生成一个 DATA 帧,然后发送该帧。最终它将接收到终端块(表示块结束的零长度块),并将其转换为长度为零的 DATA 帧,并设置了流结束标志。

当然,如果代理执行了一些缓冲或其他优化,则 DATA 帧大小可能不完全等于块大小。

由于 HTTP/2 接收/发送包含流结束标志的 DATA 帧,代理可以轻松地与 HTTP/1.1 进行转换,将流结束 DATA 帧映射到终端块,并且终端块到流结束数据帧。

于 2015-04-07T09:06:00.577 回答