Http 2.0 中的 HPACK 算法
什么是 HPACK 算法?
HPACK 算法是一种用于压缩 HTTP 头部字段的算法,它在 HTTP/2 协议中被引入,以解决 HTTP/1.1 中头部字段冗余和占用带宽的问题。12
HPACK 算法的主要特点有:
- 它使用两个表(静态表和动态表)来将头部字段与索引值关联,从而减少头部字段的大小。
- 它使用霍夫曼编码(Huffman coding)来对头部字段的名称和值进行进一步压缩,达到最高压缩比 8:5。
- 它保留了头部字段列表内头部字段的顺序,以便在压缩和解压缩后重建完整的头部列表。
- 它允许编码器决定如何更新动态表,从而控制动态表使用多少内存。
- 它限制了动态表的大小,以减少解码器的存储需求。
- 它消除了多余的头部字段,将漏洞限制到已知的安全攻击,并且在受限的环境中具有有限的内存需求。3
HPACK 算法底层原理及实现
-- todo
如何使用 HPACK 算法?
HPACK 算法的具体过程可以分为以下几个步骤:
- 编码器和解码器分别维护一个动态表作为编码和解码上下文。动态表是一个按先进先出顺序存储头部字段的列表,其中可以包含重复的头部字段。动态表最初是空的,当每个头部块被解压缩时,将添加条目。
- 编码器根据原始头部列表中头部字段的顺序对头部块中的头部字段表示进行排序。解码器根据头部块中的顺序对已解码头部列表中的头部字段进行排序。
- 编码器将每个头部字段表示为索引或字面。索引表示形式定义了一个头部字段,作为对静态表或动态表中条目的引用;字面表示形式通过指定其名称和值来定义头部字段。名称可以用字面形式表示,也可以作为对静态表或动态表中条目的引用。值按字面表示。
- 编码器可以选择将字面值直接编码,也可以使用霍夫曼编码来对字面值进行进一步压缩。霍夫曼编码是一种变长编码,它根据字符出现的概率分配不同长度的二进制编码,使得出现频率高的字符使用较短的编码,出现频率低的字符使用较长的编码。
- 编码器决定是否将某些头部字段作为新条目插入动态表中。这样可以在后续请求中重复使用这些条目,从而减少传输量。编码器还可以通过发送更新指令来调整动态表的大小。
- 解码器接收到编码后的头部块后,根据索引地址空间中的索引值来查找静态表或动态表中的条目,或者根据字面值或霍夫曼编码来解析名称和值。解码器还可以使用霍夫曼树来对霍夫曼编码进行解码,还原出原始的字面值。
- 解码器在处理头部字段表示列表时更新动态表,从而在此过程中重建头部字段的列表。解码器还可以根据编码器发送的更新指令来调整动态表的大小。
下表展示了一个使用 HPACK 算法压缩和解压缩头部字段的示例:
原始头部字段 | 编码后的头部字段 | 解码后的头部字段 |
---|---|---|
:method=GET | 0x82 | :method=GET |
:path=/index.html | 0x85 | :path=/index.html |
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36 | 0x40 0x8a 0x94 e7 0x81 0x9d 29 ad 17 18 62 60 65 a8 e6 10 d9 b4 0x7f d6 ad a8 e6 c2 c3 d4 de ce cf d0 d1 d2 d3 d4 e1 e2 e3 e4 e5 e6 ef f1 f2 f3 f4 f5 f6 f7 ff c8 bf fb fd fc fb df a7 c5 ff | user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36 |
HPACK 算法有什么优势和局限性?
HPACK 算法相比于 HTTP/1.1 中未压缩的头部字段,有以下优势:
- 它可以显着减少头部字段的大小,从而节省带宽和提高传输效率。
- 它可以避免使用 DEFLATE 等通用压缩算法带来的安全风险,如 CRIME 攻击。
- 它可以保持头部字段列表的顺序,以便在不同的上下文中正确解释头部字段。
- 它可以让编码器灵活地控制动态表的使用和大小,以适应不同的场景和需求。
HPACK 算法也有一些局限性,如:
- 它需要编码器和解码器维护一个动态表,并在每次请求或响应时更新动态表,这会增加内存消耗和计算开销。
- 它需要编码器和解码器遵循严格的规范,以保证互操作性和安全性。任何不符合规范的编码或解码都可能导致错误或漏洞。
- 它不能完全消除头部字段的冗余,因为一些头部字段可能没有预定义的索引值,或者一些头部字段的值可能是随机或动态生成的。
总结
HPACK 算法是一种用于压缩 HTTP 头部字段的算法,它在 HTTP/2 协议中被引入,以解决 HTTP/1.1 中头部字段冗余和占用带宽的问题。它使用两个表(静态表和动态表)来将头部字段与索引值关联,从而减少头部字段的大小。它使用霍夫曼编码来对头部字段的名称和值进行进一步压缩,达到最高压缩比 8:5。它保留了头部字段列表内头部字段的顺序,以便在压缩和解压缩后