nghttpd 连接自动关闭

nghttpd connection closed automatically

我正在尝试使用 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 中,我有推送文件。在另一个终端,我输入:

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

我该如何解决这个问题?

HTTP/2 是二进制协议,您不能像使用 HTTP/1.1.

那样使用 telnet

您想仔细阅读HTTP/2 specification that describes that the HTTP/2 protocol is binary and requires to compress HTTP headers using HPACK。 这两件事结合在一起使得使用 telnet 和手动输入到套接字变得非常困难;与 HTTP/2 服务器交互的常用方法是使用 HTTP/2 客户端工具。

此类客户端工具包括 nghttp 本身以及 curl

更详细一点:HTTP/2 服务器发送控制帧,如 MAGICSETTINGS(这包括最大并发流和初始 Window 大小等信息)和在客户端确认这些之前,服务器不尊重客户端(也在 SETTINGS 帧中)。

Telnet只是建立TCP连接,然后等待用户发出下一个数据包。

在几秒钟内没有看到这些控制帧,服务器将在几秒钟内关闭连接。

这符合 RFC 7540 第 6.5.3 节:

If the sender of a SETTINGS frame does not receive an acknowledgement within a reasonable amount of time, it MAY issue a connection error (Section 5.4.1) of type SETTINGS_TIMEOUT.

这是当我通过 Telnet 连接时 nghttpd 的日志(运行 详细模式):

[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 server的log部分打印出来了。服务器在发送 SETTINGS 帧后 10 秒发送 GOAWAY 帧并关闭 TCP 连接。