Dropped https client connection doesn't drop backend proxy_pass connection

Maxim Dounin 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:, server: www.*, request: "GET /events/ HTTP/1.0",
> upstream: "", 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 
pending data.

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.

Further reading:


Maxim Dounin

More information about the nginx mailing list