RFC 7541: HPACK: Header Compression for HTTP/2
總結此頁面
全文總結
本文檔為《HPACK: Header Compression for HTTP/2》,由 R. Peon 撰寫,屬於互聯網標準軌道文檔。該規範定義了 HPACK,一種用於高效表示 HTTP 頭字段的壓縮格式,用於 HTTP/2。文檔詳細介紹了 HPACK 的各個方面,包括壓縮過程概述、頭塊解碼、動態表管理、基本類型表示、二進制格式和安全考慮等內容。
重要亮點
HPACK 的定義和目的:HPACK 是一種用於 HTTP/2 的頭字段壓縮格式,旨在消除冗餘頭字段、限制已知安全攻擊的脆弱性,並在受限環境中有有限的內存需求。它的格式簡單且不靈活,以減少因實現錯誤導致的互操作性或安全問題的風險。
壓縮過程概述:HPACK 不描述特定的編碼器算法,而是精確定義瞭解碼器的操作方式。它使用兩個表(靜態表和動態表)將頭字段映射到索引值,編碼時可以根據頭字段的順序和安全性考慮選擇不同的表示方式,包括索引表示和三種不同的字面量表示。
頭塊解碼:解碼器按順序處理頭塊以重建原始頭列表,處理過程中遵循特定規則,確保成功解碼併產生頭列表。一旦頭字段被解碼並添加到頭列表中,就不能被刪除。
動態表管理:為了限制解碼器的內存需求,動態表的大小受到嚴格限制。可以通過計算表大小、設置最大表大小、在表大小變化時進行條目驅逐以及在添加新條目時進行條目驅逐等方式來管理動態表。
基本類型表示:HPACK 編碼使用兩種基本類型,即無符號可變長度整數和字節字符串。整數表示可以在字節的任何位置開始,為了優化處理,總是在字節的末尾結束。字符串字面量可以直接編碼或使用霍夫曼編碼。
二進制格式:詳細描述了不同頭字段表示和動態表大小更新指令的二進制格式,包括索引頭字段表示、三種字面量頭字段表示(帶增量索引、不帶索引和永不索引)。
給一個編碼樣例並解釋
以下是一個使用 HPACK 進行編碼的樣例,並對其進行解釋。
樣例:編碼請求頭字段
假設我們要編碼以下 HTTP/2 請求頭字段:
:method: GET
:scheme: http
:path: /
:authority: www.example.com
編碼過程解釋
:method: GET
因為:method: GET是靜態表中的常見頭字段,其索引為 2(參考文檔中的靜態表定義)。所以在 HPACK 中,它將被編碼為一個索引頭字段表示。
二進制格式為:82
解釋:按照索引頭字段表示的格式(文檔中 6.1 節),它以1開頭,後面跟着索引值。這裏索引值為 2,用 7 位前綴表示就是0000010,所以整體就是10000010,十六進制為82。
:scheme: http
同樣是靜態表中的常見頭字段,索引為 6。
二進制格式為:86
解釋:以1開頭,索引值 6 用 7 位前綴表示為0000110,即10000110,十六進制為86。
:path: /
也是靜態表中的常見頭字段,索引為 4。
二進制格式為:84
解釋:以1開頭,索引值 4 用 7 位前綴表示為0000100,即10000100,十六進制為84。
:authority: www.example.com
對於:authority這個頭字段,由於它可能是首次出現或者在動態表中沒有對應的索引,將使用字面量頭字段表示且添加到動態表(增量索引)。
假設www.example.com字符串長度編碼後為 15(這裏省略具體字符串長度編碼過程,可參考文檔中 5.1 節和 5.2 節關於整數和字符串字面量編碼)。
二進制格式為:410f77772e6578616d706c652e636f6d
解釋:
按照字面量頭字段帶增量索引的格式(文檔中 6.2.1 節),它以01開頭。如果頭字段名稱匹配靜態表或動態表中的條目,可以用索引表示,這裏:authority可以用索引 1 表示(在一些特定的索引空間規則下),用 6 位前綴表示為000001。
然後是值長度,這裏假設為 15,用 7 位前綴表示可能是0001111(實際編碼可能因整數編碼規則有細微差異)。
最後是值本身的字節序列,即www.example.com的編碼。
整體編碼結果
將上述編碼結果組合起來,對於這個請求頭字段的 HPACK 編碼就是:828684410f77772e6578616d706c652e636f6d。這個編碼結果將在 HTTP/2 通信中用於傳輸頭字段信息,接收方可以根據 HPACK 的解碼規則進行解碼,還原出原始的頭字段。
接收方和發送方如何約定 HPACK 的解碼規則
接收方和發送方通過以下方式約定 HPACK 的解碼規則:
標準規範約定
遵循 RFC 標準:HPACK 的規範在 RFC 7541 中詳細定義。發送方和接收方都需要遵循這個標準文檔中規定的各種規則和算法。例如,對於頭字段的表示方式(索引表示、字面量表示等)、動態表的管理規則、整數和字符串的編碼規則等都有明確的定義。雙方都按照這些標準規範來實現編碼和解碼邏輯,以確保能夠正確地處理和理解對方發送的數據。
協議協商確定參數
SETTINGS_HEADER_TABLE_SIZE 參數:在 HTTP/2 協議中,通過SETTINGS_HEADER_TABLE_SIZE這個設置參數來協商動態表的大小。發送方和接收方在建立連接時,會通過協議的相關機制交換這個參數的值。這個參數決定了動態表在接收方可以使用的最大內存空間,發送方在編碼過程中需要考慮這個限制,不能超過接收方所允許的動態表大小。接收方則根據這個參數來管理動態表的內存使用,當動態表大小達到或接近這個限制時,可能會進行一些清理或驅逐操作。
其他可能的參數:除了動態表大小參數外,雖然 HPACK 本身相對固定,但在 HTTP/2 協議的框架下,可能還會有一些其他相關的參數或配置信息影響着 HPACK 的使用。例如,協議版本相關的一些特性或設置可能會對 HPACK 的某些行為產生影響,雙方需要確保對這些協議相關的參數和特性有一致的理解和配置。
初始狀態的一致性
靜態表的一致性:HPACK 使用了一個預定義的靜態表,其中包含了常見的頭字段及其索引。發送方和接收方都使用相同的靜態表定義,這是確保正確解碼的基礎。例如,雙方都知道:method: GET在靜態表中的索引是 2,這樣當發送方發送一個索引值為 2 的頭字段表示時,接收方能夠正確地識別它代表的是:method: GET這個頭字段。
動態表的初始狀態:動態表在開始時是為空的,這是雙方都默認的初始狀態。隨着頭塊的解碼,動態表會逐漸被填充。發送方和接收方都從這個相同的初始狀態開始,並且在處理每個頭塊時,根據規範更新動態表的狀態。例如,當發送方發送一個帶有增量索引的字面量頭字段時,接收方會按照規則將其添加到動態表中,並在後續的解碼過程中可能會使用到這個新添加的條目。