关于 http 1.1 header Transfer-Encoding 的用法
关于 Transfer-Encoding 在官方文档中有以下几个点要注意:
- 它是 Hop to Hop 的 header, 也就是中间代理可以改的, 并不是 end to end 的 header;
- 它是传输编码, 并不是 content-encoding, content-encoding 是 end to end;
- 可能的值有: chunked, compress, deflate, gzip, identity. 可以是多个, 用逗号隔开;
- 如果是 chunked, 因为预先不知道内容长度, 所以 Content-Length 是不需要的;
- 如果有 chunked, chunked 必须在逗号隔开的最后一个;
- HTTP/1.1 应用程序必须能够编码/解码 chunked;
- identity 代表原样传输, 没有编码, 必须永远被接受;
- 在 request 的 header 中的 TE, 其实是 Accepted-Transfer-Encoding 的缩写;
比较容易混淆, 官方文档有没有说明的是:
尽管 Transfer-Encoding 是一个 response header, 可是在 request 的 header 中也可以使用这个 header, 并且服务端都能处理. 参考下面这 2 处文章:
- 在 Wiki https://en.wikipedia.org/wiki/Chunked_transfer_encoding 中的 Format 一节中, 有写到:
If a Transfer-Encoding field with a value of "chunked" is specified in
an HTTP message (either a request sent by a client or the response
from the server)
Chunking is most often used by the server for responses, but clients
can also chunk large requests
另外在 Tomcat8 的实现中, org.apache.coyote.http11.Http11Processor 的类的 prepareRequest() 方法中, 我们可以看到具体的对于 Transfer-Encoding 的处理方法. 其中包含对于 request 使用 chunked 处理.
使用 Curl 测试 content-length 和 payload 的数据量不一致的问题:
curl -X POST http://localhost:8080/post --header "Content-Type:application/json" --header "content-length: 2" --header "transfer-encoding:abc" --data "{"
更多内容, 参考: rfc7230, RFC2616
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding