Firefox中奇怪的HTTP / 2 HPAC编码



我正在研究服务器端的HTTP/2实现,并使用Firefox作为测试客户端。 有时我会收到一个看起来被 FF 错误编码的请求。 但在责怪FF之前,我想与您确认我是否正确解码了HPACK数据。

以下是原始请求(按名称排序,如 Firefox 开发控制台所示):

GET /images/rewards/icon-profile-on.png?81aa8356289ae0f1e4715f4f04f681cfe85147f0
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.5
Connection: keep-alive
Cookie: _ga=GA1.3.1983042994.1521655507
Cookie: _gid=GA1.3.1027405523.1521655507
Host: static.kfc.com.my
Referer: https://kfc.com.my/
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0

请注意,一些标头在编码之前被转换,例如 Host 被编码为 :authority,连接被删除 - 这些是 HTTP/2 的要求)。顺序也会更改。 感兴趣的标头是 Cookie 和 Host (:authority)

以下是此请求的 HEADERS 帧数据(十六进制)(在连接的第一个流中)以及我对数据的解释:

// ix=2; :method: GET
"82"
// ix=5; :path: /images/rewards/icon-profile-on.png?81aa8356289ae0f1e4715f4f04f681cfe85147f0
// (not stored in the header table)
"05 b6 60 d4 8e 62 a1 8b 0b e0 76 48 86 0c 43 d4 "
"b5 76 1e 53 50 55 8f 52 f5 d5 37 f8 f0 46 37 99 "
"6d c1 3c f8 ca 09 42 56 9d 0b 72 b5 28 1a 95 c7 "
"82 49 4a f3 61 69 d9 41"
// ix=1->62 (lookup at index 1, store at 62); :authority: static.kfc.com.my
"41 8c 42 46 93 11 7e b2 91 72 1e 95 e9 f5 "
// ix=7; :scheme: https
"87"
// ix=58->63; User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:59.0) Gecko/20100101 Firefox/59.0
"7a b4 d0 7f 66 a2 81 b0 da e0 53 fa fc 08 7e d4 "
"ce 6a ad f2 a7 97 9c 89 c6 be d4 b3 bd c6 df 5c "
"1f da 98 8a 4e a7 60 40 08 00 10 05 4c 26 b0 b2 "
"9f cb 0d be b8 3f"
// ix=19->64; Accept: */*
"53 83 f9 63 e7 "
// ix=17->65; Accept-Language: en-US,en;q=0.5
"51 8b 2d 4b 70 dd f4 5a be fb 40 05 db "
// ix=16->66; Accept-Encoding: gzip, deflate, br
"50 8d 9b d9 ab fa 52 42 cb 40 d2 5f a5 23 b3 "
// ix=51->67; Referer: https://kfc.com.my/
"73 8e 9d 29 ad 17 18 63 ac a4 5c 87 a5 7a 7d 31 "
// ix=32->68; Cookie: _ga=GA1.3.1983042994.1521655507
"60 97 8a 61 c1 8a 10 ae ca e1 7d e6 40 d0 9f 7d "
"a5 c2 d8 82 e3 6d b6 07 7f "
// The issue is here:
// ix=62->69 :authority:_gid=GA1.3.1027405523.1521655507
"7e 97 8a 63 49 06 28 42 bb 2b 84 02 75 a0 36 d8 "
"99 5c 2d 88 2e 36 db 60 77"

最后一个解码的标头应该是 Cookie:_gid=...并且必须编码为 32->69 或 68->69(查找现有 Cookie 并将其存储在 69 索引下) 然而,Firefox 编码了索引 62,即 :authority,从而生成了一个重复的 :authority 标头,其值为第二个 Cookie。

还是我错过了什么?

Chrome没有这个问题。

来自 HPACK 规范:

动态表由在 中维护的标头字段列表组成 先进先出的顺序。动态中的第一个也是最新的条目 表位于动态表的最低索引和最早的条目 处于最高索引。

这意味着权限按照您的建议添加为索引 62,但在添加用户代理(接管索引位置 62)时,权限将增加到 63。然后它递增到 64...等等。

因此,在添加第二个 cookie 时,第一个 cookie 位于索引 62 处。此时,您有两个对 cookie 标头的引用 - 原始引用来自位置 32 的静态表,新引用位于位置 62。两者都可以用来引用新的cookie,看起来Chrome使用前者,而Firefox使用后者。

顺便说一下,Wireshark 是你的朋友,因为它允许你查看解码的消息(包括索引值),如果你看了下一条消息,那么你会看到相反的顺序引用。

最新更新