Метод PRI в реализации http2 вызывает проблему - PullRequest
0 голосов
/ 20 мая 2018

Я пытаюсь расширить сервер с HTTP / 2 , который уже поддерживает HTTP / 1.1 с TLS v1.2 .Я пишу это в Go , где я определяю конфигурацию tls следующим образом -

tlsConfig := &tls.Config{
                    Certificates: []tls.Certificate{cert},
                    ServerName:   "mysrvr",
                    NextProtos:   []string{"h2", "http/1.1", "http/1.0"},
                    Time:         time.Now,
                    Rand:         rand.Reader,
            }

Как очевидно, я использовал строку " h2 " для настройки ALPNhandshake.

Теперь, когда я делаю запрос через curl, я получаю этот запрос -

$ curl -v https://127.0.0.1:8000 -k --http2

Когда я анализирую запрос, он показывает, что вместо него сначала отправляется метод PRI GET -

HTTP/2.0
PRI

Я получил некоторое представление о методе PRI из https://tools.ietf.org/html/rfc7540#page-78, в котором говорится следующее -

This method is never used by an actual client.
This method will appear to be used when an HTTP/1.1 server or
intermediary attempts to parse an HTTP/2 connection preface. 

У меня сейчас вопрос: почему был отправлен запрос PRI , когда сервер явно поддерживает HTTP / 2 ?Нужно ли анализировать его и отвечать пустым кадром SETTINGS в соответствии со спецификацией HTTP / 2, или должна была позаботиться об этом среда исполнения Go http2?

Я использую http.ReadRequestанализировать клиентские запросы, но это не работает для HTTP / 2 запросов, даже когда я игнорирую PRI запросов (как предложено ниже).

1 Ответ

0 голосов
/ 20 мая 2018

Первое сообщение, которое должен отправить клиент HTTP / 2, это сообщение PRI.Из спецификации HTTP / 2 :

В HTTP / 2 каждая конечная точка должна отправлять предисловие соединения в качестве окончательного подтверждения используемого протокола и устанавливать начальныйнастройки для соединения HTTP / 2.Каждый клиент и сервер отправляют разные предисловия к соединению.

Предисловие к клиентскому соединению начинается с последовательности из 24 октетов, которая в шестнадцатеричной форме имеет вид:

0x505249202a20485454502f322e300d0a0d0a534d0d0a0d0a

То есть предисловие к соединениюначинается со строки PRI * HTTP / 2.0 \ r \ n \ r \ nSM \ r \ n \ r \ n).За этой последовательностью ДОЛЖЕН следовать кадр SETTINGS (раздел 6.5), который МОЖЕТ быть пустым.

...

Примечание : Предисловие клиентского соединения выбрано так, чтобыбольшая часть серверов и посредников HTTP / 1.1 или HTTP / 1.0 не пытаются обрабатывать дальнейшие кадры.

Суть этого сообщения в том, что это поддельное сообщение типа HTTP / 1, поэтому любойсервер, который не знает HTTP / 2, должен ответить с ошибкой.

Любой сервер HTTP / 2 должен ожидать, что это сообщение будет отправлено, а затем должен просто игнорировать его и продолжать говорить HTTP / 2.

На самом деле, если это сообщение НЕ отправлено, то сервер должен воспринимать это как ошибку, а не продолжать:

Клиенты и серверы ДОЛЖНЫ рассматривать неверное предисловие соединения как ошибку соединения (Раздел 5.4.1) типа PROTOCOL_ERROR.Кадр GOAWAY (раздел 6.8) МОЖЕТ быть опущен в этом случае, поскольку неверное предисловие указывает, что узел не использует HTTP / 2.

...