【CSDN有獎(jiǎng)組稿】科技之路,共同進(jìn)步,高品質(zhì)移動(dòng)發(fā)展,VR/AR/MR,物聯(lián)網(wǎng)原創(chuàng)文章。請(qǐng)給mobilehub@csdn.net發(fā)一封電子郵件。
HTTPS協(xié)議原理分析 HTTPS協(xié)議需要解決的問題HTTPS作為一個(gè)安全協(xié)議而誕生,因此它必須面對(duì)以下兩個(gè)主要的安全問題:
認(rèn)證
保證雙方身份的真實(shí)性。說白了,A想和B溝通,A如何確認(rèn)B的身份不是C偽造的?
通信加密
通信的保密性和完整性取決于算法和密鑰,以及雙方如何選擇算法和密鑰。
如果能同時(shí)解決以上兩個(gè)問題,就能保證真實(shí)有效的通信方采用有效的算法與密鑰進(jìn)行通信,進(jìn)而完成協(xié)議安全的初衷。
在介紹HTTPS協(xié)議如何解決兩個(gè)主要安全問題之前,我們首先了解幾個(gè)概念。
數(shù)字證書
數(shù)字證書是在互聯(lián)網(wǎng)通信中識(shí)別雙方身份信息的數(shù)字文件,由認(rèn)證機(jī)構(gòu)頒發(fā)。
加利福尼亞
證書頒發(fā)機(jī)構(gòu)是數(shù)字證書的頒發(fā)機(jī)構(gòu)。作為權(quán)威機(jī)構(gòu),它在審查申請(qǐng)人的身份后簽發(fā)數(shù)字證書,這樣我們只需要驗(yàn)證數(shù)字證書就可以確定對(duì)方的真實(shí)身份。
HTTPS協(xié)議、SSL協(xié)議、TLS協(xié)議和握手協(xié)議的關(guān)系
HTTPS是安全套接層上超文本傳輸協(xié)議的簡(jiǎn)稱,即SSL上的HTTP,可以理解為基于SSL的HTTP協(xié)議。HTTPS協(xié)議的安全性是通過SSL協(xié)議實(shí)現(xiàn)的(目前常用的,本文以TLS 1.2為基礎(chǔ)進(jìn)行分析)。
SSL協(xié)議是一種記錄協(xié)議,具有良好的可擴(kuò)展性,可以輕松添加子協(xié)議,握手協(xié)議是SSL協(xié)議的子協(xié)議。
TLS協(xié)議是SSL協(xié)議的后續(xù)版本,本文涉及的SSL協(xié)議默認(rèn)為TLS協(xié)議1.2版。
HTTPS協(xié)議的安全性是通過SSL協(xié)議實(shí)現(xiàn)的,目前的TLS協(xié)議1.2版包含四個(gè)核心子協(xié)議:握手協(xié)議、密鑰配置切換協(xié)議、應(yīng)用數(shù)據(jù)協(xié)議和告警協(xié)議。
握手協(xié)議是認(rèn)證和通信加密的核心。接下來(lái),著重介紹握手協(xié)議。
信號(hào)交換協(xié)議
握手協(xié)議的作用是確認(rèn)雙方身份,協(xié)商安全連接的參數(shù)(加密算法、密鑰等)。),從而保證雙方的真實(shí)身份,協(xié)商的算法和密鑰可以保證通信安全。
握手協(xié)議的引入僅限于客戶端-服務(wù)器認(rèn)證,單向認(rèn)證也是互聯(lián)網(wǎng)公司最常用的認(rèn)證方式。
首先,讓我們看看協(xié)議交互,如圖1所示:
圖1握手協(xié)議
接下來(lái),以Wireshark抓取接口的握手協(xié)議流程為例,分析每個(gè)協(xié)議消息。
ClientHello消息
ClientHello消息的作用是一次性向服務(wù)器發(fā)送客戶端可以用來(lái)建立加密通道的參數(shù)集。
消息內(nèi)容包括預(yù)期的協(xié)議版本(TLS 1.2)、可用的密碼套件、客戶端隨機(jī)數(shù)、擴(kuò)展和其他信息,如圖2所示。
圖2客戶端您好
服務(wù)器你好消息
服務(wù)器Hello消息的功能是從客戶機(jī)Hello參數(shù)集中選擇適當(dāng)?shù)膮?shù),并將服務(wù)器用來(lái)建立加密通道的參數(shù)發(fā)送給客戶機(jī)。
消息內(nèi)容包括:采用的協(xié)議版本(TLS 1.2)、采用的密碼套件、服務(wù)器隨機(jī)數(shù)、會(huì)話標(biāo)識(shí)(用于恢復(fù)會(huì)話的會(huì)話標(biāo)識(shí))、擴(kuò)展字段,如圖3所示。
從那時(shí)起,客戶端和服務(wù)器之間的協(xié)議版本和密碼套件就已經(jīng)協(xié)商好了。
這里,服務(wù)器發(fā)出的會(huì)話ID可以用于后續(xù)的會(huì)話恢復(fù)。如果客戶端在ClientHello中攜帶會(huì)話ID,并且服務(wù)器批準(zhǔn),則雙方可以通過原主密鑰直接生成新的一組密鑰繼續(xù)通信。將兩次網(wǎng)絡(luò)往返減少到一次網(wǎng)絡(luò)往返,提高渠道建立效率。
圖3服務(wù)器你好
證書消息
證書消息的目的是向客戶端發(fā)送服務(wù)器證書的詳細(xì)信息,以便客戶端驗(yàn)證服務(wù)器身份。
消息內(nèi)容:服務(wù)器頒發(fā)的證書鏈,如圖4所示。
為了保證客戶端能夠正確識(shí)別出頒發(fā)的證書,服務(wù)器需要將頒發(fā)該證書的CA證書一起頒發(fā),形成證書鏈,保證客戶端能夠根據(jù)證書鏈的信息在系統(tǒng)配置中找到根證書,并通過根證書的公鑰逐層驗(yàn)證證書的有效性。
如圖,58服務(wù)器頒發(fā)了兩個(gè)證書:自己的證書和頒發(fā)CA的證書。通過頒發(fā)CA的證書信息,可以直接找到根證書。
圖4證書
客戶端在本地驗(yàn)證服務(wù)器證書。如果驗(yàn)證通過,客戶端到服務(wù)器的身份驗(yàn)證就完成了。
證書解決了兩端的認(rèn)證問題。有了CA的權(quán)力,證書由CA頒發(fā),認(rèn)證交給CA。
只要是我們認(rèn)可的CA,我們都認(rèn)可證書持有人的身份。由于CA的介入,解決了中間人攻擊的問題,因?yàn)橹虚g人沒有服務(wù)器的證書供客戶端驗(yàn)證。
服務(wù)器密鑰交換消息(可能無(wú)法發(fā)送)
服務(wù)器密鑰交換消息的功能是將服務(wù)器提供的密鑰交換的額外參數(shù)發(fā)送給客戶端。有些算法不需要額外的參數(shù),所以服務(wù)器密鑰交換消息可能不會(huì)發(fā)送。
消息內(nèi)容:密鑰交換的附加參數(shù),如圖5所示。
圖5服務(wù)器密鑰交換
如圖5所示,服務(wù)器發(fā)出“EC Diffile-Hellman”密鑰交換算法所需的參數(shù)。
服務(wù)器錯(cuò)誤消息
ServerHelloDone消息的目的是通知客戶端服務(wù)器hello階段的數(shù)據(jù)已經(jīng)發(fā)送,等待客戶端的下一條消息。
ClientKeyExchange消息
客戶機(jī)密鑰交換消息的目的是向服務(wù)器發(fā)送客戶機(jī)提供密鑰交換所需的數(shù)據(jù)。
當(dāng)我們選擇RSA密鑰交換算法時(shí),該消息的內(nèi)容是由證書的公鑰加密并用于生成主密鑰的預(yù)主密鑰。
如圖6所示,因?yàn)檫x擇的密鑰交換算法是“EC Diffie-Hellman”,所以ClientKeyExchange消息發(fā)送“EC Diffie-Hellman”算法所需的客戶端參數(shù)。
圖6客戶端密鑰交換
客戶端密鑰交換發(fā)送時(shí),兩端都有完整的密鑰數(shù)據(jù)和隨機(jī)數(shù)生成主密鑰,兩端都可以根據(jù)選擇的算法計(jì)算主密鑰。
至此,ClientKeyExchange發(fā)送后,兩端都可以生成主密鑰,解決了密鑰交換問題。
有些讀者可能對(duì)隨機(jī)數(shù)的使用有些懷疑。作者認(rèn)為加入隨機(jī)數(shù)是為了提高密鑰的隨機(jī)性。
因?yàn)榭蛻舳酥苯由傻拿荑€很可能不夠隨機(jī),所以通過使用預(yù)主密鑰加上兩端提供的兩個(gè)隨機(jī)數(shù)作為種子,可以保證創(chuàng)建的主密鑰更接近真實(shí)的隨機(jī)密鑰。
更改密碼規(guī)格消息
經(jīng)過以上六條消息,我們解決了身份認(rèn)證、密碼組選擇和密鑰交換等問題。雙方還通過主密鑰生成了六個(gè)實(shí)際使用的加密和解密密鑰。
ChangeCipherSpec消息的功能是聲明所有后續(xù)消息都是用密鑰加密的。這條消息之后,我們就看不到WireShark上的明文信息了。
已完成的消息
Finished message的作用是計(jì)算握手階段所有消息的匯總,并發(fā)送給對(duì)方驗(yàn)證,避免在通信過程中被中間人篡改。
HTTPS議定書概要
從那時(shí)起,我們就知道HTTPS如何通過引入握手協(xié)議來(lái)確保通信安全。
然而,在充分利用HTTPS之前,我們還需要考慮一個(gè)眾所周知的問題——HTTPS的表現(xiàn)。
與HTTP協(xié)議相比,HTTPS協(xié)議建立數(shù)據(jù)通道更加耗時(shí)。如果直接部署在App中,必然會(huì)降低數(shù)據(jù)傳輸效率,間接影響用戶體驗(yàn)。
接下來(lái),我們介紹HTTPS性能拯救者——HTTP 2協(xié)議。
協(xié)議新寵HTTP 2協(xié)議介紹
隨著互聯(lián)網(wǎng)的飛速發(fā)展,HTTP1.x協(xié)議發(fā)展迅速,但是當(dāng)一個(gè)App頁(yè)面包含幾十個(gè)請(qǐng)求時(shí),HTTP1.x協(xié)議的局限性就暴露出來(lái)了:
每個(gè)請(qǐng)求和響應(yīng)都需要建立一個(gè)單獨(dú)的鏈接來(lái)發(fā)出請(qǐng)求(連接字段可以解決一些問題),這就浪費(fèi)了資源。
每個(gè)請(qǐng)求和響應(yīng)都需要添加完整的報(bào)頭信息,應(yīng)用數(shù)據(jù)傳輸效率低。
默認(rèn)不加密,數(shù)據(jù)在傳輸過程中容易被監(jiān)控和篡改。
HTTP2就是為了解決HTTP1.x暴露的問題而誕生的
說到HTTP2,不得不提spdy。
由于HTTP1.x暴露的問題,Google設(shè)計(jì)了一個(gè)新的協(xié)議,叫做spdy。Spdy在五層協(xié)議棧的TCP層和HTTP層引入了新的邏輯層,提高了效率。Spdy是中間層,兼容TCP層和HTTP層,在不修改HTTP層的情況下,可以提高應(yīng)用數(shù)據(jù)傳輸速度。
通過復(fù)用技術(shù),spdy使客戶端和服務(wù)器能夠多次交互,提高了通信效率。
而HTTP2是基于spdy開發(fā)的。
通過引入流和幀的概念,繼承了spdy的復(fù)用性,并增加了一些實(shí)用特性。
HTTP2有什么特點(diǎn)?HTTP2的特性不僅解決了上述暴露的問題,還具有一些使HTTP協(xié)議更加有用的功能。
多路技術(shù)
壓縮標(biāo)題信息
優(yōu)先處理請(qǐng)求
支持服務(wù)器向客戶端推送消息
另外,目前HTTP2只在HTTPS協(xié)議場(chǎng)景中使用,在握手階段通過ClientHello和ServerHello的擴(kuò)展字段協(xié)商,所以目前HTTP2的使用場(chǎng)景默認(rèn)都是安全加密的。
下面描述HTTP2協(xié)議協(xié)商的兩個(gè)特點(diǎn),復(fù)用和報(bào)頭信息壓縮。實(shí)現(xiàn)部分利用okhttp源代碼(基于parent-3.4.2)進(jìn)行分析介紹。
okhttp是目前使用最廣泛的支持HTTP2的Android開源網(wǎng)絡(luò)庫(kù)。以okhttp為例介紹HTTP2特性,也可以方便讀者提前了解okhttp,以后訪問okhttp。
協(xié)議協(xié)商HTTP2協(xié)議的協(xié)商在握手階段進(jìn)行。
協(xié)商的方式是擴(kuò)展握手協(xié)議擴(kuò)展字段,增加一個(gè)應(yīng)用層協(xié)議協(xié)商字段進(jìn)行協(xié)商。
在握手協(xié)議的客戶機(jī)Hello階段,客戶機(jī)在應(yīng)用層協(xié)議協(xié)商字段中填寫支持的協(xié)議列表,供服務(wù)器選擇。如圖7所示:
圖7 ALPN1
收到ClientHello消息后,服務(wù)器從客戶端支持的協(xié)議列表中選擇適當(dāng)?shù)膮f(xié)議作為后續(xù)的應(yīng)用層協(xié)議。如圖8所示:
圖8 ALPN2
這樣,兩端都完成了HTTP2協(xié)議的協(xié)商。
在沒有HTTP2的情況下,spdy還通過擴(kuò)展字段來(lái)擴(kuò)展next_protocol_negotiation字段,并與NPN協(xié)議協(xié)商spdy。然而,由于NPN協(xié)商的復(fù)雜性,對(duì)https協(xié)議的入侵性很強(qiáng),在ALPN協(xié)商協(xié)議出現(xiàn)后,逐漸被淘汰。因此,本文討論了協(xié)議協(xié)商,并介紹了NPN協(xié)議的協(xié)商。
協(xié)議特性之多路復(fù)用為了優(yōu)化http1.x對(duì)TCP性能的浪費(fèi),http2提出了復(fù)用的概念。
復(fù)用的意義
在HTTP2中,同一個(gè)域名下的請(qǐng)求可以通過同一個(gè)TCP鏈路傳輸,這樣多個(gè)請(qǐng)求就不需要獨(dú)立建立鏈路,節(jié)省了建立鏈路的開銷。
為了達(dá)到這個(gè)目的,HTTP2提出了流和框架的概念。流表示請(qǐng)求和響應(yīng),而請(qǐng)求和響應(yīng)的具體數(shù)據(jù)被打包成幀。鏈路中傳輸?shù)臄?shù)據(jù)根據(jù)流標(biāo)識(shí)和幀類型進(jìn)行不同的處理。圖9是復(fù)用的抽象圖,其中每個(gè)塊代表一個(gè)幀,而相同顏色的塊代表相同的流。
圖9 http2_stream
那么HTTP2復(fù)用是如何實(shí)現(xiàn)的呢?
由于有許多網(wǎng)絡(luò)請(qǐng)求的場(chǎng)景,我們選擇其中一個(gè)路徑來(lái)介紹:
已經(jīng)在域名中的客戶端和服務(wù)器之間建立了一個(gè)TCP通道
新創(chuàng)建的客戶端請(qǐng)求通過連接的TCP通道發(fā)送和響應(yīng)
多路復(fù)用實(shí)現(xiàn)
默認(rèn)情況下,我們添加了各種參數(shù)來(lái)創(chuàng)建請(qǐng)求對(duì)象R,并通過請(qǐng)求對(duì)象創(chuàng)建了調(diào)用對(duì)象C。在獨(dú)立線程中,調(diào)用c.execute()方法執(zhí)行同步請(qǐng)求操作。
okhttp調(diào)用execute方法后,實(shí)際上是由一系列的攔截器執(zhí)行的。
攔截器是按照添加的順序執(zhí)行的,其中我們關(guān)注的是RetryAndFollowUpInterceptor、ConnectInterceptor0和CallServerInterceptor。
1.在RetryAndFollowUpInterceptor中,okhttp為我們創(chuàng)建了一個(gè)StreamAllocation對(duì)象,其中包含一個(gè)基于url創(chuàng)建的Address對(duì)象。
地址類的url字段不同于請(qǐng)求類的URL字段。Address類的url字段不包含路徑和查詢字段,只包含方案和權(quán)限,這在Connection復(fù)用的平等操作中起著很大的作用。
2.在連接攔截器中,流分配對(duì)象的地址依次與連接池中每個(gè)連接對(duì)象的地址相匹配,匹配成功并滿足某些條件的連接可以被重用?;谄ヅ涞倪B接為后續(xù)的讀寫操作創(chuàng)建Http2xStream。
連接池中與Address的匹配主要是通過Address的url,url因?yàn)橹话桨负蜋?quán)限,所以可以用于域名匹配,這是基于域名級(jí)別的okhttp復(fù)用的基礎(chǔ)。
其實(shí)真正的流讀寫操作是FramedConnection和FramedStream,Connection和Http2xStream是為了方便上層而從具體操作中抽象出來(lái)的類。
3.在CallServerInterceptor中,Http2xStream為請(qǐng)求發(fā)送創(chuàng)建一個(gè)FrameStream,用對(duì)應(yīng)的StreamID緩存FrameStream綁定,這樣在響應(yīng)到來(lái)時(shí),就可以根據(jù)StreamID索引來(lái)跟進(jìn)操作。
在FramedStream發(fā)送請(qǐng)求后,執(zhí)行readResponseHeaders方法時(shí)調(diào)用等待,當(dāng)前線程被掛起。
當(dāng)幀連接讀取線程接收到流標(biāo)識(shí)消息時(shí),它會(huì)查詢緩存中的幀流,并喚醒相應(yīng)的線程進(jìn)行響應(yīng)解碼。
總結(jié)okhttp的復(fù)用實(shí)現(xiàn)思路:
通過將請(qǐng)求的地址與連接池中現(xiàn)有的連接地址進(jìn)行匹配,選擇可用的連接。
由Http2xStream創(chuàng)建的FramedStream在發(fā)送請(qǐng)求后緩存FramedConnection中FramedStream對(duì)象和StreamID之間的映射關(guān)系。
收到消息后,幀連接解析幀信息,通過解析的流標(biāo)識(shí)從映射中選擇緩存的幀流,并喚醒幀流來(lái)處理響應(yīng)。
在我看來(lái),http2是一種與http協(xié)議格式兼容的自定義協(xié)議,通過Stream向請(qǐng)求分發(fā)數(shù)據(jù),通過Frame對(duì)請(qǐng)求數(shù)據(jù)進(jìn)行詳細(xì)細(xì)分。
協(xié)議特性之壓縮頭信息為了解決HTTP1.x中報(bào)頭信息過多導(dǎo)致效率低下的問題,HTTP2提出的解決方案是壓縮報(bào)頭信息。在具體的壓縮模式中,引入了HPACK。
HPACK壓縮算法專用于HTTP2報(bào)頭壓縮。為了壓縮報(bào)頭信息,HPACK緩存報(bào)頭字段作為索引,索引ID代表報(bào)頭字段??蛻舳撕头?wù)器端維護(hù)索引表,在通信過程中盡量使用索引進(jìn)行通信,收到索引后查詢索引表,從而分析出真實(shí)的表頭信息。
HPACK索引表分為動(dòng)態(tài)索引表和靜態(tài)索引表。動(dòng)態(tài)索引表是HTTP2協(xié)議通信時(shí)兩端動(dòng)態(tài)維護(hù)的索引表,靜態(tài)索引表是硬編碼到協(xié)議中的索引表。
作為分析H-pack壓縮頭信息的基礎(chǔ),有必要介紹H-pack如何表示索引和頭字符串。
指數(shù)
索引用整數(shù)表示。由于HPACK需要考慮壓縮、編碼和解碼,整數(shù)的結(jié)構(gòu)定義如圖10所示。
圖10內(nèi)部支柱
類別id
HPACK分類是通過類別識(shí)別來(lái)指導(dǎo)后續(xù)的編解碼操作,共有1,010,100,000,000等八個(gè)常見類別。
第一個(gè)字節(jié)低整數(shù)
第一個(gè)字節(jié)不包括類別標(biāo)識(shí)符的剩余位,后者用于指示較低的整數(shù)。如果該值大于剩余位表示的容量,則需要后續(xù)字節(jié)來(lái)表示高整數(shù)。
結(jié)束id
指示該字節(jié)是否為整數(shù)解析終止字節(jié)。
高整數(shù)
字節(jié)的剩余7位用于填充高整數(shù)位。
根據(jù)數(shù)據(jù)大小,可能有0個(gè)或更多“結(jié)束標(biāo)識(shí)+高整數(shù)”字節(jié)。
例如,如果您想指示類為1,索引為2,可以使用10000010,并且不需要額外的字節(jié)來(lái)增加高整數(shù)。
標(biāo)題字符串
頭串的長(zhǎng)度需要顯式聲明,所以數(shù)據(jù)的第一個(gè)字節(jié)由“類型標(biāo)識(shí)符+數(shù)據(jù)長(zhǎng)度”組成。如圖11所示:
圖11弦_支柱
類型id
是否選擇霍夫曼編碼,選擇1,不選擇0,okhttp默認(rèn)不選擇霍夫曼編碼。
數(shù)據(jù)長(zhǎng)度
標(biāo)識(shí)數(shù)據(jù)長(zhǎng)度,用上面提到的整數(shù)表示法表示。
數(shù)據(jù)內(nèi)容
二進(jìn)制數(shù)據(jù)。
解碼示例
下面全面的okhttp源代碼分析HPACK解碼頭字段的過程。
對(duì)編碼感興趣的讀者可以參考RFC 7541或者直接分析OkHttp源代碼。
當(dāng)我們需要解碼報(bào)頭字段時(shí),我們首先解析報(bào)頭字段的第一個(gè)字節(jié)(HPACK報(bào)頭字段的第一個(gè)字節(jié)分為8個(gè)類別,其中選擇了3個(gè)類別描述),第一個(gè)字節(jié)用于指導(dǎo)當(dāng)前報(bào)頭字段的解析規(guī)則:
1xxxxxxx
類id為1,這意味著接收到一個(gè)以k和v為索引的頭字段。
k,V值:通過解析HPACK整數(shù)得到KV對(duì)的索引值,根據(jù)索引值映射對(duì)應(yīng)的頭原字段,壓縮效率最高。
01xxxxxx
類別ID為01,表示接收到以K為索引、V為原始字段的表頭字段,需要添加到動(dòng)態(tài)索引表中。
k值:k值的索引值是通過解析HPACK整數(shù)得到的,對(duì)應(yīng)的頭原字段由索引值映射。
v值:v值的原始字段是通過解析HPACK字符串得到的。
k和v的值需要插入到動(dòng)態(tài)索引表中。
01000000
01000000表示k和v都是原始字段,需要添加到動(dòng)態(tài)索引表的表頭字段。
k和v值:k和v的原始字段通過解析HPACK字符串得到,并插入到動(dòng)態(tài)索引表中。
有不添加動(dòng)態(tài)索引表、調(diào)整索引表大小等類別,這里不展開。如果有興趣,可以看看okhttp源代碼的實(shí)現(xiàn)。
okhttp解析頭信息的核心方法實(shí)現(xiàn)如下:
voidreadHeaders()引發(fā)IOException {
while(!source . excluded()){ int b = source . read byte()& amp;0xff
if(b = = 0x 80){//10000000//類別ID為1,但索引為0 0 throwenwioeexception(" index = = 0 ");} else if((b & amp;0x 80)= = 0x 80){//1 nnnnnn//類別為1,整數(shù)索引通過readIndexedHeader解析。int index = ReadNT(b,PREFX _ 7 _ BITS);
//通過index獲取完整的表頭字段readIndexedHeader(index-1);} else if(b = = 0x 40){//01000000//0100000表示KV為原字段。對(duì)字符串進(jìn)行分析,依次得到k值和v值,插入到動(dòng)態(tài)表read literatureheaderwith incrementalidenxignewname();} else if((b & amp;0x 40)= = 0x 40){//01 nnnnnn//01 xxxxx代表k值作為索引,v值作為原始字符串。依次解析整數(shù)索引和字符串,在動(dòng)態(tài)表中插入int index = readint (b,prefix _ 6 _ bits);readliteralheaderwrithincrementalindexingindexed name(index-1);} else if((b & amp;0x 20)= = 0x 20){//001 nnnn//類別為001,表示更新動(dòng)態(tài)列表容量maxdynamictablebytecount = readint(b,prefix _ 5 _ bits
if(MaxDynamiCTableByteCount & lt;0 | | MaxDynamiCTableByteCount & gt;headeratableizesetting){
thrownewIOException("無(wú)效動(dòng)態(tài)表大小更新"+maxDynamicTableByteCount);} adjustDynamicTableByteCount();} elseif(b == 0x10|| b == 0) { // 000?0000-忽略從不索引位。//此類別表示KV為原始字符串,字符串依次解析,解析后的KV值不插入動(dòng)態(tài)表。readLiteralHeaderWithoutIndexingNewName();} else{ // 000?NNNN-忽略從不索引位。//類似于前一類,但是k是索引,v是原字符串int index = readint (b,prefix _ 4 _ bits);readliteralheadrwithoutindexingindexed name(index-1);} }}
壓縮效應(yīng)
k值為“accept-encoding”v值為“g,deflate”的頭字段,在HTTP2中可以用索引值15代替,從而達(dá)到頭字段壓縮的效果。
“accept-charset”報(bào)頭字段用14表示報(bào)頭k值,該值根據(jù)HPACK規(guī)則被編碼并寫入流中。
有了HPACK,一個(gè)報(bào)頭字段變化少的App,會(huì)把每個(gè)報(bào)頭字段壓縮到4字節(jié)以下,壓縮效果非常明顯。
1.《clientkey HTTPS 與 HTTP2 協(xié)議分析》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識(shí),僅代表作者本人觀點(diǎn),與本網(wǎng)站無(wú)關(guān),侵刪請(qǐng)聯(lián)系頁(yè)腳下方聯(lián)系方式。
2.《clientkey HTTPS 與 HTTP2 協(xié)議分析》僅供讀者參考,本網(wǎng)站未對(duì)該內(nèi)容進(jìn)行證實(shí),對(duì)其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。
3.文章轉(zhuǎn)載時(shí)請(qǐng)保留本站內(nèi)容來(lái)源地址,http://f99ss.com/fangchan/938305.html