This demonstrates how browsers (Chrome in particular) handle an HTTP2 GOAWAY frame.
It has been observed that a server sending a GOAWAY while Chrome is loading the page resources will result in the following:
- Chrome does not appear to retry the requests that are known to not have been received / handled by the server
- Chrome appears to discard fully received responses for streams that sent an ACK that ends up receiving an RST after the socket is closed - This does not appear to be correct as the response was correctly received and should not be discarded
There are two ways to test using this repo:
- Local Build
- With the local build you can see Chrome sending many more than 10 requests that the server is notifying as the max concurrent streams in the SETTINGS frame (this may or may not be ok)
- Chrome does not retry the refused streams, which it appears that it should, as it can confirm from the GOAWAY frame that the server has not received the request
- Deployed Build with AWS NLB
- An AWS NLB will send a RST to the client if a packet is received after the socket is closed
- This RST appears to trigger the discarding of completely received responses that get a RST in response to one of the ACKs for the packets that made up that response
Use Wireshark with a pre-master secret to decrypt and decode the HTTP2 traffic.
Instructions for pre-master secret with Wireshark
On Mac, Chrome is typically started with open -a "Google Chrome"
after exporting the env var export SSLKEYLOGFILE=/path/to/sslkeylogfile.txt
docker-compose build
docker-compose up
Type thisisunsafe
in the Chrome window to allow usage of the self-signed certificate for localhost
keepalive_requests 10;
http2_max_concurrent_streams 10;
Initial requests are ERR_FAILED
:
Later requests are ERR_HTTP2_SERVER_REFUSED_STREAM
:
keepalive_requests 10;
http2_max_concurrent_streams 10000;
Responses / errors are exactly the same as the 10 / 10 case above
keepalive_requests 10000;
http2_max_concurrent_streams 10000;
No errors at all:
keepalive_requests 10000;
http2_max_concurrent_streams 10;
http2-10k-keepalive-10-concurrent.mp4
Responses / no errors - same as the 10,000 / 10,000 case above
keepalive_requests 190;
http2_max_concurrent_streams 10;
A single file usually fails to load with ERR_FAILED
in this case:
- keepalive_requests docs
- default: 1,000
- http2_max_concurrent_requests docs
- default: 128
It took 43 page loads before 1 request failed with ERR_FAILED
.