Re: ISSUE: MUST a client wait for 100 when doing PUT or POST requests?

At 03:22 PM 6/10/97 -0700, Roy T. Fielding wrote:

>The *choice* of whether or not the client waits for the 100 response
>is not an interoperability requirement.  If an application has reason
>to expect that the server will accept the request and read the incoming
>data before closing (as is the case for existing POST requests to a
>CGI script) or if the application doesn't mind receiving a reset and
>repeating the request at a slower rate the second time, then it does
>not need to wait for the 100.  If, however, it is an application that
>wants to test the waters before diving in, then it can wait for the 100.
>Neither case impacts the interoperability between client and server.

The real question that came up in the discussion, which I sent to the
mailing list was the following:

>Is it enough to rely on the half-close of the
>connection or should the client wait for a 100 code before sending the
>body?

In case we can rely on the half-close to work and to be implemented
everywhere, we don't have a problem and 100 can be sent as currently
described. The reason for suggesting, that applications should wait for the
100 code was that this may not always be the case.

The reason why this can be a correctness problem, is when a client
pipelines non-idempotent methods. For example, the following situation may
occur:

The client starts a pipeline like this

	DELETE /old HTTP/1.1
	Host: some.host

	PUT /big HTTP/1.1
	Host: some.host
	Content-Length: 100000
	Content-Type: text/html
	
	12345678901234567890........	

The server responds:

	HTTP/1.1 200 OK

	HTTP/1.1 401 Unauthorized
	Connection: Close

Both applications behave according to the spec. The DELETE request has been
processed and succeeded but the second did not have appropriate
authentication. However, the server has said that it closes the connection
and it does so in both directions. The client has already sent a large
chunk of the big document but as the server doesn't accept more data, TCP
generates a RST to make the other end stop. This will cause the _first_
response to get lost even though nothing went wrong and the client has no
mechanism to find out.

This is not particular to PUT or POST but can happen just as well if the
client pipelines 50 DELETE requests. However, as PUT and POST are likely to
be bigger the problems can happen more easily.

I can see three ways out of the problem:

1) Add a requirement for HTTP/1.1 that servers MUST do half-closing
connections. The problem is then to determine for how long the incoming
connection should stay open in order to make sure that the client won't
loose the response. At the TCP level, the only way to determine this is to
make sure that the segment which contains the response has been ACK'ed by
the client and received by the server. I don't know of any method to
propagate this information to the application layer.

The only place mentioning the half-close problem is the connection
management draft by Jim Gettys and Alan Freier. This document currently
progresses independently from the HTTP/1.1 spec.

2) As Paul Leach mentions, don't allow pipelining of any non-idempotent
methods like PUT, POST, DELETE, etc. It can still be hard to recover a
broken pipeline due to TCP RST but at least it is possible.

3) Allow pipelining of PUT and POST but with the requirement that the
client MUST wait for the 100 code before sending the body if doing so. A
non-pipelined request does not have to wait for the 100 code. Disallow
pipelining of other non-idempotent methods. This will in many cases save a
RRT compared to 2).

I don't know whether 1) is realistic, 2) will work but is the most
conservative. 3) allows for some optimization using pipelining and does not
prevent current practice.

Thanks,

Henrik
--
Henrik Frystyk Nielsen, <frystyk@w3.org>
World Wide Web Consortium
http://www.w3.org/People/Frystyk

Received on Wednesday, 11 June 1997 07:50:08 UTC