Re: HTTP and half close (WAS: HTTP client abort detection)

There is a long-expired Internet-Draft, "HTTP Connection Management"
(http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-connection-00.txt),
that has some good discussion of related issues.

<!--StartFragment-->The HTTP/1.1 Proposed Standard [HTTP/1.1] specification
is silent on
   when, or even if, the connection should be closed (implementation
   experience was desired before the specification was frozen on this
   topic). So HTTP has moved from a model that closed the connection
   after every request/response to one that might never close. Neither
   of these two extremes deal with "connection management" in any
   workable sense.
<!--EndFragment-->

     -Carl



Miles Sabin <MSabin@interx.com> on 03/14/2001 07:35:00 AM

To:   http-wg@cuckoo.hpl.hp.com
cc:
Subject:  HTTP and half close (WAS: HTTP client abort detection)



Scott Lawrence wrote,
> Miles Sabin wrote:
> > I've been trying (unsuccessfully) to decide whether or not
> > RFC 2616 permits a server to interpret the receipt of a FIN
> > on the incoming-request side of it's connection to a client
> > as a full client close ...
>
> I think that it would have been poor form at best for the HTTP
> WG to ignore the Tcp semantics in that way.  In fact, the
> client is doing you a favor by sending the FIN as soon as it
> knows it's done with that half-connection - the server can then
> close its half right away even if it might otherwise have left
> it open for persistence, perhaps suffering the time-wait
> penalty when it times it out (if the client sends the first
> FIN, then it has to hold the time-wait, and the server
> doesn't).

Thinking about this some more, I'm coming to the conclusion that
there's a genuine and problematic gap in RFC 2616. Just to make
sure there's no misunderstanding here, I want to emphasize that
I'm quite well aware of the benefits for servers of clients
sending the first FIN.

As far as I can make out there's nothing in RFC 2616 which
unambiguously rules out any of the following possible client and
server implementations,

1. Clients which send a FIN early ... ie. by doing a half close
   as soon as their last request is sent, but possibly before
   the corresponding response has been received.

2. Clients which don't (half or full) close until all pending
   responses have been received.

A. Servers which treat an early client FIN only as a half close
   and continue processing and sending pending responses.

B. Servers which treat an early client FIN as an indicator of a
   client abort, and hence abandon processing and sending pending
   responses.

The problem is that clients of type 1 aren't fully interoperable
with servers of type B ... if a type 1 client does an eager
half close a type B server would abandon it's response.

So at least one of these two should be ruled out by RFC 2616.

Unfortunately I don't see that either unambiguously is. And if
neither are ruled out by the spec, then interoperability
considerations mean that it's not safe for client or server
implementors to adopt either. In real-world terms, I'm pretty
sure that most existing user-agents (nb. I'm not talking about
clients generally) are of type 2, and most servers are of type
A.

Here are some pro and con considerations wrt type 1 clients and
type B servers.

* The pragmatic good citizenship argument that a client should
  send the first FIN, and sending it immediately after its
  request has been sent, before any or all of the response has
  been received, makes that likely.

  On the other hand, this isn't the only way for a client to send
  the first FIN. In scenarios which allow a client to half close
  eagerly it should also be possible for it to send Connection:
  close, in which case the server would know that the connection
  is terminating. Hence the server, assuming it sends a Content-
  Length or chunks, could quite happily defer closing after
  sending the response, on the assumption that the client will
  close soon and that it can close it's own end when that
  happens.

  On balance, I don't think any conclusion can be drawn from the
  above. Early half close helps servers, but there are other
  ways of getting the same effect.

* A similar pragmatic argument that if servers are allowed to
  treat early client FINs as client aborts, then they might be
  able to avoid expensive response processing.

  In the particular case of a proxy server, such a FIN might be
  detected during proxy-side DNS resolution, but before the
  initiation of a connect to an origin server. If the proxy
  isn't going to cache the now unwanted response (either because
  it's not a caching proxy, or because it's confident the
  response will be uncacheable) then it would make sense not to
  attempt to forward the request to the origin server at all.

* From 8.1.4 Practical Considerations,

    Servers SHOULD always respond to at least one request per
    connection, if at all possible. Servers SHOULD NOT close a
    connection in the middle of transmitting a response, unless a
    network or client failure is suspected.

  So long as we read 'middle' of a response liberally and allow
  it to cover any point in time between the servers receipt of
  the request up to the completion of the sending of the
  response, then this seems to support type 1 clients against
  type B servers.

  Nevertheless, it's very hard to see the practical difference
  between a 'network or client failure' and, say, the behaviour
  of a user agent when a user hits the stop button because the
  server hasn't managed to deliver a response sufficiently
  quickly.

* If we aren't so liberal with the reading of 'middle' in the
  above quoted para, then we have,

    A client, server, or proxy MAY close the transport connection
    at any time. For example, a client might have started to send
    a new request at the same time that the server has decided to
    close the "idle" connection. From the server's point of view,
    the connection is being closed while it was idle, but from
    the client's point of view, a request is in progress.

  This suggests that a server which detects an early client FIN
  would be within it's rights in exploiting the persistent
  connection close race condition to avoid processing or sending
  any response at all: it's free to close the connection at any
  time, and it's not yet started to send it's response. The only
  difference between this scenario and the typical cases is the
  exact location of the request message ... on the wire, in the
  TCP receive buffers, or in a server buffer.

* If type 1 clients are legitimate, this parenthetical comment in
  4.4 Message Length becomes quite baffling,

    the transfer-length of that body is determined by one of the
    following (in order of precedence):

    5. By the server closing the connection. (Closing the
       connection cannot be used to indicate the end of a request
       body, since that would leave no possibility for the server
       to send back a response.)

  because if an early half-close were legitimate, it would
  provide a perfectly respectable mechanism for delimiting a
  request body.

None of the above leaves me with any particularly clear idea of
what best practice might be. Unless I can be persuaded otherwise
I'm obliged to be cautious from an interoperability perspective
and assume,

* That a type 1 client implementation is inadvisable, because
  it wouldn't reliably interoperate with type B servers.

* That a type B server implementation is inadvisable, because
  it wouldn't reliably interoperate with type 1 clients.

Can anyone shed any more light on this?

Cheers,


Miles

--
Miles Sabin                               InterX
Internet Systems Architect                5/6 Glenthorne Mews
+44 (0)20 8817 4030                       London, W6 0LJ, England
msabin@interx.com                         http://www.interx.com/

Received on Wednesday, 14 March 2001 08:03:04 UTC