NOT sure this is a nginx problem, but I thought I’d pass it along.
I have a small custom Scheme HTTP library that uses its FFI to call
Linux
socket APIs. In other words, its a home brew implementation. I have
used
it to do various HTTP GETs/POSTs for RSS, JSON, etc with success.
However, when I attempted to do a simple RSS fetch from a site which
responds as Server: nginx/0.6.25, I observed an immediate, and
unexpected,
socket close (reset by peer) from nginx. I suspect it might be nginx
and
how it handles TCP connections and not the 3rd server application (
www.blippr.com). Though it could be the application.
Here is the sequence of events.
- Client connects fine. TCP connect is standard 3-way handshake. SYN,
SYN-ACK, ACK - My cliient sends a well-formed HTTP GET request for RSS content.
- My client library then closes my half of the duplex connection via
“shutdown SHUT_WR”. This means at the TCP level a FIN/ACK is sent to
nginx.
(Semantically this means, the client will not be sending any more data.) - nginx immediatly responds with a ACK, and then closes the socket
without
a response, by sending its own FIN/ACK, to which the client sends an
ACK.
In other words a standard 4-way TCP teardown. (Semantically nginx
sending
its own FIN/ACK means no more data will be sent.)
From what little I understand, it appears nginx is incorrectly
interrupting
the SHUT_WR (sends a FIN/ACK) as an end TCP connection. Not as "no
more
data will be sent on the write half (from the client) of the duplex TCP
connection.
However, I think the TCP correct behaviour for nginx should be to
respond
the HTTP request. Even though the client intiated SHUT_WR this only
indicates no further data will be sent by the client, to which nginx
should
respond with an ACK, but not close the connection until after sending
the
HTTP response and then sending its own FIN/ACK.
The above 1-4 sequence works fine with all other HTTP servers I’ve
called
to date.
I do successfully recieve a response if I do not do a call “shutdown
SHUT_WR” after sending the HTTP GET request, which is the workaround.
Given my limited knowledge this what I think I’m seeking. It IS very
possible that nginx is not at fault here, but I thougt I’d pass it
along.
Ray.