Revised resolution for the STATUS100 issue

I'd like to thank everyone who commented on the previous draft
of this proposal.  I've incorporated most of the specific comments
in the revised draft, below.

Changes include:
	(1) Changing "HTTP/1.1 or later" to "HTTP/1.1", in
	contexts where this was incorrectly placing a requirement
	on the behavior of an implementation of a future version
	of HTTP/1.x

	(2) Made it clear that user-agents should retry requests,
	not "clients" in general
	
	(3) Converted requirements for clients to ignore unexpected
	100 (Continue) responses, and for proxies to forward 100
	responses, into a general requirement for 1xx responses.
	
	(4) Modified some TCP-specific language, to make it clearer
	that non-TCP transports are supported for HTTP.
	
	(5) Require that the origin server MUST NOT wait for
	the request body before it sends a required 100 (Continue)
	response.
	
	(6) Allow, rather than require, a server to omit
	100 (Continue) if it has already seen some of the
	request body.
	
	(7) Allow servers to defend against denial-of-service
	attacks and broken clients.

During our editorial group discussion today, we agreed that the
proposal (with these changes) was pretty close to the right
solution, so we are likely to issue a last-call on this soon.
I.e., speak up now if you have complaints.

-Jeff
P.S.: Note that there is a new issue,
	http://www.w3.org/pub/WWW/Protocols/HTTP/Issues/#IDEMPOTENT
open; the section on Idempotent Methods will be revised.   Those
changes will NOT be included in the resolution for STATUS100.


=== 
=== Major revisions to 8.2
=== 
======================

8.2 Message Transmission Requirements

8.2.1 Persistent connections and flow control

   HTTP/1.1 servers SHOULD maintain persistent connections and use
   transport-level flow control mechanisms, if available, to resolve
   temporary overloads, rather than terminating connections with the
   expectation that clients will retry. The latter technique can
   exacerbate network congestion.

8.2.2 Monitoring connections for error status messages

   An HTTP/1.1 client sending a message-body SHOULD monitor
   the network connection for an error status while it is transmitting
   the request. If the client sees an error status, it SHOULD
   immediately cease transmitting the body. If the body is being sent
   using a "chunked" encoding (section 3.6), a zero length chunk and
   empty footer MAY be used to prematurely mark the end of the
   message. If the body was preceded by a Content-Length header, the
   client MUST close the connection.

8.2.3 Automatic retrying of requests

   If a user agent sees the transport connection close before it
   receives a final response to its request, if the request method is
   idempotent (see section 9.1.2), the user agent SHOULD retry the
   request without user interaction.  If the request method is not
   idempotent, the user agent SHOULD NOT retry the request without user
   confirmation.  (Confirmation by user-agent software with semantic
   understanding of the application MAY substitute for user
   confirmation.)

