On Thu, Apr 08, 2010 at 11:58:25AM +0200, Willy Tarreau wrote:
3) I have sample configuration running with option http-server-close and
without option httpclose set.
I observe the following at haproxy side:
Request comes:
GET /some-url HTTP/1.1
Host: host.pp.ru
User-Agent: Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.2.2)
Gecko/20100326 Firefox/3.6.2
Accept: */*
Accept-Language: en-us,ru;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
So client requests keep-alive. I suppose that haproxy should send request
to
backend with Connection: close (because http-server-close is set) but
send response to client with keep-alive enabled.
Exactly.
But that does not happen:
HTTP/1.1 200 OK
Date: Thu, 08 Apr 2010 08:41:52 GMT
Expires: Thu, 08 Apr 2010 08:42:52 GMT
Content-Type: text/javascript; charset=utf-8
Connection: Close
jsonp1270715696732([a, [ab, and, a2, ac, are, a a, ad, a
b, a1, about]])
Why haproxy responds to client with Connection: Close?
Because the server did not provide information required to make the keep-alive
possible. In your case, there is no content-length nor any
transfer-encoding
header, so the only way the client has to find the response end, is the
closure
of the connection.
An exactly similar issue was identified on Tomcat and Jetty. They did not use
transfer-encoding when the client announces it intends to close. The Tomcat
team was cooperative and recently agreed to improve that. In the mean time,
we have released haproxy 1.4.4 which includes a workaround for this : combine
option http-pretend-keepalive with option http-server-close and your
server
will believe you're doing keep-alive and may try to send a more appropriate
response. At least this works with Jetty and Tomcat, though there is nothing
mandatory in this area.
Hello!
Here is a sample HTTP session with my (hand-made) server.
1) GET /some-url HTTP/1.1
Host: hots.pp.ru
User-Agent: Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.2.3) Gecko/2010041
4 Firefox/3.6.3
Accept: text/javascript, application/javascript, */*
Accept-Language: en-us,ru;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
2)
HTTP/1.1 200 OK
Date: Mon, 26 Apr 2010 11:34:19 GMT
Expires: Mon, 26 Apr 2010 11:35:19 GMT
Content-Type: text/javascript; charset=utf-8
Connection: Keep-Alive
Transfer-Encoding: chunked
some data
tcpdump analysis of several subsequent requests shows that HTTP keep-alive works
in my case.
When I put that server behind haproxy (version 1.4.4) I see the following:
1) GET some URL HTTP/1.1
Host: host.pp.ru
User-Agent: Mozilla/5.0 (X11; U; FreeBSD amd64; en-US; rv:1.9.2.3) Gecko/2010041
4 Firefox/3.6.3
Accept: text/javascript, application/javascript, */*
Accept-Language: en-us,ru;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
2)
HTTP/1.1 200 OK
Date: Mon, 26 Apr 2010 11:45:01 GMT
Expires: Mon, 26 Apr 2010 11:46:01 GMT
Content-Type: text/javascript; charset=utf-8
Connection: Close
some data
I have
mode http
option http-server-close
option http-pretend-keepalive
in my config (tried both with and without http-pretend-keepalive).
Can you please explain in more detail what server makes wrong and why haproxy
adds Connection: Close header
(and why Firefox successfully uses HTTP keep-alive with the same server without
haproxy).
Thanks in advance!