nghttpd соединение закрывается автоматически

Я пытаюсь использовать сервер nghttpd для проверки HTTP/2.0. Для начала я использую:

sudo nghttpd --push=/test=/test1.png,/test2.pcapng,/test2.txt,/test3.png  --no-tls --workers=3  --early-response  -v  80.

В моем CWD у меня есть push-файлы. В другом терминале я набираю:

telnet localhost 80

И все, кажется, хорошо, так как у меня есть этот вывод в первом терминале

[id=1] [ 11.893] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
      (niv=1)
      [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=1] [ 21.898] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
      (last_stream_id=0, error_code=SETTINGS_TIMEOUT(0x04), opaque_data(0)=[])

Проблемы возникают, когда я пытаюсь (любой тип) HTTP GET со вторым терминалом:

telnet localhost 80
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET /test HTTP/2.0
Connection closed by foreign host.

В моем первом терминале я получаю этот вывод

[id=1] [314.531] closed

Как я могу решить это?

2 ответа

Решение

Немного доработки: сервер HTTP/2 отправляет контрольные кадры наподобие MAGICа также SETTINGS (это включает в себя такую ​​информацию, как Max Concurrent Streams и Initial Window Size), и сервер не учитывает клиента, пока они не будут подтверждены клиентом (в SETTINGS рамка тоже).

Telnet просто устанавливает TCP-соединение, а затем ждет, когда пользователь выдаст следующие пакеты.

Не видя эти контрольные кадры в течение нескольких секунд, сервер закрывает соединение в течение нескольких секунд.

Это соответствует RFC 7540, раздел 6.5.3:

Если отправитель кадра SETTINGS не получает подтверждение в течение разумного периода времени, он МОЖЕТ выдать ошибку соединения (Раздел 5.4.1) типа SETTINGS_TIMEOUT.

Это журнал nghttpd (работает в подробном режиме), когда я подключился через Telnet:

[id=2] [ 34.645] send SETTINGS frame <length=6, flags=0x00, stream_id=0>
          (niv=1)
          [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[id=2] [ 44.654] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
          (last_stream_id=0, error_code=SETTINGS_TIMEOUT(0x04), opaque_data(0)=[])
[id=2] [ 44.654] closed

На самом деле, в вашем вопросе кроется ответ, только то, что вы распечатали журнал сервера nghttpd по частям. Сервер отправил GOAWAY кадр 10 секунд после отправки SETTINGS кадр и закрыл соединение TCP.

HTTP/2 - это двоичный протокол, и вы не можете использовать telnet как вы могли бы с HTTP/1.1.

Вы хотите внимательно прочитать спецификацию HTTP/2, которая описывает, что протокол HTTP/2 является двоичным и требует сжатия заголовков HTTP с помощью HPACK. Эти две вещи в сочетании делают очень трудным в использовании telnet и ручной ввод в розетку; Обычный способ взаимодействия с сервером HTTP/2 - использование инструментов клиента HTTP/2.

Такие клиентские инструменты включают nghttp сам и, среди прочего, curl,

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