Почему 5 кадров PRIORITY отправляются с клиента HTTP2 до того, как он отправляет кадр HEADERS? Они необходимы для успешного соединения HTTP2?

Я заметил, что некоторые клиенты HTTP2 (Firefox и nghttp) отправляют 5 кадров PRIORITY для потока 3, 5, 7, 9, 11 после согласования протокола http2 и перед отправкой кадра HEADERS. Мне любопытно почему? Я знаю значение фреймов PRIORITY, но не вижу смысла отправлять их, но это делают и Firefox, и nghttp, поэтому должны быть некоторые причины.

И самое главное, эти потоки (поток 3, 5, 7, 9, 11) не используются после кадров ПРИОРИТЕТА согласно журналу.

Выходная информация с сервера для Firefox отображается следующим образом.

$ nghttpd -d ~/Proxy 8080 key.pem cert.pem -v
Enter PEM pass phrase:
IPv4: listen 0.0.0.0:8080
IPv6: listen :::8080
[ALPN] client offers:
* h2
* spdy/3.1
* http/1.1
SSL/TLS handshake completed
The negotiated protocol: h2
[id=1] [ 18.917] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
      (niv=1)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=1] [ 18.920] recv SETTINGS frame <length=12, flags=0x00, stream_id=0>
      (niv=2)
      [SETTINGS_INITIAL_WINDOW_SIZE(0x04):131072]
      [SETTINGS_MAX_FRAME_SIZE(0x05):16384]
[id=1] [ 18.920] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
      (window_size_increment=12517377)
[id=1] [ 18.920] recv PRIORITY frame <length=5, flags=0x00, stream_id=3>
      (dep_stream_id=0, weight=201, exclusive=0)
[id=1] [ 18.920] recv PRIORITY frame <length=5, flags=0x00, stream_id=5>
      (dep_stream_id=0, weight=101, exclusive=0)
[id=1] [ 18.920] recv PRIORITY frame <length=5, flags=0x00, stream_id=7>
      (dep_stream_id=0, weight=1, exclusive=0)
[id=1] [ 18.920] recv PRIORITY frame <length=5, flags=0x00, stream_id=9>
      (dep_stream_id=7, weight=1, exclusive=0)
[id=1] [ 18.920] recv PRIORITY frame <length=5, flags=0x00, stream_id=11>
      (dep_stream_id=3, weight=1, exclusive=0)
[id=1] [ 18.920] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
      ; ACK
      (niv=0)
[id=1] [ 18.926] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
      ; ACK
      (niv=0)
[id=1] [ 25.773] recv (stream_id=13) :method: GET
[id=1] [ 25.773] recv (stream_id=13) :path: /plaintext.txt
[id=1] [ 25.773] recv (stream_id=13) :authority: 127.0.0.1:8080
[id=1] [ 25.773] recv (stream_id=13) :scheme: https
[id=1] [ 25.773] recv (stream_id=13) user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:45.0) Gecko/20100101 Firefox/45.0
[id=1] [ 25.773] recv (stream_id=13) accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
[id=1] [ 25.773] recv (stream_id=13) accept-language: en-US,en;q=0.5
[id=1] [ 25.773] recv (stream_id=13) accept-encoding: gzip, deflate, br
[id=1] [ 25.773] recv (stream_id=13) if-modified-since: Wed, 27 Apr 2016 13:10:07 GMT
[id=1] [ 25.773] recv HEADERS frame <length=196, flags=0x25, stream_id=13>
      ; END_STREAM | END_HEADERS | PRIORITY
      (padlen=0, dep_stream_id=11, weight=32, exclusive=0)
      ; Open new stream
[id=1] [ 25.774] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=13>
      (window_size_increment=12451840)
[id=1] [ 25.774] send HEADERS frame <length=42, flags=0x05, stream_id=13>
      ; END_STREAM | END_HEADERS
      (padlen=0)
      ; First response header
      :status: 304
      server: nghttpd nghttp2/1.8.0
      date: Fri, 29 Apr 2016 08:07:25 GMT
[id=1] [ 25.774] stream_id=13 closed

Но Chrome не отправляет их, как показано ниже. Так они не нужны для успешного подключения?

$ nghttpd -d ~/Proxy 8080 key.pem cert.pem -v
Enter PEM pass phrase:
IPv4: listen 0.0.0.0:8080
IPv6: listen :::8080
[ALPN] client offers:
 * h2
 * spdy/3.1
 * http/1.1
SSL/TLS handshake completed
The negotiated protocol: h2
[id=1] [ 16.069] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
      (niv=1)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=1] [ 16.083] closed
[ALPN] client offers:
 * h2
 * spdy/3.1
 * http/1.1
 SSL/TLS handshake completed
 The negotiated protocol: h2
 [id=2] [ 16.298] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
      (niv=1)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
 [id=2] [ 16.299] closed
[ALPN] client offers:
 * h2
 * spdy/3.1
 * http/1.1
SSL/TLS handshake completed
The negotiated protocol: h2
[id=3] [ 16.303] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
      (niv=1)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=3] [ 16.303] recv SETTINGS frame <length=12, flags=0x00, stream_id=0>
      (niv=2)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):1000]
      [SETTINGS_INITIAL_WINDOW_SIZE(0x04):6291456]
[id=3] [ 16.303] recv WINDOW_UPDATE frame <length=4, flags=0x00, stream_id=0>
      (window_size_increment=15663105)
[id=3] [ 16.303] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
      ; ACK
      (niv=0)
[id=3] [ 16.303] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
      ; ACK
      (niv=0)
[id=3] [ 16.311] recv (stream_id=1) :method: GET
[id=3] [ 16.311] recv (stream_id=1) :authority: 127.0.0.1:8080
[id=3] [ 16.311] recv (stream_id=1) :scheme: https
[id=3] [ 16.311] recv (stream_id=1) :path: /plaintext.txt
[id=3] [ 16.311] recv (stream_id=1) accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
[id=3] [ 16.311] recv (stream_id=1) upgrade-insecure-requests: 1
[id=3] [ 16.311] recv (stream_id=1) user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.86 Safari/537.36
[id=3] [ 16.311] recv (stream_id=1) accept-encoding: gzip, deflate, sdch
[id=3] [ 16.311] recv (stream_id=1) accept-language: en-US,en;q=0.8
[id=3] [ 16.311] recv HEADERS frame <length=238, flags=0x25, stream_id=1
....

1 ответ

Решение

Они не требуются для успешного подключения.

В остальном я просто угадываю здесь. Firefox использует эти потоки как "виртуальные потоки". Затем он делает дальнейшие реальные потоки зависимыми от этих виртуальных потоков. Результатом должно стать создание различных групп приоритетов без необходимости указывать приоритеты для (реальных) потоков.

Другие вопросы по тегам