# 5. http2的基本概念
http2到底做了些什么呢?到多远才是HTTPbis小组工作的界限?
事实上,http2的界定非常严格,让小组的工作颇为掣肘。
-
[X] 它必须维持HTTP的范式。毕竟它只是一个让客户端发送请求到服务器的基于TCP的协议。
-
[X] 不能改变`http://`和`https://`这样的URL,也不能对其添加新的结构。使用这类URL的网站太多了,没法指望他们全部改变。
-
[X] HTTP1的服务器和客户端依然会存在很久,所以我们必须提供HTTP1到http2服务器的代理。
-
[X] 随后,我们也要让这种代理能够将http2的功能一对一的映射到HTTP 1.1的客户端。
-
[X] 删除或者减少协议里面那些可选的部分。虽然这并不是一个大的需求,但是SPDY和Google的团队会非常喜欢这点。让协议里所有部分都成为强制要求的,就能防止人们在实现的时候偷懒,从而避免将来的问题。
-
[X] 不再使用小版本号。服务器和客户端都必须确定自己是否完整兼容http2或者彻底不兼容。如果将来该协议需要被扩充更变,那么新的协议将会是http3,而不是http 2.x。
## 5.1. http2和现有的URI结构
如前所述,现有的URI结构正在被HTTP 1.x使用而不能改变,所以http2也必须沿用该结构。正因如此我们才必须找到一种方式将协议升级至http2,或者让服务器使用http2来彻底替代旧的协议。
HTTP 1.1本身就有制定“升级”的方案:提供一个头,让服务器在收到旧协议请求的时候,向客户端发送新协议的响应。这样做的代价是需要一次往返通信。
这个往返通信的代价是SPDY团队不能接受的。因为他们只实现了基于TLS的SPDY,所以他们也只开发了一个TLS的扩展来简化协议的协商。这个扩展被称作NPN(Next Protocol Negotiation),通过它,服务器通知客户端所有他支持的协议,从而让客户端从中选择一个合适的。
## 5.2. 为`https://`所准备的http2
足够的关注使得http2在TLS上得以正常运作,SPDY只支持TLS,所以按理说TLS也应成为http2 必需的组件,但出乎意料的是http2仅将TLS作为可选部分。然而,全球两大浏览器领导者 - Firefox和Chrome明确地表示,他们只实现基于TLS的http2.
只选择TLS的原因包括了保护用户隐私,早期的评估结果表明,将新的协议建立在TLS上更可能成功。这也是因为所有来自80端口的流量都会被当作HTTP 1.1或者是其某个变种,而不是另外一个种全新的协议。
关于是否该强制使用TLS的主题在邮件组和会议上引起了不小的争议 - 这到底是好是坏呢?不管怎么样,对于这种备受争议的话题请谨慎讨论,尤其是当你面对一个HTTPbis小组成员的时候。
类似地,还有一个激烈而长期的辩论,即当使用TLS时http2是否应该强制规定密码列表,或者应该建立一个黑名单,或者它根本就不需要从TLS层得到任何东西,而由TLS工作组来解决。最后规范指定TLS最低版本是1.2,并且有加密组的限制。
## 5.3 基于TLS之上的http2协商
Next Protocol Negotiation (NPN)是一个用来在TLS服务器上协商SPDY的协议。IETF将这个非正式标准进行规范,从而变成了ALPN(Application Layer Protocol Negotiation)。ALPN被推广用于http2,而SPDY客户端和服务器仍然使用NPN。
由于NPN先诞生,而ALPN还经历了一些标准化过程。所以许多早期的http2客户端和服务器在协商http2时同时实现了这两者的扩展。并且,由于SPDY使用NPN,不少服务器同时提供SPDY和http2来支持NPN和APLN。
ALPN和NPN的主要区别在于谁持有会话协议的决定权,ALPN是由客户端给服务器发送一个协议优先级列表,由服务器最终选择一个合适的。而NPN则正好相反,是客户端有最终决定权。
## 5.4 为`http://`所准备的http2
如前所述,对于纯文本的HTTP1.1来说,协商http2的方法就是给服务器发送一个带**升级**头部的报文。如果服务器支持http2,它将回复“101 Switching”状态码,并从此开始在该连接上使用http2。也许你很容易就发现这个升级流程会造成一个完整的往返时延开销,但好处是http2连接相比HTTP1可以被更大限度地重用和保持。
虽然有些浏览器厂商的发言人宣称他们不会实现这种http2会话方式,但IE团队已公开表示他们会实现,与此同时,curl已经支持该方式。