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

Я заметил, что некоторые клиенты HTTP2 (Firefox и https://nghttp2.org/documentation/package_README.html) отправляют 5 кадров PRIORITY для потока 3, 5, 7, 9, 11 после согласования протокола http2 и до отправки кадра HEADERS. Мне любопытно, почему? Я знаю значение фреймов ПРИОРИТЕТА, но не понимаю смысла их отправлять, но это делают и Firefox, и nghttp, поэтому должны быть какие-то причины.

И, что наиболее важно, эти потоки (поток 3, 5, 7, 9, 11) не используются после кадров PRIORITY согласно журналу.

Выходная информация с сервера для 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
....

person user3744927    schedule 29.04.2016    source источник


Ответы (1)


Они не необходимы для успешного подключения.

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

person dsign    schedule 29.04.2016
comment
Вы совершенно правы! Это 5 потоков с фиксированной группировкой, созданных с помощью кадра PRIORITY при установлении сеанса, и каждый новый поток зависит от одного из них. Я только что нашел об этом хороший блог bitsup.blogspot. fi / 2015/01 / и выяснил, что nghttp (https://nghttp2.org/documentation/nghttp.1.html) имитирует способ, который Firefox использует для управления зависимостями с помощью незанятых потоков. - person user3744927; 29.04.2016