Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do browsers handle HTTP keepalive race condition?

There exists a known race condition in the HTTP keepalive mechanism:

  • HTTP KeepAlive connection closed by server but client had sent a request in the mean time
  • https://github.com/mikem23/keepalive-race

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.

like image 836
speller Avatar asked Mar 06 '17 16:03

speller


People also ask

What is HTTP keep-alive?

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.

What is keep alive in http 2 header?

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.

Are connection and keep-alive fields allowed in HTTP/2 responses?

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.

How do I enable keep-alive on my server?

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.


1 Answers

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:

  • handle it gracefully: retrying the remaining requests in a new connection automatically, so that the user stays completely unaware of the underlying failure that happened
  • fail-fast: showing the user a failure with the appropriate 408 error message

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.

like image 180
Dimos Avatar answered Oct 13 '22 11:10

Dimos