nghttp2.org

HTTP/2 C library and tools

Test Your HTTP/2 Server With Nghttp Client

nghttp command-line client has some useful options to test your HTTP/2 server implementation. This blog post introduces such command-line options.

We recommend to enable -nv options for nghttp to see what is happening on HTTP/2 framing layer. It is very good source of information for debugging.

Flow control

To test whether server enfoces flow control window size advertised by client, use -W and/or -w option. -W option specifies connection level flow control window size. It specifies the number of bits rather than the size directly, so if you specify -W14, the window size becomes 16383 (= 2 ** 14 - 1). Similarly, -w option specifies stream level flow control window size. Since HTTP/2 does not have dedicated way to reduce connection level window size, we achieve this by not sending WINDOW_UPDATE frame to server to keep the available window size less than or equal to the specified size. Therefore, to test connection window size less than default value which is 65535, nghttp should request resource more than 65535 bytes, otherwise -W has no effect. If nghttp found any errors related to flow control, it emits FLOW_CONTROL_ERROR and exists nonzero.

Header compression and multiplexing

HTTP/2 uses header compression technique called HPACK. We know that, by iterop experience, single request/response is not enough to test HPACK. The problem is more likely happening after several request/response transactions. This is because HPACK uses stateful compression mechanism and it requires both server and client share same compression context. If they are out of sync, problem appears. So testing HPACK must be done with multiple requests and responses. This means that it also exercises multiplexing.

For this purpose, -a option is handy. If -a is used, nghttp parses downloaded HTML file and finds statically linked resources, such as CSS, Javascript and images. Then it requests them which are multiplexed in the same HTTP/2 session (same connection).

If nghttp client found an error while decoding header block, it emits COMPRESSION_ERROR and exists nonzero.

Uploading

To upload the content of a file, use -d option. By default, nghttp adds content-length header field when uploading data. Specifying --no-content-length option will omit content-length header field from request header.

Padding

-b option adds given number of bytes to HEADERS or DATA frame as padding. This will verify that whether server can correctly parse frames by taking into account the existence of padding bytes.

CONTINUATION frame

Using --continuation will send very large headers to server using CONTINUATION frame. The total header block size (HEADERS + CONTINUATION) is around 18K bytes.

Priority

Use -a option and see that how server reacts to priority hints given from client. If -a is used, nghttp parses downloaded HTML file and finds statically linked resources, such as CSS, Javascript and images. Then it requests them which are multiplexed in the same HTTP/2 session (same connection). By default, nghttp prioritizes resources as follows:

  1. HTML (highest)
  2. CSS (high)
  3. Javascripts (JS) (middle)
  4. images (low)

Then it creates dependency tree and issues requests with this dependency hints. To verify how server reacts to this hints, -r option is very useful. It saves the HTTP transactions to given file as HAR format. Then you can use HAR file viewer to see the load times. To compare the result without prority, issue the same request with --no-dep option, which entirely omits priority hints.