标头如何在HTTP / 2中的客户端和服务器端保持同步?

时间:2018-10-26 07:10:52

标签: http2

由于HTTP/2使用hpack压缩标题,因此每个连接都有一个静态表和一个动态表。但是我有一个问题,客户端和服务器端如何同步标头?

2 个答案:

答案 0 :(得分:0)

有两个表:一个用于客户端启动的消息,另一个用于服务器启动的消息。

按照spec

  

当用于双向通信(例如HTTP)时,   端点维护的编码和解码动态表是   完全独立的,即请求和响应动态表   是分开的。

客户端和服务器都必须管理两个表的副本。因此,当客户端发送消息时,它将更新客户端表的副本;当客户端接收到消息时,客户端将更新服务器表的副本。同样在服务器端。

由于TCP保证了邮件的传递顺序,因此可以使客户端表在客户端和服务器端(以及与服务器表端类似)保持同步。在无法保证按顺序发送消息的连接上,这将变得更加复杂,因此QUIC在HPACK上使用了一种名为QPACK的变体,它具有处理此问题的额外功能。

答案 1 :(得分:0)

要启动HTTP2连接,应已建立TCP连接。然后,客户端准备并发送包含以魔术字符串为前缀的SETTINGS帧的第一个HTTP2数据包,并为此特定的TCP连接创建两个单独的动态表,一个用于客户端发出的消息,另一个用于服务器发出的消息。当服务器端收到以魔术字符串为前缀的HTTP2数据包时,它会类似地创建其两个单独的动态表。

当客户端准备第一个HTTP2请求时,它首先构造HEADERS框架并在其中附加所有需要的标头。第一个HEADERS帧的每个标头要么是静态表的1个字节长的索引(例如0x02->方法:GET),要么是由几个字节组成的标头的文字表示形式。在后一种情况下,字节序列的第一个字节用于向服务器提供有关如何处理和存储此新头的信息。同时,客户端已经将标头存储在其动态表中。

当服务器端接收到第一个HTTP2 HEADERS帧时,它将使用其静态表对报头块进行解码以对一个字节的报头进行解码。对于每个文字标头,它会根据从该标头字节序列的第一个字节中检索到的信息在动态表中创建一个新条目。

第二次从客户端准备包含标头(HEDERS,CONTINUATION或PUSH PROMISE)的帧时,已存储在动态表中的每个使用的标头都表示为1个字节*(动态表索引)。对于第一次使用且静态表中不存在的每个标头,将再次使用文字表示形式,并在客户端动态表中添加新条目。当服务器端接收到第二帧时,它会查看其静态或动态表以解码一字节的报头。对于每个文字标头(首次出现),它还会在其动态表中创建一个新条目。

这样,来自客户端的消息的动态表在两侧保持同步。以类似的方式使服务器起源消息的动态表保持同步。

相同的过程一直持续到TCP连接终止。逐渐地,动态表被填充,并且需要更少的文字表示。

很明显,帧的有序交付至关重要。这是从基础TCP协议保护的。另外,标头应始终在两侧都以串行方式处理。

HTTP2使用HPACK格式进行标头压缩。

* 为简单起见,在上面的示例中假定了“带有递增索引和新名称的文字标题字段”。