背景介紹就到此為止了,歷史的腳步將我們推到了今天這一步?,F(xiàn)在讓我們深入看看該協(xié)議的規(guī)范,看看那些細(xì)節(jié)和概念。
http2是一個(gè)二進(jìn)制協(xié)議。
仔細(xì)想想,如果你是一個(gè)曾經(jīng)跟互聯(lián)網(wǎng)協(xié)議打過(guò)交道,那你很可能本能反對(duì)二進(jìn)制協(xié)議,你甚至準(zhǔn)備好了一大堆理由來(lái)證明基于文本/ascii的協(xié)議是多么的有用,正如你曾無(wú)數(shù)次地通過(guò)手工輸入HTTP請(qǐng)求來(lái)通過(guò)telnet遠(yuǎn)程登陸。
二進(jìn)制的http2可以使成幀更便捷。在HTTP1.1和其他基于文本的協(xié)議中,識(shí)別幀的起始和結(jié)束相當(dāng)復(fù)雜。而在移除掉可選的空白符和其他冗余后,實(shí)現(xiàn)這些會(huì)變得更容易。
另一方面,從幀結(jié)構(gòu)中分離出協(xié)議本身的部分也變得更容易。而在HTTP1中,各個(gè)部分相互交織,一團(tuán)亂麻。
協(xié)議的壓縮特點(diǎn)和其經(jīng)常運(yùn)行在TLS之上的事實(shí)讓純文本的屬性值變得毫無(wú)作用,畢竟也無(wú)法從數(shù)據(jù)流上看到文本。我們需要習(xí)慣于使用類似Wireshark的工具來(lái)從協(xié)議層面對(duì)http2一探究竟。
調(diào)試這樣的協(xié)議將需要curl這樣的工具,要進(jìn)一步地分析網(wǎng)絡(luò)數(shù)據(jù)流需要類似Wireshark的http2解析器。
http2發(fā)送二進(jìn)制幀。幀的類型有很多種,但他們都有如下的公共字段:
Type, Length, Flags, Steam Identifier和frame payload
BREACH和CRIME攻擊的隱患。通過(guò)向流中注入一些已知的文本來(lái)觀察輸出的變化,攻擊者可以推出原始發(fā)送的數(shù)據(jù)。
為協(xié)議的動(dòng)態(tài)內(nèi)容進(jìn)行壓縮并使其免于被攻擊,需要仔細(xì)且全面的考慮。而這正是HTTPbis小組嘗試去做的。
HPACK,HTTP/2頭部壓縮,顧名思義它是一個(gè)專為http2頭部設(shè)計(jì)的壓縮格式。確切的講,它甚至被制定寫入在另外一個(gè)單獨(dú)的草案里。新的格式同時(shí)引入了一些其他對(duì)策讓破解壓縮變得困難,例如采用幀的可選填充和用一個(gè)bit作為標(biāo)記,來(lái)讓中間人不壓縮指定的頭部。
用Roberto Peon(HPACK的設(shè)計(jì)者之一)的話說(shuō),“HPACK旨在提供一個(gè)一致性的實(shí)現(xiàn)使信息量的損失盡可能少,使編解碼快速而方便,使接收方能控制壓縮文本的大小,允許代理重新建立索引(如,通過(guò)代理在前后端共享狀態(tài)),以及對(duì)哈夫曼編碼串的更快速比較”。
HTTP 1.1的有一個(gè)缺點(diǎn)是:當(dāng)一個(gè)含有確切值的Content-Length的HTTP消息被送出之后,你就很難中斷它了。當(dāng)然,通常你可以斷開(kāi)整個(gè)TCP鏈接(但也不總是可以這樣),但這樣導(dǎo)致的代價(jià)就是需要重新通過(guò)三次握手建立一個(gè)新的TCP連接。
一個(gè)更好的方案是只終止當(dāng)前傳輸?shù)南⒉⒅匦掳l(fā)送一個(gè)新的。在http2里面,我們可以通過(guò)發(fā)送RST_STREAM幀來(lái)實(shí)現(xiàn)這種需求,從而避免浪費(fèi)帶寬和中斷已有的連接。
這個(gè)功能通常被稱作“緩存推送”。主要的思想是:當(dāng)一個(gè)客戶端請(qǐng)求資源X,而服務(wù)器知道它很可能也需要資源Z的情況下,服務(wù)器可以在客戶端發(fā)送請(qǐng)求前,主動(dòng)將資源Z推送給客戶端。這個(gè)功能幫助客戶端將Z放進(jìn)緩存以備將來(lái)之需。
服務(wù)器推送需要客戶端顯式的允許服務(wù)器提供該功能。但即使如此,客戶端依然能自主選擇是否需要中斷該推送的流。如果不需要的話,客戶端可以通過(guò)發(fā)送一個(gè)RST_STREAM幀來(lái)中止。
http2上面每個(gè)流都擁有自己的公示的流量窗口,它可以限制另一端發(fā)送數(shù)據(jù)。如果你正好知道SSH的工作原理的話,這兩者非常相似。
對(duì)于每個(gè)流來(lái)說(shuō),兩端都必須告訴對(duì)方自己還有更多的空間來(lái)接受新的數(shù)據(jù),而在該窗口被擴(kuò)大前,另一端只被允許發(fā)送這么多數(shù)據(jù)。只有數(shù)據(jù)幀受流量控制。
更多建議: