我尝试实施http / 2代码,我试图向谷歌发送请求。我查看了Wirehark Mozilla Firefox是如何做到的。这是一个例子:
这是第一个SETTINGS
框架之后第一个google请求
Header Block Fragment: 8205a563fc9a52c5649012cf829a03f1f3372e66f78c9eb6...
[Header Length: 590]
[Header Count: 11]
Header: :method: GET
Representation: Indexed Header Field
Header: :path: /?gfe_rd=cr&ei=oVxgWYizHcyRZK-lqKgG&gws_rd=ssl
Representation: Literal Header Field without Indexing - Indexed Name
Header: :authority: www.google.ru
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: :scheme: https
Representation: Indexed Header Field
Header: user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: accept-language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: accept-encoding: gzip, deflate, br
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: cookie: NID=107=L67kU0sEsfzwpItJcUZyRfjKENJ1xa2N8_m4xqnVLCj9dW289EDyzg7ZvXZCt9kEII0nd5BA2Tns95vlkCGlGP850ULPoOKFeMJoaQT_0o7Cl3skG4PDdQgUW2hlRh7Z
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: dnt: 1
Representation: Literal Header Field with Incremental Indexing - New Name
Header: upgrade-insecure-requests: 1
Representation: Literal Header Field with Incremental Indexing - New Name
Padding: <MISSING>
所以客户端的动态表看起来像这样,假设我明白这一点:
1 ->upgrade-insecure-requests: 1
2 ->dnt :1
3 ->cookie: NID=107=kjxoLmF8StT6CO8a8T-z68DAIJB6cyzAwqWOjjmXGubtu2pmJSfGPCjUAo9D-OTzuk03u34YLxLMjH236FBDzKVYayleievvTkamyhrLuOz4AYT_7KiuVIS5JA_BuVEa
4 ->accept-encoding: gzip, deflate, br
5 ->accept-language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
6 ->accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
7 ->user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
8 ->:authority: www.google.ru
标记为Representation: Literal Header Field with Incremental Indexing
的所有标题都插入到动态表中,首先插入的标题,移动到更高的索引,新条目位于顶部。
但是这张表不起作用,因为当浏览器执行第二次请求时,要下载一些图像(谷歌徽标或其他),一些乱七八糟的东西,
第二个请求已解码:
[Header Length: 535]
[Header Count: 11]
Header: :method: GET
Representation: Indexed Header Field
Header: :path: /images/hpp/ic_wahlberg_product_core_48.png8.png
Representation: Literal Header Field without Indexing - Indexed Name
Header: :authority: www.google.ru
Representation: Indexed Header Field
Header: :scheme: https
Representation: Indexed Header Field
Header: user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0
Representation: Indexed Header Field
Header: accept: */*
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: accept-language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3
Representation: Indexed Header Field
Header: accept-encoding: gzip, deflate, br
Representation: Indexed Header Field
Header: referer: https://www.google.ru/
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: cookie: NID=107=j8x_CchswQznRlhYWeTtf7rDE7QaxZBxbGeQevst16TVFJ3qOJjlsVwxEobdZaVAeUFboCuuUhu0VdJwujroT_u5hoGttx5Mcu4xnMZQIfK7OSMhqtSbO135AL8GlZWU
Representation: Literal Header Field with Incremental Indexing - Indexed Name
Header: dnt: 1
Representation: Indexed Header Field
Padding: <MISSING>
这是第二个编码请求:
82 = :method: GET ( index 2 in the static table is "method: GET" )
05 a3 60 d4 8e 62 a1 89 eb ad 83 12 2f 03 9e 88
cb 64 d1 57 61 e4 b4 89 88 87 b0 b1 34 f2 f5 d5
33 cb d7 54 df = :path: /images/hpp/ic_wahlberg_product_core_48.png8.png (05 is the index of "path:" in static table, rest is huffman encoded literal )
c5 = :authority: www.google.ru ( index 8 at the dynamic table, 0xc5 & 0x7f = 69 (dec) static table length (61)? is this correct?
87 = scheme: https - static table
c4 = user-agent: Mozilla/5.0... ( index 7 at the dynamic table, 0xc5 & 0x7f = 68 (dec) static table length (61)? is this correct?
这是我无法理解的地方:
7f 04 83 f9 63 e7
- 根据wireshark的意思,这意味着accept: */*
,并且它被签名为Literal Header Field with Incremental Indexing - Indexed Name
,因此0x7f
应该是标头的索引。文字增量索引的掩码为0x40
,因此我们使用AND
对0x7f
进行布尔0x3f
,得到63
十进制,即dnt: 1
我们的动态表中的标头,这是完全错误的。
有人可以帮忙,这怎么解码正确? http / 2是否使用相同的动态表进行响应解码? (也许那就是为什么我的解码搞砸了?)
答案 0 :(得分:1)
通过仅在查找索引字段信息后查看单个字节(0x7f
或0x3f
),计算错误的索引号。但是,您还需要另外查看HPACK中如何表示整数(以及头字段索引)。 HPACK规范中的5.1 Integer Representation部分对此进行了介绍。
你可以看到,如果第一个字节中用于数字的所有位都设置为零,则还需要考虑下一个字节。在这种情况下会发生这种情况,因为0x3f意味着所有使用的6位都设置为1.因此实际索引号编码为0x7f 0x04
。我认为这应该导致63 + 4 = 67,这是动态表的第6个条目。在第一次请求后,这将匹配您对动态表的预期布局。
顺便说一句:有趣的是它没有从静态表中选择索引19,即accept
。从我的角度来看,这里没有额外的值来引用动态表,只有字段名称(并且没有采用任何值),并且在静态表中查找可能会减少某些实现的开销。
澄清这些问题:
http / 2是否使用相同的动态表进行响应解码?
不,所有已发送标头的动态表都有一个实例(客户端请求标头),所有收到的标头都有一个实例(客户端的响应标头)。