分类 Web 相关 下的文章
HTTP 2 的特性
从 HTTP 2 in action 这本书看的, 发现这个网站总结的不错: https://tools.keycdn.com/http2-test, 就摘抄过来了. 顺便测试了一下 (20191104), taobao, ebay 支持 Http2, jd 和 baidu 主页都不支持 HTTP2
- HTTP/2 is binary, instead of textual.
- It is fully multiplexed, sending multiple requests in parallel over a single TCP connection.
- It uses header compression HPACK to reduce overhead.
- It allows servers to “push” responses proactively into client caches instead of waiting for a new request for each resource
- It uses the new ALPN extension which allows for faster-encrypted connections since the application protocol is determined during the initial connection.
- It reduces additional round trip times (RTT), making your website load faster without any optimization.
- Domain sharding and asset concatenation is no longer needed with HTTP/2.
- Flow control
- 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:
- 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;
- Incognito tabs use their own independent socket pool (All incognito tabs for a profile share just one socket pool, though);
- Isolated apps use their own socket pools.
- Different profiles and guest mode use their own socket pools.
- 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
设置 https proxy
关于 http 1.1 的 Keep-Alive 的持久连接 以及客户端和服务器端的处理
关于 http 1.1 的 Keep-Alive 有以下几点要注意:
- default 行为
- 可设置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