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:
- HTML (highest)
- CSS (high)
- Javascripts (JS) (middle)
- 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.