HTTP/2.0 Header Compression 头部压缩(下)

912 阅读4分钟

上一篇 我们了解了Header Compression的压缩效果和原理(索引表和静态霍夫曼编码)。这篇文章我们主要是对照 rfc7541 文档,了解Header字段压缩规则,以及实际的表现形式。

Header字段表现形式分为两大类:Indexed数字索引、Literal字符。Literal字符形式又包含三种:有索引、无索引、从不索引。如下图:

接下来我们详细的分析,对于每种表现形式规则,Header字段如何显示的。

1. Indexed Header Field Representation

Header字段都在索引表中(包含静态表、动态表),则直接使用索引表里的Index。表现形式如下:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 1 |        Index (7+)         |
   +---+---------------------------+

索引头字段以1bit1模式开头,后跟7bit的索引值。

Sample

举个简单的例子,:method: GET。 编码过程:Find Index Tables,Index 2 = 0000010,得到10000010。 压缩效果:9B method:GET ---> 1B 10000010

2. Literal Header Field with Incremental Indexing

Header字符需要加入索引,增量Index,且修改Dynamic Table。包含 Name 已经在索引表和Name-Value都不在索引表。

Indexed Name New Value

Name在索引表,Value不在索引表。表现形式如下:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 1 |      Index (6+)       |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

01:索引头开始位,2bit,后面跟6bit的索引值。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

Sample

举个简单的例子,:authority:www.laoqingcai-已注销.com 。通过Wireshark查看编码过程和压缩效果如下: 上图左边是第一次请求,右边是第二次请求。整个压缩效果也很明显,从原始的27Byte,第一次请求变成15Byte,后续请求变成1Byte。

New Name New Value

Name不在索引表,Value不在索引表。表现形式如下:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 1 |           0           |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

01:索引头开始位,2bit,后面6bit为0。 H:Name是否使用静态霍夫曼编码。 Name Length:7bit的Name长度,后面跟Name内容。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

Sample

举个简单的例子,sec-fetch-site:none 。通过Wireshark查看编码过程和压缩效果如下: 上图左边是第一次请求,右边是第二次请求。整个压缩效果也很明显,从原始的19Byte,第一次请求变成16Byte,后续请求变成1Byte。

3. Literal Header Field without Indexing

Header字段不加入index,且不需要修改Dynamic Table。包含Name已经在索引表和Name-Value都不在索引表。

Indexed Name New Value

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 0 |  Index (4+)   |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

0000:索引头开始位,4bit 0。 Index:Name索引。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

New Name New Value

Name不在索引表,格式如下:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 0 |       0       |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

0000:索引头开始位,4bit 0,后面4bit为0。 H:Name是否使用静态霍夫曼编码。 Name Length:7bit的Name长度,后面跟Name内容。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

Sample

举个简单的例子,:path: /api/hello 。通过Wireshark查看编码过程和压缩效果如下:

上图左边是第一次请求,右边是第二次请求。整个压缩效果也很明显,从原始的15Byte,第一次请求变成14Byte,后续还是14Byte。

4. Literal Header Field Never Indexing

Header字段从不加入index,且永不修改Dynamic Table(包含中间节点,代理)。包含Name已经在索引表和Name-Value都不在索引表。

Indexed Name New Value

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 1 |  Index (4+)   |
   +---+---+-----------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

0001:索引头开始位。 Index:Name索引。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

New Name New Value

Name不在索引表,格式如下:

     0   1   2   3   4   5   6   7
   +---+---+---+---+---+---+---+---+
   | 0 | 0 | 0 | 1 |       0       |
   +---+---+-----------------------+
   | H |     Name Length (7+)      |
   +---+---------------------------+
   |  Name String (Length octets)  |
   +---+---------------------------+
   | H |     Value Length (7+)     |
   +---+---------------------------+
   | Value String (Length octets)  |
   +-------------------------------+

0001:索引头开始位,后面4bit全跟0。 H:Name是否使用静态霍夫曼编码。 Name Length:7bit的Name长度,后面跟Name内容。 H:Value是否使用静态霍夫曼编码。 Value Length:7bit的Value长度,后面跟Value内容。

参考链接

rfc7541