Sending a Response before the Request has been entirely consumed?

Hello, Is it valid for a server to start sending an HTTP Response before the Request has been entirely consumed? Or to put it differently, is there any case where it would be valid for the Response message-body to be streaming the value from the Request message-body? Doing that seems like it would, in general, not be a good idea. For example, if you started sending a 200 OK response, and then you encountered a parse error in the Request message body, there is no way to go back and change to an error status code. One slight exception seems to be the use of 100 (Continue), section 8.2.3, http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html but even there, you are just looking at the Request headers, not trying to stream from the Request message body to the Response message body. In this section: http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6 It says, "After receiving and interpreting a request message, a server responds with an HTTP response message." Which could be interpreted to mean that the entire request message must be received and interpreted before the response can be sent. But, that could be reading too much into it. I'd rather see something like: "The server MUST read the entire request message before sending a response." Any thoughts? Is there any definitive statement? Are there any real world examples where you would want to stream the request message body into the response? For example, a service where you can PUT/POST a document, and it gets transformed on the fly and returned in the response? At this point I am inclined to design the server such that you must read the entire request message before you can begin sending the response. But, if that is a mistake, I'd love to hear about it now ;) - jeremy

On 09/17/2013 03:08 PM, Jeremy Shaw wrote:
Hello,
Is it valid for a server to start sending an HTTP Response before the Request has been entirely consumed? Or to put it differently, is there any case where it would be valid for the Response message-body to be streaming the value from the Request message-body?
I don't know about valid from a "standards" point of view, but a valid use case, yes. For some reason or other, you are able to determine early that you do not care to answer this request, and you want to drop it or return an error as rapidly as possible. For instance, if a particular page is getting DOS'ed, part of your mitigation strategy might be to bail out of any request for that page as early as possible, or if it's because a particular page is being over-accessed you might want to return a static snapshot ASAP and get on with the next request. Or based on IPs, or whoknows what. I think you're right that returning a 200 before you've seen the entire header is probably never a good idea, but there are many 4xx and 5xx series responses you can make.

So, section 8.2.2 says:
~~~~
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.
~~~~
It's a bit ambiguous what it means by error status -- but let's assume it
means a Response with a 4xx or 5xx series error code.
How does this interact with HTTP persistent connections. If the server
sends a 4xx error code, there could still be other valid requests in the
queue? If the request had a content-length header, then the client is going
to close the connection on us, so there is nothing more for us to do. But
if it was chunked, it sounds like we could drain any remaining data it
sends and then process additional requests over the persistent connection?
I'm still thinking that sending a response body that depends on the request
body before the whole request body has been received is asking for trouble.
For example, let's assume that the client is a simple, non-threaded client
which attempts to send the entire request before reading the response at
all. (After all, SHOULD and MAY are not the same as MUST). If the server
tried to stream directly from the request body into the response body, that
would likely result in a deadlock because the client would not be reading
any of the response until it was done sending the entire request. And the
server would not be reading more of the request because it would be blocked
trying to send the response.
So, we can assume the client *might* read the Response before it sends all
the Request, but we should definitely not rely on it?
- jeremy
On Tue, Sep 17, 2013 at 2:30 PM, Jeremy Bowers
On 09/17/2013 03:08 PM, Jeremy Shaw wrote:
Hello,
Is it valid for a server to start sending an HTTP Response before the Request has been entirely consumed? Or to put it differently, is there any case where it would be valid for the Response message-body to be streaming the value from the Request message-body?
I don't know about valid from a "standards" point of view, but a valid use case, yes. For some reason or other, you are able to determine early that you do not care to answer this request, and you want to drop it or return an error as rapidly as possible. For instance, if a particular page is getting DOS'ed, part of your mitigation strategy might be to bail out of any request for that page as early as possible, or if it's because a particular page is being over-accessed you might want to return a static snapshot ASAP and get on with the next request. Or based on IPs, or whoknows what.
I think you're right that returning a 200 before you've seen the entire header is probably never a good idea, but there are many 4xx and 5xx series responses you can make.

On Wed, Sep 18, 2013 at 1:54 AM, Jeremy Shaw
I'm still thinking that sending a response body that depends on the request body before the whole request body has been received is asking for trouble.
We allow you to do this in Snap but you have to explicitly ask for it. An
example application here would be streaming transcoding. The client has to
be written with this in mind in order for this to work (if it's not reading
the response while it's streaming the request body, eventually its write()s
will block), so this is a feature that only really makes sense for API
servers.
G
--
Gregory Collins

Interesting. That is the one use case I could think of -- transcoding on
the fly. And, I was thinking the same thing -- only allow that if the user
explicitly asks for it. But, by default, make them read the request before
sending the response, because that is what they want 99% of the time and
doing something else is just asking for trouble.
- jeremy
On Wed, Sep 18, 2013 at 4:58 AM, Gregory Collins
On Wed, Sep 18, 2013 at 1:54 AM, Jeremy Shaw
wrote: I'm still thinking that sending a response body that depends on the request body before the whole request body has been received is asking for trouble.
We allow you to do this in Snap but you have to explicitly ask for it. An example application here would be streaming transcoding. The client has to be written with this in mind in order for this to work (if it's not reading the response while it's streaming the request body, eventually its write()s will block), so this is a feature that only really makes sense for API servers.
G -- Gregory Collins

On 2013-09-18 01:54, Jeremy Shaw wrote: [--snip--]
I'm still thinking that sending a response body that depends on the request body before the whole request body has been received is asking for trouble.
A couple of use cases: Server-Sent Events (aka. EventSource in HTML5). In that case you never full receive the (empty) request body, since your goal is to not close the connection at all. And generalizing slightly: You want this if the server can decide, based on the currently received *prefix* of the full request body, that it can send some *prefix* of the response body already. (It might even make sense even if the server later has to "cancel" some part of the previous response by writing a "cancel instruction" later in the response. For example, if latency in getting the first bit of data is more important than complete accuracy.) This would generally make most sense in streaming scenarios, but I could imagine this the general prefix-based consideration might apply to e.g. synchronization algorithms based on comparing hash-trees for instance. Of course, unless you can guarantee that the response will below the networking buffer size, your client must be nonblocking/multi-threaded :). Regards,
participants (4)
-
Bardur Arantsson
-
Gregory Collins
-
Jeremy Bowers
-
Jeremy Shaw