8.2.4 Use of the 100 (Continue) status

   The purpose of the 100 (Continue) status (see section 10.1.1) is to
   allow an end-client that is sending a request message with a request
   body to determine if the origin server is willing to accept the
   request (based on the request headers) before the client sends the
   request body.  In some cases, it may either be inappropriate or
   highly inefficient for the client to send the body if the server
   will reject the message without looking at the body.

   Requirements for HTTP/1.1 clients:
   o  If a client will wait for a 100 (Continue) response before sending
      the request body, it MUST send an "Expect" request-header field
      (section 14.XX) with the "100-continue" expectation.

   o  A client MUST NOT send an "Expect" request-header field
      (section 14.XX) with the "100-continue" expectation if it
      does not intend to send a request body.

      Note: Because of the presence of older implementations, the
      protocol allows ambiguous situations in which a client may send
      "Expect: 100-continue" without receiving either a 419
      (Expectation Failed) status or a 100 (Continue) status.
      Therefore, when a client sends this header field to an origin
      server (possibly via a proxy) from which it has never seen a 100
      (Continue) status, the client should not wait for an indefinite
      or lengthy period before sending the request body.

   Requirements for HTTP/1.1 origin servers:
   o  Upon receiving a request which includes an "Expect" request-header
      field with the "100-continue" expectation, an origin server MUST
      either respond with 100 (Continue) status and continue to read
      from the input stream, or respond with an error status.  The
      origin server MUST NOT wait for the request body before sending
      the 100 (Continue) response.  If it responds with an error
      status, it MAY close the transport connection or it MAY
      continue to read and discard the rest of the request. It MUST NOT
      perform the requested method if it returns an error status.
   
   o  An origin server SHOULD NOT send a 100 (Continue) response if
      the request message does not include an "Expect" request-header
      field with the "100-continue" expectation, and MUST NOT send a
      100 (Continue) response if such a request comes from an HTTP/1.0
      (or earlier) client.
   
   o  An origin server MAY omit a 100 (Continue) response if
      has already received some or all of the request body for the
      corresponding request.
   
   o  An origin server that sends a 100 (Continue) response MUST
      ultimately send a final status code, once the request body
      is received and processed, unless it terminates the transport
      connection prematurely.
   
   o  If an origin server receives a request that does not include an
      "Expect" request-header field with the "100-continue"
      expectation, and the request includes a request body, and the
      server responds with an error status before reading the entire
      request body from the transport connection, then the server
      SHOULD NOT close the transport connection until it has read the
      entire request, or until the client closes the connection.
      Otherwise, the client may not reliably receive the response
      message.  However, this requirement should not be construed
      as preventing a server from defending itself against
      denial-of-service attacks, or from badly broken client
      implementations.

   For compatibility with RFC 2068, a server MAY send a 100 (Continue)
   status in response to an HTTP/1.1 PUT or POST request that does not
   include an "Expect" request-header field with the "100-continue"
   expectation.  This exception, the purpose of which is to minimize
   any client processing delays associated with an undeclared wait for
   100 (Continue) status, applies only to HTTP/1.1 requests, and not to
   requests with any other HTTP-version value.

   Requirements for HTTP/1.1 proxies:
   o  If a proxy receives a request that includes an "Expect"
      request-header field with the "100-continue" expectation, and the
      proxy either knows that the next-hop server complies with
      HTTP/1.1 or higher, or does not know the HTTP version of the
      next-hop server, it MUST forward the request, including the
      Expect header field.

   o  If the proxy knows that the version of the next-hop server is
      HTTP/1.0 or lower, it MUST NOT forward the request, and it MUST
      respond with a 419 (Expectation Failed) status.

   o  Proxies SHOULD maintain a cache recording the HTTP version
      numbers received from recently-referenced next-hop servers.

   o  A Proxy MUST NOT forward a 100 (Continue) response if the request
      message was received from an HTTP/1.0 (or earlier) client and did
      not include an "Expect" request-header field with the
      "100-continue" expectation.  This requirement overrides the
      general rule for forwarding of 1xx responses (see section 10.1).

8.2.5 Client behavior if server prematurely closes connection

   If an HTTP/1.1 client sends a request which includes a
   request body, but which does not include an "Expect" request-header
   field with the "100-continue" expectation, and if the client is not
   directly connected to an HTTP/1.1 origin server, and if
   the the client sees the connection close before receiving any status
   from the server, the client SHOULD retry the request, subject to the
   restrictions in section 8.2.3. If the client does retry this
   request, it MAY use the following "binary exponential backoff"
   algorithm to be assured of obtaining a reliable response:

  1. Initiate a new connection to the server

  2. Transmit the request-headers

  3. Initialize a variable R to the estimated round-trip time to the
     server (e.g., based on the time it took to establish the
     connection), or to a constant value of 5 seconds if the round-trip
     time is not available.

  4. Compute T = R * (2**N), where N is the number of previous retries
     of this request.

  5. Wait either for an error response from the server, or for T seconds
     (whichever comes first)

  6. If no error response is received, after T seconds transmit the body
     of the request.

  7. If client sees that the connection is closed prematurely, repeat
     from step 1 until the request is accepted, an error response is
     received, or the user terminates the retry process.

   If at any point an error status is received, the client

  o  SHOULD NOT continue and

  o  SHOULD close the connection if it has not completed sending the
     request message.

=============================
===
=== What follows is basically what I sent on Wed, 02 Jul 97, in
=== 	http://www.ics.uci.edu/pub/ietf/http/hypermail/1997q3/0027.html
=== but with a few changes:
=== 
=== (1) I've changed the header name from "Expected" to "Expect",
=== just to save a couple of bytes.
=== 
=== (2) Following Scott Lawrence's suggestion in
=== 	http://www.ics.uci.edu/pub/ietf/http/hypermail/1997q3/0032.html
=== I've changed the status code from 412 (Precondition Failed) to a new
=== 419 (Expectation failed) code, and included additional language
=== for specifying that new code.
=== 
=== (3) I've added some clarifications based on my message on "Is 100-Continue
=== hop-by-hop?",
=== 	http://www.ics.uci.edu/pub/ietf/http/hypermail/1997q3/0078.html
=== 
=== (4) I did NOT add an "Expect: 100-hopbyhop" because nobody has
=== spoken up in its favor.
=== 
=== (5) I reorganized the paragraphs slightly, and introduced a new
=== subhead.
=== 
=============================

