Re: Can the response entity be transmitted before all the request entity has been read?

On Fri, 2004-03-12 at 06:41, Jamie Lokier wrote:
> Dear all,
> 
> I have been implementing an HTTP/1.1 server which consumes the request
> entity lazily, as need by the application.
> 
> If the application decides that it can generate some or all of the
> response before it finishes reading the whole request entity, is that
> allowed?
> 
> Can the application generate all the response without reading any of
> the request entity and without sending 100 (Continue) - is that
> allowed?
> 
> I've been studying RFC 2616 and don't see an answer.
> 
> RFC 2616, 8.2.2:
> 
>   8.2.2 Monitoring Connections for Error Status Messages
> 
>      An HTTP/1.1 (or later) 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 trailer 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.
> 
> I'm not entirely sure if this means _network_ errors (such as TCP
> shutdown or reset), or HTTP Error Status codes 4xx and 5xx.  I guess
> it means HTTP Error Status codes, because of the implication that the
> connection might continue.

It does mean HTTP Error Status responses (any status > 299).

> 1. Regarding my first question, whether the response can be partly
> transmitted before all of the request entity has been read.
> 
> If the above section means HTTP Error Status codes, then the answer is
> no if the status is an error code.  In other words, if the server
> wanted to generate an error response, but use data from the request
> entity to do it, incrementally, it would have to read all of the
> request entity that it needs before transmitting any of the response.
> Is this right?

Yes.

> What is the answer if the status is not an error code.  Can the server
> begin transmitting the response entity before all of the request
> entity has been read?  (Assume that the server is intelligent enough
> to avoid deadlock by always reading request data when it arrives).

Yes.

> One simple example would be a server which serves the file it is being
> transmitted, or a transformation of it.  It would be quite nice to
> upload a file, and have the transformed version generated
> incrementally and downloaded as the upload proceeds.  (This is
> obviously possible using two separate connections, but my question is
> is it supported by HTTP/1.1 over a single connection?)

Sure - it's TCP, so it's actually more efficient to use it in both
directions at the same time (piggybacked acks).

> 2. Regarding my second question, whether a non-error response can be
> safely transmitted without reading the request entity.  Is it allowed?
> Does the connection have to be made non-persistent; i.e. closed afterwards?

Not if the client says it's HTTP/1.1.  If the client is 1.0, then you
have to assume a non-persistent connection by default.

If you have enough information to begin the response just from reading
the request headers, then you are free to send the response headers
right away; even the 1xx response is optional - you can skip right to
sending the final response.  (Note: the rules of the protocol don't
forbid this - what any given client will do with this is a different
question that can be answered only with testing).

> If 100 (Continue) isn't transmitted, some clients may start
> transmitting their request entities anyway.  Therefore there's no way
> for the server to determine whether data received from the client is
> the request entity or the next request, if it wants to try avoiding
> 100 (Continue) to produce a non-error response without using the
> request entity.

No, you can tell from the headers whether or not there is a request
body.  If there is a non-zero Content-Length, or a 'Transfer-Encoding:
chunked', or a Content-Type specifying a multipart encoding, then that
indicates the presence of a body.  If none of the above are there, then
there is no body and the next byte starts the next request.

> This comes up because the server will transmit 100 (Continue) only
> when the application begins to read the request entity via the server,
> naturally.  If the application generates a 200 OK response complete
> with entity, and has not read the request entity, what must the server
> do?  What should it do?
> 
> Does it have to read the request entity anyway if it wants to keep the
> connection persistent?  (If so, it might be worth doing that if the
> request entity is known to be very small).

Yes, to keep the connection open it must consume the request entity.

> Or can it avoid reading the request entity completely, by not sending
> 100 (Continue) and somehow determining when the next request arrives
> on that connection.  Is that possible?

No, but even if it were it wouldn't save you anything - TCP is a stream;
there's no way to discard the bytes other than at the receiver (without
closing the connection, that is).

-- 

Received on Friday, 12 March 2004 08:29:29 UTC