Hpack 个人理解篇

抽象

该规范定义了HPACK,HPACK的压缩格式有效地表示要在HTTP / 2中使用的HTTP标头字段。

解决问题

HTTP1.X 由于其设计的缺陷,被大家诟病已久,其中头疼的问题之一,就是无意义的重复的头部。
而 HTTP/2 的实现就是参考了 SPDY 协议, 但是专门为头部压缩设计了一套压缩算法,就是我们的 HPACK 。
该规范定义了HPACK,这是一种新型压缩机,它消除了冗余标头字段,将漏洞限制为已知安全性攻击,并且在受限条件下使用时具有有限的内存要求环境。

Hpack 理解

静态索引表

因为表中的参数都是提前定义好的,只有固定的几十个值,当遇到不在静态表中的,就会加入到动态表。
静态索引表用 index 表示在表中的位置,在需要替换时,根据 index 索引进行替换即可,这样就会大大缩减替换时候的开销。

动态索引表

动态表是一个由先进先出的队列维护的有空间限制的表,里面同样维护的是头部与对应的索引。
每个动态表只针对一个连接,每个连接的压缩解压缩的上下文有且仅有一个动态表。
动态表就是,当一个头部没有出现过的时候,会把他插入动态表中,下次同名的值就可能会在表中查到到索引并替换掉头部。为什么我说是可能呢,因为动态表是有最大空间限制的。
动态表的大小 = (每个 Header 的字节数的和+32) * 键值对个数
32是为了头所占用的额外空间和计算头被引用次数而估计的值。
那么动态表是如何管理大小呢,2种情况下,动态表会被修改:
压缩方用上述方式要求动态修改动态表的大小。在这种情况下,如果新的值更小,并且当前大小超过了新值,就会从旧至新,不断的删除头,直到小于等于新的大小。
收到或发出一个新的头部,会触发插入和可能的删除操作。 RFC 里面说的比较复杂,我用等价的语义解释一下。新的值被插到队首,一样从旧到新删除直到空间占用小于等于最大值。那么在这种情况下,如果新来的头比最大值还要大,就等于变相的清除了动态表。
动态索引表中最新的值是索引值最小的,最旧的值是索引值最大的。
动态表与静态表共同组成了索引表的索引空间。

编码

无符号整数编码

在 HPACK 中一个无符号整数,并不总是在一个字节的开始,但是总是在一个字节的末尾结束。


image.jpeg

在这张图中 0-2 bit 表示占位,而在图中 value 表示占了5 bit ,因此,根据2^n-1 公式可得,上图中表示小于32位时一个字节就可以表示,当大于32位时又是另一种情况,如下图:


image.jpeg

第一个字节的 n 个 bit 全部置1,之后用整体字符数量-(2^n-1)获得实际使用位数,最终以0表示结尾。最终,将首字节1占位去掉,最终获得到写入真实字符。

字面字符串编码

image.jpeg

StringData: 如果是 huffman 编码,则使用 huffman 编码后的字符串,否则就是原始串。

静态HUFFMAN编码

Huffman 编码是一个根据字符出现的概率重新编排字符的二进制代码,从而压缩概率高的字符串,进而压缩整个串的长度。
我个人也不是很了解,只是知道一些基础,细细如何压缩计算,我也没理解,如果有对Huffman理解较深的大家可以交流。

Hpack 对 Http 带来的影响

1、为了解决CRIME 带来的安全隐患
2、无意义的重复的头部
3、通过静态索引表和动态索引表,提升压缩性能,减少压缩损耗
4、减少响应带宽损耗

请求头部

:method:GET, :path:/ and :scheme:https总是出现在静态字典里,所以每个都会被编码为一个字节。另外一些头部项只有键会被压缩成一个字节: :authority, accept, accept-encoding, accept-language, cookie 和 user-agent 会出现在静态字典。
没有匹配到的头部会被插入到动态字典给之后的请求使用。
显而易见,在请求头部里的大多数项都是重复的。这意味他们每个都可以被编码至一到两个字节,这样提升是显而易见的。

响应头部

假设可以完全匹配到 12 个头部里的 7 个。剩下的 5 个中,4 个头部的键可以被全部匹配到,以及 6 个字符串(译者注:5 个头部键值共有 10 个字符串,6 个字符串包括 1 个键和 5 个值)将会使用 Huffman 编码进行有效编码。
假设两个 expires 头部几乎是完全相同的,但因为它们不能完全匹配,所以它们只可以用 Huffman 编码进行压缩。
请求越多,动态表会越大,那么更多头部会被匹配到,压缩比率就会更高

测试 Hpack

如果你已经安装了 nghttp2,你可以用一个叫 h2load 的工具测试你的网站里 HPACK 的压缩效率。
附上如何使用 h2load:
http://www.nghttp2.org/documentation/h2load-howto.html
个人还在研究如何查看,这个自己也没搞的太清楚

你可能感兴趣的:(Hpack 个人理解篇)