1

我正在尝试使用 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

我该如何解决这个问题?

4

2 回答 2

1

HTTP/2 是二进制协议,不能telnet像 HTTP/1.1 那样使用。

您需要仔细阅读HTTP/2 规范,该规范描述了 HTTP/2 协议是二进制的,并且需要使用HPACK压缩 HTTP 标头。这两件事结合起来使得使用telnet和手动输入套接字非常困难;与 HTTP/2 服务器交互的常用方法是使用 HTTP/2 客户端工具。

此类客户端工具包括nghttp其自身以及curl.

于 2018-06-06T13:36:20.460 回答
1

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

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

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

这符合 RFC 7540 第 6.5.3 节:

如果 SETTINGS 帧的发送者在合理的时间内没有收到确认,它可能会发出 SETTINGS_TIMEOUT 类型的连接错误(第 5.4.1 节)。

这是我通过 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 服务器的日志。服务器在发送GOAWAY帧后 10 秒发送SETTINGS帧并关闭 TCP 连接。

于 2018-06-07T08:06:39.930 回答