2. 压缩过程概述
本规范不描述编码器的具体算法. 相反, 它精确定义了解码器应如何运行, 允许编码器产生此定义所允许的任何编码.
2.1. header list 顺序
HPACK 保留 header list 中 header field 的顺序. 编码器 MUST 按原始 header list 中的顺序, 对 header block 中的 header field representation 进行排序. 解码器 MUST 按 header block 中的顺序, 对已解码 header list 中的 header field 进行排序.
2.2. 编码和解码上下文
为了解压缩 header block, 解码器只需要维护一个 dynamic table (见 Section 2.3.2) 作为解码上下文. 不需要其他动态状态.
当用于双向通信时, 例如在 HTTP 中, 端点维护的编码 dynamic table 和解码 dynamic table 完全独立, 即请求和响应的 dynamic table 是分开的.
2.3. 索引表
HPACK 使用两个表将 header field 与索引关联起来. static table (见 Section 2.3.1) 是预定义的, 包含常见的 header field (其中大多数的值为空). dynamic table (见 Section 2.3.2) 是动态的, 编码器可以使用它对已编码 header list 中重复出现的 header field 建立索引.
这两个表会合并到一个单一地址空间中, 用于定义索引值 (见 Section 2.3.3).
2.3.1. static table
static table 由预定义的静态 header field 列表组成. 其条目在 Appendix A 中定义.
2.3.2. dynamic table
dynamic table 由一个 header field 列表组成, 该列表按先进先出的顺序维护. dynamic table 中第一个也是最新的条目位于最低索引处, dynamic table 中最旧的条目位于最高索引处.
dynamic table 初始为空. 随着每个 header block 被解压缩, 条目会被添加进去.
dynamic table 可以包含重复条目 (即 name 相同且 value 相同的条目). 因此, 解码器 MUST NOT 将重复条目视为错误.
编码器决定如何更新 dynamic table, 因而可以控制 dynamic table 使用多少内存. 为了限制解码器的内存需求, dynamic table size 受到严格限制 (见 Section 4.2).
解码器在处理 header field representation 列表期间更新 dynamic table (见 Section 3.2).
2.3.3. index address space
static table 和 dynamic table 会合并为一个单一 index address space.
从 1 到 static table 长度之间的索引 (含两端) 引用 static table 中的元素 (见 Section 2.3.1).
严格大于 static table 长度的索引引用 dynamic table 中的元素 (见 Section 2.3.2). 要找到 dynamic table 中的索引, 需要减去 static table 的长度.
严格大于两个表长度之和的索引 MUST 被视为 decoding error.
对于大小为 s 的 static table 和大小为 k 的 dynamic table, 下图展示了整个有效的 index address space.
`<---------- Index Address Space ---------->`
`<-- Static Table -->` `<-- Dynamic Table -->`
+---+-----------+---+ +---+-----------+---+
| 1 | ... | s | |s+1| ... |s+k|
+---+-----------+---+ +---+-----------+---+
^ |
| V
Insertion Point Dropping Point
Figure 1: Index Address Space
2.4. header field representation
已编码的 header field 可以表示为索引或字面值.
indexed representation 将 header field 定义为对 static table 或 dynamic table 中某个条目的引用 (见 Section 6.1).
literal representation 通过指定 name 和 value 来定义 header field. header field name 可以按字面值表示, 也可以表示为对 static table 或 dynamic table 中某个条目的引用. header field value 按字面值表示.
本规范定义了三种不同的 literal representation:
-
一种 literal representation, 它将 header field 作为新条目添加到 dynamic table 的开头 (见 Section 6.2.1).
-
一种 literal representation, 它不将 header field 添加到 dynamic table (见 Section 6.2.2).
-
一种 literal representation, 它不将 header field 添加到 dynamic table, 并额外规定此 header field 始终使用 literal representation, 尤其是在由中介重新编码时 (见 Section 6.2.3). 这种 representation 旨在保护不应因压缩而面临风险的 header field value (更多细节见 Section 7.1.3).
可以根据安全考虑选择这些 literal representation 中的一种, 以保护敏感的 header field value (见 Section 7.1).