http2:PUSH_PROMISE保留的流ID验证

时间:2018-01-12 06:02:03

标签: http2 request-promise

The spec说:

  

新建立的流的标识符必须是数字的   大于启动端点已打开的所有流或   保留。这将控制使用HEADERS框架打开的流   和使用PUSH_PROMISE保留的流。一个端点   收到意外的流标识符必须用a响应   PROTOCOL_ERROR类型的连接错误(第5.4.1节)。

对于发送PUSH_PROMISE的服务器的情况,我认为符合要求的服务器必须发送严格增加的流ID。但我不明白客户端应该如何检测这种情况。

例如,在一个连接上,如果服务器发送:

  1. PUSH_PROMISE承诺的第2流
  2. PUSH_PROMISE承诺的第4流
  3. 因为并发,客户端可能会收到

    1. PUSH_PROMISE承诺的第4流
    2. PUSH_PROMISE承诺的第2流
    3. 规范会让我觉得客户端应该对此产生错误,但服务器没有做错任何事。

      我在这里缺少什么?

1 个答案:

答案 0 :(得分:3)

如果服务器写了PUSH_PROMISE[stream=2]然后PUSH_PROMISE[stream=4],那么这些帧将以相同的顺序传送(这由TCP保证)。

客户端的任务是以有序的方式从套接字读取。 对于HTTP / 2实现,要求甚至更严格,因为它不仅必须以有序的方式从套接字读取,而且还必须以有序的方式解析帧。

这是PUSH_PROMISE帧携带HPACK块并且为了使服务器和客户端HPACK上下文保持同步这一事实所必需的,必须处理帧(或至少这些帧的HPACK块)按顺序排列,stream=2 之前 stream=4

之后,客户端可以同时处理2帧。

对于实现,这实际上非常简单,因为分配用于执行I / O读取的线程通常会:

loop
  read bytes from socket
  if no bytes or socket closed -> break loop
  parse read bytes (with HPACK decoding) -> produce frame objects
  pass frame objects to upper software layer
end loop

由于read和parse是顺序的,并且没有其他线程从同一个套接字读取,因此符合订购保证。