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 服务器发送控制帧,如 MAGIC
和 SETTINGS
(这包括最大并发流和初始 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 连接。
我正在尝试使用 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 服务器发送控制帧,如 MAGIC
和 SETTINGS
(这包括最大并发流和初始 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 连接。