There exists a known race condition in the HTTP keepalive mechanism:
As I understand, I need my HTTP client either to have a shorter timeout than my HTTP server, or retry when getting TCP-FIN or TCP-RST.
My question is, how do today's web-browsers, that use the HTTP keepalive feature, handle this race condition. Do they retry?
I'll be happy for references, a google search hasn't come up with anything.
HTTP keep-alive, a.k.a., HTTP persistent connection, is an instruction that allows a single TCP connection to remain open for multiple HTTP requests/responses. By default, HTTP connections close after each request.
Keep-Alive The Keep-Alive general header allows the sender to hint about how the connection may be used to set a timeout and a maximum amount of requests. The Connection header needs to be set to "keep-alive" for this header to have any meaning. Connection-specific header fields such as Connection and Keep-Alive are prohibited in HTTP/2.
Warning: Connection-specific header fields such as Connection and Keep-Alive are prohibited in HTTP/2. Chrome and Firefox ignore them in HTTP/2 responses, but Safari conforms to the HTTP/2 spec requirements and won't load any response which contains them.
In the event that keep-alive is not enabled on your server, it can be turned on by adding the following code to your .htaccess file: Within the ‘Connection keep-alive’ header, the following two directives can affect its functionality. MaxKeepAliveRequests – This directive sets the maximum number of requests for every keep-alive connection.
According the the RFC, in these cases, a server should respond with a 408 error code, signalling to the client that the connection has already been closed on its side. As the RFC states:
If the client has an outstanding request in transit, the client MAY repeat that request on a new connection.
This means that it's up to the client (aka each browser) to decide how a 408 response will be handled. There are 2 alternatives:
For example, it seems that Chrome in the past was following the second approach until a point, where people started considering this as a "buggy" behaviour and switched to the first one. You can find the bug thread related to the Chromium bug here and the associated code change here.
Note: As you can read in the final emails in the linked thread, Chrome performs these retries, only when some requests have succeeded in this connection. As a result, if you try to reproduce that with a single request, returning a 408 response, you'll notice that Chrome won't probably retry in that case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With