分类 Web 相关 下的文章

HTTP 2 的特性

从 HTTP 2 in action 这本书看的, 发现这个网站总结的不错: https://tools.keycdn.com/http2-test, 就摘抄过来了. 顺便测试了一下 (20191104), taobao, ebay 支持 Http2, jd 和 baidu 主页都不支持 HTTP2

  1. HTTP/2 is binary, instead of textual.
  2. It is fully multiplexed, sending multiple requests in parallel over a single TCP connection.
  3. It uses header compression HPACK to reduce overhead.
  4. It allows servers to “push” responses proactively into client caches instead of waiting for a new request for each resource
  5. It uses the new ALPN extension which allows for faster-encrypted connections since the application protocol is determined during the initial connection.
  6. It reduces additional round trip times (RTT), making your website load faster without any optimization.
  7. Domain sharding and asset concatenation is no longer needed with HTTP/2.
  8. Flow control
  9. Stream prioritization

如何判断一个网站是不是支持 HTTP2? 使用最新的 curl 命令:

LM-SHC-16507776:tmp xiatian$ curl -vvv -s  --http2 https://www.jd.com:443/ 2>&1 | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server accepted to use http/1.1
LM-SHC-16507776:tmp xiatian$ curl -vvv -s  --http2 https://www.ebay.com:443/ 2>&1 | grep ALPN
* ALPN, offering h2
* ALPN, offering http/1.1
* ALPN, server accepted to use h2

上面的输出中 baidu 首页不支持, ebay 首页支持.


从下面这个问答看:
在 Chrome 里面, 对于 HTTP 2 同一个 origin 不同的 tab 之间共享一个 tcp 连接.
对于 HTTP 1.1:

  1. HTTP/1.1 sockets are stored in a pool when they are not active. A request from any tab may end up using any socket in the pool;
  2. Incognito tabs use their own independent socket pool (All incognito tabs for a profile share just one socket pool, though);
  3. Isolated apps use their own socket pools.
  4. Different profiles and guest mode use their own socket pools.
  5. Global requests not tied to a profile use their own socket pool;

https://stackoverflow.com/questions/51535819/in-http-1-1-are-connections-shared-across-multiple-chrome-tabs-to-the-same-origi
https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/S3TEvmRWcNE

捕获 ssl/tls 版本

tcpdump -i any -s 1500 'tcp port 443 and (tcp[((tcp[12:1] & 0xf0) >> 2)+5:1] = 0x01) and (tcp[((tcp[12:1] & 0xf0) >> 2):1] = 0x16)' -w output.txt

https://serverfault.com/questions/574405/tcpdump-server-hello-certificate-filter
https://networkengineering.stackexchange.com/questions/20227/find-ssl-version-in-tcp-packets-in-established-tcp-connection
http://blog.fourthbit.com/2014/12/23/traffic-analysis-of-an-ssl-slash-tls-session
https://stackoverflow.com/questions/39624745/capture-only-ssl-handshake-with-tcpdump
https://www.cnblogs.com/ggjucheng/archive/2012/01/14/2322659.html

关于 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