# HTTP Client FIN-ACK

**URL:** <https://www.ruby-forum.com/t/http-client-fin-ack/147976>\
**Category:** NGINX\
**Created:** [September 7, 2008, 11:57pm UTC](https://www.ruby-forum.com/t/http-client-fin-ack/147976 "2008-09-07T23:57:53Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ray\_Racine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a9adbd/32.png) [@Ray\_Racine](https://www.ruby-forum.com/u/Ray_Racine)\
**Post date:** [September 7, 2008, 11:57pm UTC](https://www.ruby-forum.com/t/http-client-fin-ack/147976/1 "2008-09-07T23:57:53Z")

</div>

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](http://www.blippr.com)). Though it could be the application.

Here is the sequence of events.

1. Client connects fine. TCP connect is standard 3-way handshake. SYN,  
SYN-ACK, ACK
2. My cliient sends a well-formed HTTP GET request for RSS content.
3. 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.)
4. 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.

---

<div class="post-metadata">

**Author:** ![Ray\_Racine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a9adbd/32.png) [@Ray\_Racine](https://www.ruby-forum.com/u/Ray_Racine)\
**Post date:** [September 8, 2008, 4:06am UTC](https://www.ruby-forum.com/t/http-client-fin-ack/147976/2 "2008-09-08T04:06:40Z")

</div>

Hello!

On Sun, Sep 07, 2008 at 05:15:08PM -0400, Ray Racine wrote:

> [www.blippr.com](http://www.blippr.com)). Though it could be the application.  
> a response, by sending its own FIN/ACK, to which the client sends an ACK.  
> indicates no further data will be sent by the client, to which nginx should  
> possible that nginx is not at fault here, but I thougt I’d pass it along.  
> There is no such thing as half-close in RFC 2616 (Hypertext  
> Transfer Protocol – HTTP/1.1). The most relevant part I was able  
> to find is from RFC 1945 (Hypertext Transfer Protocol – HTTP/1.0,  
> 1.3 Overall Operation):

% Except for experimental applications, current practice requires  
that  
% the connection be established by the client prior to each request  
and  
% closed by the server after sending the response. Both clients and  
% servers should be aware that either party may close the connection  
% prematurely, due to user action, automated time-out, or program  
% failure, and should handle such closing in a predictable fashion.  
In  
% any case, the closing of the connection by either or both parties  
% always terminates the current request, regardless of its status.

Please note: half-close isn’t distinguishable from full close at  
the other end without sending data. So in your situation server  
really have two options:

```
1. Assume client closed connection ("due to user action,

```

automated time-out, or program failure" - e.g. since user clicked  
‘stop’ button or clicked a link on a page) and try to minimize  
performance impact of doing unneeded work.

```
2. Assume client does something strange with TCP like half-close

```

for some unknown reason, and try to respond anyway.

By default nginx does 1 if request was proxied to backend and no  
reply from backend was got yet (and hence nginx has no chance to  
send data to client for unknown period of time on the one hand,  
and may save backend from unneded request on the other hand). It  
may be instructed not to do so by proxy\_ignore\_client\_abort  
configuration directive.

The strange thing in your story is that you see ‘reset by peer’,  
but I suspect it’s just wording problem and you see normal FIN  
from nginx side, not RST.

Maxim D.

p.s. Just don’t use shutdown(SHUT\_WR) with http, it’s wrong.

---

<div class="post-metadata">

**Author:** ![Ray\_Racine](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/a9adbd/32.png) [@Ray\_Racine](https://www.ruby-forum.com/u/Ray_Racine)\
**Post date:** [September 9, 2008, 2:11am UTC](https://www.ruby-forum.com/t/http-client-fin-ack/147976/3 "2008-09-09T02:11:10Z")

</div>

Hi ya!,

Thanks for the response.

I did some additional research. It appears the debate on what to do  
with  
half-close clients with regards to HTTP goes back quite a ways. I  
disagree  
that it is “strange” to do a TCP half-close, its part and parcel to the  
protocol itself and situationally, for a client it does make sense to do  
so. On the other hand, I also agree with you, given the additional  
background reading I’ve done, its probably just better to avoid it given  
the  
ambiguity around doing a half-close in the context of HTTP and varous  
alludes found in the HTTP RFC(s).

It may or then again it may not be of interest that nginx is somewhat  
unique  
in its behavior on how it deals with a half-close compared to other HTTP  
systems I’ve observed so far. These other systems Apache, IIS, Varnish,  
lighthttpd, … first complete the response and then finish the close  
handshake. nginx is the only system I’ve observed so far which responds  
with an immediate close (FIN/ACK).

Thanks,

Ray
