Opened 10 years ago

Closed 7 years ago

#176 closed editorial (incorporated)

half-close because of pipelining

Reported by: mnot@… Owned by: fielding@…
Priority: normal Milestone: 21
Component: p1-messaging Severity: Active WG Document
Keywords: Cc:

Description

Real HTTP servers like Apache must not close the connection to signal the end of a response. They *half-close* it using the shutdown() socket function, and then sit for a while discarding any subsequent request which might have been pipelined.

This is necessary, because if any further data is received by a *fully*-closed TCP socket on the server, the servers's TCP will reset the connection and send a RST packet, which causes the server to abort *sending* any data which it hasn't yet transmitted successfully, and cause most clients to abort *receiving* the response, and sometimes abort sending data it has received up to the receiving application.

In other words, HTTP pipelining requires servers to half-close instead of fully-closing and then do a "lingering close" dance, if they send a response whose end is signalled by closing the connection.

If they don't do that, responses can be lost depending on transient network conditions.

This is necessary even if the reponse has "Connection: close", because the client may still have sent further request bytes before it sees any part of the response.

Since this is required for reliable HTTP pipelining over TCP, it should be mentioned somewhere in an HTTP specification. It isn't in RFC 2616 anywhere that I could see.

Change History (2)

comment:1 Changed 7 years ago by mnot@…

  • Owner set to fielding@…
  • Priority set to normal

comment:2 Changed 7 years ago by fielding@…

  • Milestone changed from unassigned to 21
  • Resolution set to incorporated
  • Status changed from new to closed

See p1 6.2.5. Tear-down ...

If a server performs an immediate close of a TCP connection, there is a significant risk that the client will not be able to read the last HTTP response. If the server receives additional data from the client on a fully-closed connection, such as another request that was sent by the client before receiving the server's response, the server's TCP stack will send a reset packet to the client; unfortunately, the reset packet might erase the client's unacknowledged input buffers before they can be read and interpreted by the client's HTTP parser.

To avoid the TCP reset problem, a server can perform a lingering close on a connection by closing only the write side of the read/ write connection (a half-close) and continuing to read from the connection until the connection is closed by the client or the server is reasonably certain that its own TCP stack has received the client's acknowledgement of the packet(s) containing the server's last response. It is then safe for the server to fully close the connection.

It is unknown whether the reset problem is exclusive to TCP or might also be found in other transport connection protocols.

Note: See TracTickets for help on using tickets.