HTTP/2部署使用一文介绍了如何部署HTTP/2到我们的应用或Web站点中。这时,正如部署HTTPS一样,大家会疑问:
带着这些疑问,我们一起来分析HTTP/2的协商机制。
HTTP/2的设计之初是不改动HTTP的语义,HTTP方法、状态码、URI及首部字段等核心概念,即不期望像用户暴露出HTTP2实现的复杂性。HTTP/2依然与HTTP/1.x保持一致,使用http
和https
来完成请求,前者对应于h2c(Http2 over cleartext TCP)
,后者则对应于h2(Http2 over TLS)
。
所以,在发起Http请求时,对于HTTP/2和HTTP1.0其实没有任何区别。对于同样的URI:https:\\www.baidu.com
或者http:\\www.baidu.com
,客户端在发起新请求之前,必须能发现服务器及所有设备是否支持HTTP/2协议,这就依赖于双端对于协议的协商机制了。
HTTP/2协议包含两种实现类型:h2C
,基于常规的非加密信道建立的HTTP/2的连接;h2
,基于TLS协议建立起来的HTTP/2的连接。针对h2C
和h2
,协商的方式是不同的。
HTTP1.1中引入了Upgrade
机制,使得客户端和服务端之间可以借助已有的HTTP语法升级到其他协议。对于h2c
的升级,正是借助Upgrade
来完成的。
客户端必须通过Upgrade
头部列出要升级到的协议和版本,并且还要包含一个HTTP2-Settings
的头部,如下:
GET / HTTP/1.1
Host: server.example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: <base64url encoding of HTTP/2 SETTINGS payload>
如果服务器不支持HTTP/2
,便会忽略upgrade
头部,直接回应Http1.x的Response。
HTTP/1.1 200 OK
Content-Length: 243
Content-Type: text/html
...
如果服务器支持HTTP/2
,则会以101
的状态码回应,并且可以在响应正文,直接发送HTTP/2的帧。
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: h2c
[ HTTP/2 connection ...]
下图是通过nghttp2分析HTTP1.x升级到HTTP/2的细节:
基于TLS的HTTP/2协商则依赖于ALPN协商机制。起初,Google在SPDY协议中开发了一个名为NPN(Next Protocol Negotiation,下一代协商)
的TLS扩展,随着SPDY被HTTP/2所取代,NPN
也被修订为ALPN(Application Layer Protocol Negotiation,应用层协议协商)
。
在TLS握手阶段,通信双方原本就要进行加密套件等的协商,ALPN
作为起拓展加入握手协商过程中,对通信不会增添性能影响。
下图通过Wireshark对HTTP/2的连接建立过程进行分析:
从上面wireShark的抓包分析来看,客户端在建立TLS连接的Client Hello握手中,通过ALPN扩展列出了自己支持的各种应用层协议。
如果服务端支持h2的话,会在server Hello中指定ALPN的结果为h2.随着TLS连接建立成功,便可以进行HTTP2.0的系列请求了。
如果不支持,会从客户端的ALPN列表中选一个自己支持的(HTTP/1.1)。随后的请求都基于HTTP/1.1来完成。
在了解HTTP/2的协商机制后,应该不会在困惑于开篇的几个问题了。HTTP/2 协议本身并没有要求它必须基于 HTTPS(TLS)部署,但是考虑到HTTPS协议的安全性,而且当前主流浏览器都只支持基于HTTPS的HTTP/2。所以考虑安全性和兼容性,我们通常需要基于HTTPS部署。
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者何慧授权发布。