Commands / Ports and connections

Ports and connections

nghttp

Also http2 client, h2 frames

An HTTP/2 client that prints every frame it sends and receives.

Where curl -v shows HTTP/2 as if it were text, nghttp -v shows the frames: SETTINGS, HEADERS (a request opening a stream), DATA, WINDOW_UPDATE, each with its length, flags and stream ID. Several URLs in one run go out as several streams on one connection.

nghttp command usage

nghttp [-n] [-v] [-a] URL...

Options

-v
print every frame sent and received
-n
discard the response bodies
-a
also fetch what the page links to (style sheets, scripts, images)

nghttp examples

nghttp -nv https://webServer.lab/
Fetches the page over HTTP/2 and prints each frame.
nghttp -nv https://webServer.lab/ https://webServer.lab/assets/1.css
Two requests as two streams on one connection.
nghttp -nva https://webServer.lab/
Fetches the page and everything it links to, all on one connection.

Reading the output

$ nghttp -nv https://webServer.lab/
[  0.009] Connected
The negotiated protocol: h2
[  0.011] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
[  0.011] send HEADERS frame <length=38, flags=0x25, stream_id=13>
          :method: GET
          :path: /
          :authority: webServer.lab
[  0.011] recv SETTINGS frame <length=30, flags=0x00, stream_id=0>
[  0.012] recv (stream_id=13) :status: 200
[  0.012] recv HEADERS frame <length=88, flags=0x04, stream_id=13>
[  0.012] recv DATA frame <length=312, flags=0x01, stream_id=13>
  • The negotiated protocol: h2: ALPN settled on HTTP/2.
  • stream_id=0: frames about the whole connection (SETTINGS, PING, WINDOW_UPDATE).
  • Odd stream IDs are requests the client opened; the response comes back on the same ID.

Pitfalls

  • It speaks HTTP/2 only: a server that accepts just http/1.1 in ALPN gets nothing from it.

Run it on real machines

Learn it on real machines.

Every lab is a small network of real Linux machines in your browser. Start with a free account: Google or email, no card.

Open this lab