【问题标题】:How does headers keep sync in both client and server side in HTTP/2?HTTP/2 中的标头如何在客户端和服务器端保持同步?
【发布时间】:2020-10-18 00:08:44
【问题描述】:

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

【问题讨论】:

    标签: http2


    【解决方案1】:

    有两张表:一张用于客户端发起的消息,另一张用于服务器发起的消息。

    根据spec

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

    客户端和服务器都必须管理这两个表的副本。因此,当客户端发送消息时,它会更新客户端表的副本,当客户端接收到消息时,客户端会更新它的服务器表副本。在服务器端也是如此。

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

    【讨论】:

      【解决方案2】:

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

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

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

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

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

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

      很明显,帧的按序交付至关重要。这是通过底层 TCP 协议保护的。此外,标头应始终在两侧以串行方式处理。

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

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

      【讨论】:

        猜你喜欢
        • 2015-03-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-01
        • 1970-01-01
        • 2017-12-15
        • 2014-05-25
        相关资源
        最近更新 更多