HTTP2 協(xié)議初識

? RFC:https://tools.ietf.org/html/rfc7540

RFC 中英文對照:https://github.com/fex-team/http2-spec/blob/master/HTTP2%E4%B8%AD%E8%8B%B1%E5%AF%B9%E7%85%A7%E7%89%88(06-29).md

O'Reilly :https://hpbn.co/http2/

SPDY:http://www.chromium.org/spdy/

隨著Web應(yīng)用日漸廣泛,復(fù)雜程度和重要性也在不斷的增長,也因此對開發(fā)人員和用戶帶來了負擔,HTTP2 支持所有的HTTP/1.1的核心特征,提供了HTTP語義的傳輸優(yōu)化,并且在各方面做到更高效。

HTTP 2 基本概念

HTTP2 是運行在TCP或者SSL協(xié)議之上,屬于應(yīng)用層的協(xié)議。HTTP2.0消息包以二進制幀的形式進行封裝。

HTTP/2 binary framing layer

HTTP2引入了一下的三個新概念:

Stream: 已經(jīng)建立連接的雙向字節(jié)流,用唯一ID標示,可以傳輸一個或多個消息

Message:邏輯上的HTTP消息,請求或者響應(yīng),可以包含多個 frame

Frame:HTTP2通信的最小單位,二進制頭封裝,封裝HTTP頭部或body

HTTP2是把一個HTTP數(shù)據(jù)包分成多個幀發(fā)送,每個幀有一個二進制頭,并把HTTP分成多個獨立小幀,多個幀組成一個Message在流中發(fā)送。不同流的幀有可能交錯到達,幀的報文頭中標示了屬于哪一個流。

HTTP/2 streams, messages, and frames

HTTP2 的幀格式

HTTP2的最小數(shù)據(jù)單位是幀,所有幀以9字節(jié)的幀頭并跟著0-16,383字節(jié)的數(shù)據(jù)。

Frame Layout

Length: unsigned 24-bit integer,最大值為 2^24(16384),指的是不包括頭部的部分

Type:幀的類型

Flags:為幀類型保留的8字節(jié)字段有具體的布爾標識

R:1位的保留字段

Stream Identifier:31字節(jié)的流標識符。0是保留的,標明幀是與連接相關(guān)作為一個整體而不是一個單獨的流。

幀主體的結(jié)構(gòu)和內(nèi)容完全取決于幀類型。

HTTP2 有以下十種幀類型:

Frame Type Registry

1、DATA :數(shù)據(jù)幀,Type=0x0,主要用來傳遞消息體

DATA Frame Payload

Pad Length : 8位,可選,只在設(shè)置了PADDED標記時呈現(xiàn)。表示幀填充的字節(jié)為單位的長度。

Data : 應(yīng)用數(shù)據(jù)。

Padding : 填充字節(jié)不包含任何應(yīng)用語義值。填充字節(jié)在發(fā)送時設(shè)為0,接收時忽略。

DATA 幀定義了以下的 Flags:

END_STREAM (0x1): 位1,表示當前幀是相應(yīng)流發(fā)送的最后一幀。設(shè)置時流進入半封閉或關(guān)閉狀態(tài)。

PADDED (0x8): 位4,表示Pad Length 字段啟用與否。

2、HEADERS :頭部幀,Type=0x1,主要用于傳遞消息頭

HEADERS Frame Payload

Pad Length:8位可選,在設(shè)置PADDED 標記時呈現(xiàn)。表示幀填充的字節(jié)為單位的長度。

E?: 1位可選,在優(yōu)先級標記設(shè)置時呈現(xiàn)。表示用于標識流依賴是否是專用的。

Stream Dependency?: 31位可選,在優(yōu)先級標記設(shè)置時呈現(xiàn)。流依賴的流的標識符。

Weight?: 8位可選,在優(yōu)先級標記設(shè)置時呈現(xiàn)。流的8位權(quán)重標記,1-256的值。

Header Block Fragment?: 報頭塊。

Padding?: 填充字節(jié)

HEADERS 幀定義了以下的 Flags:

END_STREAM (0x1) : 位1,標識是此發(fā)送端對流發(fā)送的最后報頭區(qū)塊。設(shè)置這標記使流進入半封閉狀態(tài)。

END_HEADERS (0x4)?: 位3,表示幀包含了整個的報頭塊,且后面沒有延續(xù)幀。 END_HEADERS為0的報頭幀后面必須跟著延續(xù)幀。

PADDED (0x8)?: 位4,表示Pad Length字段會呈現(xiàn)。

PRIORITY (0x20)?: 位6,優(yōu)先級標記(E), 流依賴及權(quán)重字段將會呈現(xiàn)。

3、PRIORITY :優(yōu)先級幀,Type=0x2,用于設(shè)置流的優(yōu)先級

