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
,