10.1 Informational 1xx

   This class of status code indicates a provisional response,
   consisting only of the Status-Line and optional headers, and is
   terminated by an empty line. Since HTTP/1.0 did not define any 1xx
   status codes, servers MUST NOT send a 1xx response to an HTTP/1.0
   client except under experimental conditions.

   A client MUST be prepared to accept one or more 1xx status responses
   prior to a regular response, even if the client does not expect a
   100 (Continue) status message.  Unexpected 1xx status responses
   MAY be ignored by a user agent.

   Proxies MUST forward 1xx responses, unless the connection between
   the proxy and its client has been closed, or unless the proxy itself
   requested the generation of the 1xx response.  (For example, if a
   proxy adds a "Expected:  100-continue" field when it forwards a
   request, then it need not forward the corresponding 100 (Continue)
   response(s).)

10.4.1 100 Continue

   The client may continue with its request. This interim response is
   used to inform the client that the initial part of the request has
   been received and has not yet been rejected by the server. The client
   SHOULD continue by sending the remainder of the request or, if the
   request has already been completed, ignore this response. The server
   MUST send a final response after the request has been completed.
   See section 8.2.4 for detailed discussion of the use and handling
   of this status code.

=============================

10.4.20 419 Expectation Failed

   The expectation given in an "Expect" request-header field (see
   section 14.XX) could not be met by this server, or, if the server is
   a proxy, the server has unambiguous evidence that the request could
   not be met by the next-hop server.

=============================

14.XX Expect

    The Expect request-header field is used to indicate that
    particular server behaviors are required by the client.  A
    server that does not understand or is unable to comply with any of
    the expectation values in the Expect field of a request MUST
    respond with appropriate error status.

      Expect              =  "Expect" ":" 1#expectation

      expectation  =  "100-continue" | expectation-extension
      expectation-extension =  token [ "=" ( token | quoted-string )
                                       *expect-params ]
      expect-params           =  ";" token [ = ( token | quoted-string ) ]

    The server SHOULD respond with a 419 (Expectation Failed) status
    if any of the expectations cannot be met.

    This header field is defined with extensible syntax to allow for
    future extensions.  If a server receives a request containing
    an Expect field that includes an expectation-extension that
    it does not support, it MUST respond with a 419 (Expectation
    Failed) status.

14.XX.1 Expect 100-continue

    When the "100-continue" expectation is present on a request that
    includes a body, the requesting client will wait after sending the
    request headers before sending the content-body.  In this case, the
    server MUST conform to the requirements of section 8.2.4: it MUST
    either send a 100 (Continue) status, or an error status, after
    receiving the "Expect: 100-continue" request header.

    If a proxy receives a request with the "100-continue" expectation,
    and the proxy either knows that the next-hop server complies with
    HTTP/1.1 or higher, or does not know the HTTP version of the
    next-hop server, it MUST forward the request, including the Expect
    header field.  If the proxy knows that the version of the next-hop
    server is HTTP/1.0 or lower, it MUST NOT forward the request, and
    it MUST respond with a 419 (Expectation Failed) status.  Proxies
    SHOULD maintain a cache recording the HTTP version numbers received
    from recently-referenced next-hop servers.
    
	Note: Because of the presence of older implementations, the
	protocol allows ambiguous situations in which a client may send
	"Expect: 100-continue" without receiving either a 419
	(Expectation Failed) status or a 100 (Continue) status.
	Therefore, when a client sends this header field to an origin
	server (possibly via a proxy) from which it has never seen a
	100 (Continue) status, the client should not wait for an
	indefinite or lengthy period before sending the request body.

=============================
=== 
=== 13.11 in RFC 2068 incorrectly allows a proxy to inject
=== its own 100 response into the reply stream.  The change
=== below modifies *only* the last sentence of the first
=== paragraph.
=== 
=============================

13.11 Write-Through Mandatory

   All methods that may be expected to cause modifications to the origin
   server's resources MUST be written through to the origin server. This
   currently includes all methods except for GET and HEAD. A cache MUST
   NOT reply to such a request from a client before having transmitted
   the request to the inbound server, and having received a
   corresponding response from the inbound server. This does not
   prevent a proxy cache from forwarding a 100 (Continue) response
   before the inbound server has sent its final reply.

   The alternative (known as "write-back" or "copy-back" caching) is not
   allowed in HTTP/1.1, due to the difficulty of providing consistent
   updates and the problems arising from server, cache, or network
   failure prior to write-back.

=============================
=== 
=== Add this to the end of 8.1.2.2 (Pipelining)
=== 
=============================

   Clients SHOULD NOT pipeline requests using non-idempotent methods or
   non-idempotent sequences of methods (see section 9.1.2).  Otherwise,
   a premature termination of the transport connection may lead to
   indeterminate results.  A client wishing to send a non-idempotent
   request SHOULD wait to send that request until it has received the
   response status for the previous request.

=============================

Received on Friday, 18 July 1997 15:56:25 UTC