- From: Henrik Frystyk Nielsen <frystyk@w3.org>
- Date: Wed, 11 Jun 1997 10:47:50 -0400
- To: fielding@kiwi.ICS.UCI.EDU, paulle@microsoft.com, http-wg@cuckoo.hpl.hp.com
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