# 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已經支持該方式。