2018年4月

关于 http 1.1 header Transfer-Encoding 的用法

关于 Transfer-Encoding 在官方文档中有以下几个点要注意:

  1. 它是 Hop to Hop 的 header, 也就是中间代理可以改的, 并不是 end to end 的 header;
  2. 它是传输编码, 并不是 content-encoding, content-encoding 是 end to end;
  3. 可能的值有: chunked, compress, deflate, gzip, identity. 可以是多个, 用逗号隔开;
  4. 如果是 chunked, 因为预先不知道内容长度, 所以 Content-Length 是不需要的;
  5. 如果有 chunked, chunked 必须在逗号隔开的最后一个;
  6. HTTP/1.1 应用程序必须能够编码/解码 chunked;
  7. identity 代表原样传输, 没有编码, 必须永远被接受;
  8. 在 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)

  • 在 http://www.oracle.com/technetwork/systems/chunking-155634.html 中的写到:

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

关于 Java Socket 和 TCP 连接的相关问题

这个问答解释了 Socket 和 TCP 的 level 问题.
https://stackoverflow.com/questions/10240694/java-socket-api-how-to-tell-if-a-connection-has-been-closed

这篇文章介绍了 Socket close() 和 TCP 的 FIN, RST 的相关问题.
https://docs.oracle.com/javase/8/docs/technotes/guides/net/articles/connection_release.html

查看 JDK 源代码: SocketInputStream 和 SocketOutputStream 的 read 和 write 方法, 可以看到只有在 read 和 write 的时候才能知道这个 tcp 连接的状态.

对于 NIO 可以更快的知道这个消息.

HttpClient 库的介绍中, 有关于如何关掉 idle 和 expired 的连接问题:
http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d5e373