Dropped https client connection doesn't drop backend proxy_pass connection
mdounin at mdounin.ru
Fri Mar 15 08:10:44 UTC 2013
On Fri, Mar 15, 2013 at 03:22:31PM +1100, Robert Mueller wrote:
> When using http with my test client, I see this in the nginx log when
> the client disconnects:
> 2013/03/14 23:27:27 [info] 27717#0: *1 client prematurely closed
> connection, so upstream connection is closed too while reading upstream,
> client: 10.50.1.14, server: www.*, request: "GET /events/ HTTP/1.0",
> upstream: "http://127.0.0.4:80/.../", host: "..."
> And when I check netstat, I see that the connection from nginx ->
> pushbackend has been dropped as well.
> However for https connections, this is not what happens. Instead, it
> appears nginx fails to detect that the client has closed the connection,
> and leaves the nginx -> pushbackend connection open (confirmed with
> netstat). And because we set proxy_read_timeout to 2 hours, it takes 2
> hours for that connection to be closed! That's bad.
You shouldn't rely on connection close being detected by nginx.
It's generally useful optimization, but it's not something which
is guaranteed to work.
It is generally not possible to check if the connection was closed
if there a pending data in it. One have to read all pending data
before connection close can be detected, but it doesn't work as a
generic detection mechanism as one have to buffer read data
As of now, nginx uses:
1) A EV_EOF flag as reported by kqueue. This only works if you
use kqueue, i.e. on FreeBSD and friends.
2) The recv(MSG_PEEK) call to test a case when connection was
closed. This works on all platforms, but only if there are no
In case of https, in many (most) cases there are pending data -
due to various SSL packets send during connection close. This
means connection close detection with https doesn't work unless
you use kqueue.
More information about the nginx