【HTTP 2】啓用 HTTP 2(Starting HTTP/2)

【HTTP 2】啓用 HTTP 2(Starting HTTP/2)

Starting HTTP/2

前情提要

在上一篇文章《【HTTP 2】HTTP/2 協議概述(HTTP/2 Protocol Overview)》中,簡單介紹了 HTTP 2 規範的文檔結構以及約定和術語。html

本文變對 HTTP 2 規範的第一部分進行介紹,來講明如何發起一個 HTTP 2 鏈接。git

啓用 HTTP/2(Starting HTTP/2)

HTTP 2 鏈接是一個運行在 TCP 鏈接之上的應用層協議。客戶端是 TCP 鏈接的發起者。github

HTTP 2 保持了 HTTP 1.1 的風格,一樣使用「http」和「https」做爲 URI 的開始。而且共享相同的默認端口號:「http」使用 80 端口,「https」使用 443 端口。這意味着,相關實現要處理針對目標資源的請求,好比 http://example.org/foo 或者 https://example.com/bar,須要先知道上游服務器(該客戶端當前但願創建的鏈接)是否支持 HTTP 2。安全

「http」和「https」支持 HTTP 2 的手段有所不一樣。「http」支持 HTTP 2 的方法在 3.2 節詳述,而「https」支持 HTTP 2 的方法在 3.3 節詳述。服務器

HTTP/2 版本標識(HTTP/2 Version Identification)

本文檔中所定義的協議有兩個標識符。網絡

字符串「h2」標識了使用傳輸安全層(TLS)的協議。該標識符用於 TLS 應用層協議協商(ALPN)擴展(TLS-ALPN)字段,在任何 TLS 之上的 HTTP 2 都會被該標識符標記。併發

「h2」字符串在 ALPN 協議標識中被序列化成兩個八進制序列:0x68, 0x32。post

字符串「h2c」標識了 HTTP 2 運行在明文 TCP 中。該標識符用於 HTTP 1.1 Upgrade 報文頭中,在任何 TCP 之上的 HTTP 2 都會被該標識符標記。編碼

選擇「h2」或「h2c」意味着將會致使不一樣的傳輸、安全性、幀構成,以及在本文檔中所描述的消息語法。url

「http」中啓用 HTTP/2(Starting HTTP/2 for 「http」 URIs)

一個客戶端使用「http」發起請求,並不知道下一站是否支持 HTTP 升級機制。客戶端經過發送 HTTP 1.1 請求,幷包括 Upgrade 報文頭,以「h2c」標識。這樣的 HTTP 1.1 請求必須(MUST)有且僅有一個 HTTP2-Settings 報文頭字段。

例如:

在客戶端發送 HTTP 2 幀以前,包含 Payload 的請求必須(MUST)被完整的發送。這意味着一個較大的請求將會阻塞鏈接,直到它被徹底發送完畢。

若是初始請求與後續請求的併發很是重要,OPTIONS 請求能夠用於升級至 HTTP 2 ,不過須要額外增長一次通訊的成本。

不支持 HTTP 2 的服務器能夠視 Upgrade 報文頭不存在,進行以下響應:

服務器必須(MUST)忽略 Upgrade 報文頭中的「h2」標識。「h2」標識意味着基於 TLS 的 HTTP/2,應該參考 3.3 節進行協商。

支持 HTTP 2 的服務器接受了升級請求,並以狀態碼 101(轉換協議)進行響應。在 101 響應的空行後,服務器能夠開始發送 HTTP 2 幀。這些幀必須(MUST)包括升級請求對應的響應。

例如:

由服務器發送的第一個 HTTP 2 幀必須(MUST)是一個服務器鏈接序言(Connection Preface)(參考 3.5 章),而且包含一個 SETTINGS 幀(參考章節 6.5)。根據接收的 101 響應,客戶端必須(MUST)發送一個一樣包含 SETTINGS 幀的鏈接序言(Connection Preface)(參考章節 3.5)。

在升級以前所發送的 HTTP 1.1 請求,將被分配一個流標識符 「1」(參考章節 5.1.1),其優先級爲默認級別(參考章節 5.3.5)。流 「1」 從 HTTP 1.1 請求完成後,是一個從客戶端至服務器的隱性「半關閉」的流(參考章節 5.1)。在開始 HTTP 2 鏈接後,流 「1」 被用於響應。

HTTP2-Settings 報文頭(HTTP2-Settings Header Field)

一個 HTTP 1.1 請求升級至 HTTP 2,必須(MUST)包含有且僅有一個 HTTP2-Settings 報文頭。HTTP2-Settings 報文頭是一個特定於鏈接的報頭字段,其中的參數用於管理 HTTP 2 鏈接,在服務器接收升級請求時預先提供的。

若是沒有提供 HTTP2-Settings 報文頭,或者提供了超過一個該報文頭,服務器不能夠(MUST NOT)升級該鏈接至 HTTP 2。服務器也不能夠(MUST NOT)發送這個報文頭。

HTTP2-Settings 報文頭中的內容,是一個以 Base64 編碼的 SETTINGS 幀的 Payload(即:URL 和安全文件名的 Base64 描述(RFC4648)的第 5 章,任何結尾的‘=’都將被忽略)。token68 的 ABNF(RFC5234)產物在 RFC7235 有所定義。

