nghttpd connection closed automatically

316 Views Asked by At

I'm tryng to use nghttpd server to test HTTP/2.0. To start it i'm using:

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

In my CWD i've got the push files. In another terminal, i type:

telnet localhost 80

And everything seems ok, since i have this output in the first terminal

[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)=[])

The problems occur when i try an (any type of) HTTP GET with the second terminal:

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

In my first terminal i get this output

[id=1] [314.531] closed

How can i solve this?

2

There are 2 best solutions below

2
On BEST ANSWER

Little more elaboration: the HTTP/2 server sends control frames like MAGICand SETTINGS (this includes information like Max Concurrent Streams and Initial Window Size) and the server does not honor the client until these are acknowledged by the client (in a SETTINGS frame as well).

Telnet just establishes the TCP connection and then waits for the user to issue next packets.

Without seeing these control frames in couple of seconds, the server closes the connection in couple of seconds.

This is in accordance to RFC 7540, section 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.

This is the log of nghttpd (running in verbose mode) when I connected via 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

In fact, in your question lies the answer, only that you printed the log of nghttpd server in parts. The server sent GOAWAY frame 10 seconds after sending the SETTINGS frame and closed the TCP connection.

2
On

HTTP/2 is a binary protocol, and you cannot use telnet like you could with HTTP/1.1.

You want to read carefully the HTTP/2 specification that describes that the HTTP/2 protocol is binary and requires to compress HTTP headers using HPACK. These two things combined make very difficult to use telnet and manual input to the socket; the usual way to interact with HTTP/2 server is to use HTTP/2 client tools.

Such client tools include nghttp itself and, among others, curl.