Hi Arnall,
On Mon, May 26, 2014 at 11:56:52AM +0200, Arnall wrote:
> Hi Willy,
>
> same problem here with Chrome version 35.0.1916.114 m and :
> HA-Proxy version 1.4.22 2012/08/09 (Debian 6) Kernel 3.8.13-OVH
> HA-Proxy version 1.5-dev24-8860dcd 2014/04/26 (Debian GNU/Linux 7.5)
> Kernel 3.10.13-OVH
>
> <html><body><h1>408 Request Time-out</h1>
> Your browser didn't send a complete request in time.
> </body></html>
>
> Timing : Blocking 2ms / Receiving : 1ms
Where are you measuring this ? I suspect on the browser, right ? In
this case it confirms the malfunction of the preconnect. You should
take a network capture which will be usable as a reliable basis for
debugging. I'm pretty sure that what you'll see in fact is the following
sequence :
browser haproxy
------- connect ---------->
... long pause ...
<-------- 408 + FIN -------
... long pause ...
------- send request ----->
<-------- RST -------------
And you see the error in the browser immediately. The issue is then
caused by the browser not respecting this specific rule :
http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26#section-6.5
"A client or server that wishes to time-out SHOULD issue a graceful
close on the connection. Implementations SHOULD constantly monitor
open connections for a received closure signal and respond to it as
appropriate, since prompt closure of both sides of a connection
enables allocated system resources to be reclaimed."
...
"A client sending a message body SHOULD monitor the network connection
for an error response while it is transmitting the request. If the
client sees a response that indicates the server does not wish to
receive the message body and is closing the connection, the client
SHOULD immediately cease transmitting the body and close its side of
the connection."
Anyway, from the various reports we get, it seems like sending an empty
408 message is enough to workaround this abnormal Chrome behaviour. For
this you can proceed like this :
errorfile 408 /dev/null
Note however that it breaks HTTP in that it prevents client from knowing
whether the request was processed or not. The 408 message provides *exactly*
this information :
http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-26#section-6.5.7
The 408 (Request Timeout) status code indicates that the server did
not receive a complete request message within the time that it was
prepared to wait. A server SHOULD send the close connection option
(Section 6.1 of [Part1]) in the response, since 408 implies that the
server has decided to close the connection rather than continue
waiting. If the client has an outstanding request in transit, the
client MAY repeat that request on a new connection.
With only a silent close (as Chrome seems to expect it), the client cannot
reasonably retry without violating a strict HTTP rule :
http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-26#section-6.3.1
A user agent MUST NOT automatically retry a request with a non-
idempotent method unless it has some means to know that the request
semantics are actually idempotent, regardless of the method, or some
means to detect that the original request was never applied.
Regards,
Willy