关于 代理服务器

如果一个 web 请求走代理服务器, 那么 client 端是直接和 proxy 建立连接还是和 server 端建立连接?

有代理服务器的话, 代理服务器是如何影响 read timeout 和 connection timeout 的?

关于 http cert

JDK 有2个环境变量控制 SSL/TLS:
-Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2
-Djdk.tls.client.protocols=TLSv1.1,TLSv1.2

如果一个 vip 背后有2个 IP, 两个 IP 的 cert 不一样, 会产生什么后果?

如果一个 vip 背后有2个 IP, 两个 IP 的 cert 支持的 SSL/TLS 不一样, 会产生什么后果?

在一个正在被使用的 VIP 上 突然更新一个 cert 会产生什么后果?

在一个正在被使用的 VIP 上 突然更新一个 cert 让它支持最新的 TLS 1.2 会产生什么后果?

关于 Tomcat HTTP connector 的具体实现及使用

以 tomcat 8 为例, 有4个 http protocol 实现:

  1. org.apache.coyote.http11.Http11Protocol - blocking Java connector
  2. org.apache.coyote.http11.Http11NioProtocol - non blocking Java NIO connector
  3. org.apache.coyote.http11.Http11Nio2Protocol - non blocking Java NIO2 connector
  4. org.apache.coyote.http11.Http11AprProtocol - the APR/native connector.

如果配置里面没有设置这个 protocol 的值, 是有个自动选择机制:

Sets the protocol to handle incoming traffic. The default value is
HTTP/1.1 which uses an auto-switching mechanism to select either a non
blocking Java NIO based connector or an APR/native based connector. If
the PATH (Windows) or LD_LIBRARY_PATH (on most unix systems)
environment variables contain the Tomcat native library, the
APR/native connector will be used. If the native library cannot be
found, the non blocking Java based connector will be used. Note that
the APR/native connector has different settings for HTTPS than the
Java connectors.

nio 和 nio2 有什么区别?

Apr/native 是什么?

refer:
https://tomcat.apache.org/tomcat-8.0-doc/config/http.html#Connector_Comparison

关于 http 1.1 的 Keep-Alive 的持久连接 以及客户端和服务器端的处理

关于 http 1.1 的 Keep-Alive 有以下几点要注意:

  1. default 行为
  2. 可设置timeout 和 max request 数: Keep-Alive: timeout=5, max=1000

对于Java 无论是BIO 还是NIO,客户端和服务端都可以采用一定的策略来关闭这个http 连接。另外TCP层有半连接概念,Http层没有,要么关掉,要么没关。

那么若是 Keep-Alive 的长连接, 如何区分一个 request payload 数据是不是已经结束呢?

server端:

以 tomcat8 为例: 在 tomcat8 的代码里面,
org.apache.coyote.http11.Http11Processor 的 prepareRequest() 方法里,
可以看到处理 HTTP header: transfer-encoding 的逻辑: 根据是 identity 或者 chunked
来使用不同的 filter 类来判断 payload 有没有结束, 所以在 servelet 的 service() 或 doPost
方法里, 拿到 inputStream 的时候, 已经不用担心 payload 结束的问题. 具体的 Filter 类在 package
org.apache.coyote.http11.filters里面, 比如 处理 input 的就有:
ChunkedInputFilter, IdentityInputFilter.

client 端

以 apache httpClient 5 为例: 因为 Client 端不像服务器端有过滤处理, 所以 client 端要自己处理,
所以在 httpClient 的代码里面, 就有专门处理 payload 是否结束的代码. 有个类:
DefaultContentLengthStrategy, 它有个方法 determineLength(final HttpMessage
message), 用来判断是使用 chunked 还是 content-length. 然后根据这个返回结果,
使用不同的解码器或者使用不同的 Stream 来封装 payload. stream 如:
org.apache.hc.core5.http.impl.io.ChunkedInputStream 和
org.apache.hc.core5.http.impl.io.IdentityInputStream; 解码器如:
org.apache.hc.core5.http.impl.nio.LengthDelimitedDecoder 和
org.apache.hc.core5.http.impl.nio.ChunkDecoder

关于 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 处文章:

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