PRIORITY Frame Payload

E : 1位標記,指示流的依賴是專有的。

Stream Dependency : 流所依賴流的31位標識符。

Weight: 流的權(quán)重(8位)。1-256的權(quán)重值。

4、RST_STREAM :流結(jié)束幀,Type=0x3,用于終止異常流

RST_STREAM Frame Payload

RST_STREAM 幀由一個32位整數(shù)標記錯誤碼,指明流被終止的原因。

RST_STREAM 幀必須與流相關(guān)聯(lián),就是說stream id 不能為 0x0

RST_STREAM幀絕對不能在流處于“空閑”狀態(tài)下發(fā)送。

5、SETTINGS :連接配置參數(shù)幀,Type=0x4,用于設(shè)置參數(shù)

Setting Format

載體包含0或多個參數(shù),每個包含一個16位標識以及一個32位的值。

1)設(shè)置幀由兩個終端在連接開始時發(fā)送,連接生存期的任意時間發(fā)送。

2)設(shè)置幀的參數(shù)將替換參數(shù)中現(xiàn)有值,不能識別的忽略。

3)設(shè)置幀總是應(yīng)用于連接,而不是一個單獨的流。流ID必須為0;

SETTINGS 幀定義了以下的 Flags:

ACK (0x1)?: 位1,表示設(shè)置幀被接收端接收并應(yīng)用。如果設(shè)置了ACK,設(shè)置幀的載體必須為空。

Settings Registry

SETTINGS_HEADER_TABLE_SIZE (0x1)?: 發(fā)送端通知遠端報頭壓縮表的最大承載量。初始值是4,096個字節(jié)。

SETTINGS_ENABLE_PUSH (0x2)?: 用來關(guān)閉服務(wù)器推送。0時不能發(fā)送PUSH_PROMISE。1表示可以推送。

SETTINGS_MAX_CONCURRENT_STREAMS (0x3)?: 標明發(fā)送端允許接收端創(chuàng)建的最大并發(fā)流的數(shù)量。沒有限制(<100) 。 0值阻止新流的創(chuàng)建。

SETTINGS_INITIAL_WINDOW_SIZE (0x4)?: 表示發(fā)送端流量控制的初始窗口大小(字節(jié))。初始值是65,535。 影響所有流的窗口大小.

SETTINGS_MAX_FRAME_SIZE (0x5): 接收最大幀大小。初始值為2^14 (16,384)字節(jié),最大值為2^24-1 or 16,777,215字節(jié)。

SETTINGS_MAX_HEADER_LIST_SIZE (0x6): 可接收的header列表長度(字節(jié)),基于非壓縮的列表大小。

6、PUSH_PROMISE:推送承諾幀,Type=0x5,Server推送之前告知Client端

PUSH_PROMISE Payload Format

1) 被推送的流并不需要按照順序使用。

2) 接收端可以給推送端返回一個RST_STREAM拒絕接收。

Pad Length : 8位,只在PADDED標記設(shè)置時才呈現(xiàn)。

R?: 1bit保留位。Padding?: 填充字節(jié)。

Promised Stream ID?: 31位整數(shù)表示終端準備發(fā)送的流標記。

Header Block Fragment?: 包含請求頭字段的報頭區(qū)塊。

PUSH_PROMISE 幀定義了以下的Flags:

END_HEADERS (0x4)?: 位3, 表明幀包含了整個報頭區(qū)塊。

PADDED (0x8)?: 位4, 表明Pad Length字段是已設(shè)置。

7、PING:Type=0x6,發(fā)送端測量最小的RTT時間,檢測連接是否可用

PING Payload Format

PING 幀定義了以下的Flags:

ACK (0x1)?: 位1表示PING幀是一個PING響應(yīng)。

1)PING幀可以被任何終端任何時刻發(fā)送。

2)PING幀必須在載體中包含一個8字節(jié)長度的數(shù)據(jù)。

收到不含ACK的PING幀必須發(fā)送一個有ACK的PING響應(yīng),帶相同的載荷。PING響應(yīng)應(yīng)設(shè)置比其他幀更高的優(yōu)先級。流ID為0,不和任何流關(guān)聯(lián);

8、GOAWAY:超時幀,Type=0x7,通知對端不要在連接上建新流

GOAWAY Payload Format

可以由客戶端或服務(wù)端發(fā)送。發(fā)動端將忽略連接上流標示符大于Last-Stream-ID的流。

接收端接收到超時幀后不能在這個連接上打開新流,可以創(chuàng)建新連接。

終端在關(guān)閉連接之前總是應(yīng)當發(fā)送一個超時幀;

適用于連接而不是特定的流。流標識符必須是0x0,否則錯誤處理;

