<p>Below is a message from Roy Fielding, one of the authors
of HTTP/1.1.</p>
<h3><a name="message" id="message">Why the lingering close
functionality is necessary with HTTP</a></h3>
<p>The need for a server to linger on a socket after a close
is noted a couple times in the HTTP specs, but not
explained. This explanation is based on discussions between
myself, Henrik Frystyk, Robert S. Thau, Dave Raggett, and
John C. Mallery in the hallways of MIT while I was at W3C.</p>
<p>If a server closes the input side of the connection
while the client is sending data (or is planning to send
data), then the server's TCP stack will signal an RST
(reset) back to the client. Upon receipt of the RST, the
client will flush its own incoming TCP buffer back to the
un-ACKed packet indicated by the RST packet argument. If
the server has sent a message, usually an error response,
to the client just before the close, and the client
receives the RST packet before its application code has
read the error message from its incoming TCP buffer and
before the server has received the ACK sent by the client
upon receipt of that buffer, then the RST will flush the
error message before the client application has a chance to
see it. The result is that the client is left thinking that
the connection failed for no apparent reason.</p>
<p>There are two conditions under which this is likely to
occur:</p>
<ol>
<li>sending POST or PUT data without proper
authorization</li>
<li>sending multiple requests before each response
(pipelining) and one of the middle requests resulting in
an error or other break-the-connection result.</li>
</ol>
<p>The solution in all cases is to send the response, close
only the write half of the connection (what shutdown is
supposed to do), and continue reading on the socket until
it is either closed by the client (signifying it has
finally read the response) or a timeout occurs. That is
what the kernel is supposed to do if SO_LINGER is set.
Unfortunately, SO_LINGER has no effect on some systems; on
some other systems, it does not have its own timeout and
thus the TCP memory segments just pile-up until the next
reboot (planned or not).</p>
<p>Please note that simply removing the linger code will
not solve the problem -- it only moves it to a different
and much harder one to detect.</p>
</div></div>
<div class="bottomlang">
<p><span>Available Languages: </span><a href="../en/misc/fin_wait_2.html" title="English"> en </a></p>
</div><div id="footer">
<p class="apache">Copyright 1999-2004 The Apache Software Foundation.<br />Licensed under the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a>.</p>