因爲升級(Upgrade)只應用於直接鏈接,發送 HTTP2-Settings 的客戶端必須(MUST)將 HTTP2-Settings 做爲鏈接選項,包含在 Connection 報文頭中,以防止它被轉發(參考 RFC7230章節 6.1)。

服務器解碼並解釋這些值,並將其看作其餘 SETTINGS 幀。因爲 101 響應做爲了隱式確認,因此顯式確認這些設置(參考章節 6.5.3)是不必的。在升級請求中提供這些值,使得一個客戶端有機會在接收服務器發 送的任何幀以前提供參數信息。

「https」中啓用 HTTP/2(Starting HTTP/2 for 「https」 URIs)

 

一個發起「https」請求的客戶端,須要用到 TLS(TLS1.2) 和應用層協議協商(ALPN) 擴展(TLS-ALPN)。

TLS 之上的 HTTP 2 使用「h2」做爲協議標識符。客戶端必定不能(MUST NOT)發送「h2c」協議標識符,服務器也必定不能(MUST NOT)選擇「h2c」標識符使用。「h2c」協議標識符描述了不適用 TLS 的協議。

一旦 TLS 協商完成,客戶端和服務器都必須(MUST)發送一個鏈接序言(Connection preface)。

先驗下啓用 HTTP/2(Starting HTTP/2 with Prior Knowledge)

客戶端能夠經過其餘方式判斷服務器是否支持 HTTP 2。例如 ALT-SVC,它描述了一種機制使得 HTTP 具備廣播能力。

客戶端必須(MUST)發送鏈接序言(Connection preface,參考章節 3.5),而後能夠(MAY)當即發送 HTTP 2 幀給服務器。服務端能夠經過已存在的鏈接序言識別出這個鏈接。這隻對基於明文 TCP 的 HTTP 2 鏈接創建有影響,TLS 之上的 HTTP 2 必須(MUST)使用 TLS 協議協商(TLS-ALPN)。

一樣的,服務器必須(MUST) 發送鏈接序言(參考章節 3.5)。

若是沒有其餘信息,對 HTTP 2 以前的支持並不表明着指定服務器必定會在以後的鏈接中支持 HTTP 2。好比,服務器配置有可能改變,或者服務器集羣中不一樣的實例配置有差別,亦或者網絡情況的變化。

HTTP 2 鏈接序言(HTTP/2 Connection Preface)

在 HTTP 2 中,每一個終端都須要發送一個鏈接序言做爲協議的最終確認以及 HTTP 2 的鏈接初始設置。客戶端和服務器均須要發送一個不一樣的鏈接序言。

客戶端鏈接序言以 24 個字節序列開始,以十六進制表示爲:

也就是說,鏈接序言以字符串 PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n  開頭。這個序列後必須(MUST)跟着一個 SETTINGS 幀(參考章節 6.5),其能夠(MAY)爲空。客戶端收到 101 (協議轉換)響應後,馬上發送客戶端鏈接序言。或者做爲 TLS 鏈接的第一個應用數據字節。若是在語言驗證服務器支持 HTTP 2 的狀況下啓用 HTTP 2 鏈接,客戶端鏈接序言在鏈接創建後發送。

注意:客戶端鏈接序言是用來讓大部分 HTTP 1.1 或 HTTP 1.0 服務端及中介端不試圖進一步處理幀。注意這並不能解決【TALKING】中提到的問題。

服務器鏈接序言包含一個多是空的 SETTINGS 幀(參考章節 6.5),它必須在 HTTP 2 鏈接中首個發送。

從一個節點接收到的鏈接序言中所包含的 SETTINGS 幀必須在鏈接序言發送後被確認(參考章節 6.5.3)。

爲了不沒必要要的延遲,容許客戶端在發送客戶端鏈接序言以後當即發送其餘額外的幀,不須要等待收到服務器端鏈接序言。不過,值得注意的是,服務端鏈接序言 SETTINGS 幀可能包含一些關於指望客戶端如何與服務器端通訊的必須修改的參數。在收到這些 SETTINGS 幀後,客戶端應當遵照全部設置的參數。在有些配置中,服務器可能在客戶端發送其餘額外幀以前傳輸 SETTINGS,以提供一個避免這些問題的機會。

客戶端和服務器必須(MUST)將一個非法的鏈接序言當作一個 PROTOCOL_ERROR 類型的鏈接錯誤(Connection error,參考章節 5.4.1)。在這個案例中,當一個節點不支持 HTTP 2 而出現非法序言時,GOAWAY 幀(參考章節 6.8)能夠(MAY)被省略。


本文以 CC BY-NC-SA 3.0 CN 協議共享,轉載、共享及二次創做時請保留原文出處及連接,請勿用於商業用途。

本文連接:http://litecodes.com/dev/http-2-spec-starting-http-2/

本系列文章將會在個人 GitBook:http2-spec-zh 同步更新,

下一篇文章將會翻譯協議的第三部分:HTTP Frames(HTTP 幀),不要錯過喲~

相關文章
相關標籤/搜索