連接關(guān)閉前小于或等于標識符上的流沒有完全關(guān)閉的,重試請求;

小于或等于最后流標識符的流可能仍然能成功完成,保持連接在打開狀態(tài)直到正在處理的流全部處理完成。

在發(fā)送超時幀后,發(fā)送端能丟棄流標識符大于最終流標識的流的幀。但任何修改流狀態(tài)的幀不能被忽略。

超時幀包含一個32位錯誤碼,包含關(guān)閉連接的原因。

9、WINDOW_UPDATE:Type=0x8,實現(xiàn)流量控制

WINDOW_UPDATE Payload Format

1) 可以作用單獨的流(ID!=0) 或 整個連接(ID==0)

2) 所有類型的流量控制都是逐跳的(hop-by-hop), 中介端不會轉(zhuǎn)發(fā)

3) 流量控制只適用于Data幀

4) 一個保留字節(jié),一個31位整數(shù)( 發(fā)送端被允許傳輸?shù)淖止?jié)數(shù),它的大小是接收端的緩存能力的衡量)。

5) 流和連接的初始值都是65535;流的窗口大小可以用SETTING幀設(shè)置大小SETTINGS_INITIAL_WINDOW_SIZE;

6) 通過設(shè)置窗口大小,可能導(dǎo)致窗口大小為負數(shù)(當前有10字節(jié)數(shù)據(jù),設(shè)置為5字節(jié),則剩余-5字節(jié)的長度)。

10、CONTINUATION:延續(xù)幀,Type=0x9,延續(xù)一個報頭區(qū)塊

CONTINUATION Frame Payload

只要流上前一幀是不帶END_HEADERS的HEADERS幀、PUSH_PROMISE幀或者不帶有END_HEADERS標記的CONTINUATION幀,可以發(fā)送任意多個延續(xù)幀。

CONTINUATION?幀定義了以下的Flags:

END_HEADERS (0x4)?: 位3,指示幀是否是報頭區(qū)塊的終止。 如果END_HEADERS位沒有被設(shè)置,這個幀必須跟著另一個延續(xù)幀。

HTTP2 錯誤碼

Error Code Registry

HTTP2 連接過程

http2 的版本標識:

h2:基于TLS之上構(gòu)建的HTTP/2,作為ALPN的標識符,兩個字節(jié)表示,0x68, 0x32,即https

h2c:直接在TCP之上構(gòu)建的HTTP/2,缺乏安全保證,即http

HTTP版本的請求過程:

在不知道服務(wù)器是否支持http2的情況下,可以利用http的升級機制發(fā)送試探包

1、客戶端發(fā)起請求

2、服務(wù)器不支持 http2,直接按照 http/1.1響應(yīng)

3、服務(wù)器支持 http2,通知客戶端切換到http2

4、服務(wù)器發(fā)送的第一個http2幀,必須為SETTINGS幀做為連接序言

5、客戶端接收到101響應(yīng)后,也必須發(fā)送一個序言作為響應(yīng),其邏輯結(jié)構(gòu):

6、客戶端可以馬上發(fā)送請求幀或其它幀過去,不用等待來自服務(wù)器端的SETTINGS幀

7、任一端接收到SETTINGS幀之后,都需要返回一個包含確認標志位SETTIGN作為確認

8、其它幀的正常傳輸

HTTP Upgrade

HTTPS 版本的建立連接:

1、客戶端和服務(wù)器端TLS層協(xié)商

2、客戶端發(fā)送連接序言(同上表示,PRI + SETTINGS)

3、接收到客戶端連接序言之后,服務(wù)器端發(fā)送連接序言

4、雙方各自確認SETTINGS幀

5、其它幀的正常傳輸

ALPN

HTTP/2的直接連接:

1、客戶端必須首先發(fā)送一個連接序言,其邏輯結(jié)構(gòu):

2、發(fā)送完畢序言之后,客戶端可以不用等待來自服務(wù)器端響應(yīng),馬上發(fā)送HTTP/2其它幀

3、服務(wù)器端接收到客戶端的連接序言之后,需要發(fā)送一個SETTINGS幀作為連接序言

4、任一端接收到SETTINGS幀之后,都需要返回一個包含確認標志位SETTIGN作為確認

5、其它幀的正常傳輸

Starting HTTP/2

對比明文版的HTTP/1.1和HTTP/2完成一次請求-響應(yīng):

1、HTTP/1.1在建立建立之后,只需要發(fā)送請求報文數(shù)據(jù)

2、HTTP/2客戶端需要在連接建立之初馬上發(fā)送一個連接序言過去,然后才是正常請求

3、兩端(客戶端+服務(wù)器端)的兩次完整的連接序言+確認的交互流程,多了兩次往返過程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內(nèi)容