*From: *Willy Tarreau <w...@1wt.eu>
*Sent: * 2014-05-02 11:15:07 E
*To: *Patrick Hemmer <hapr...@stormcloud9.net>
*CC: *Rachel Chavez <rachel.chave...@gmail.com>, haproxy@formilux.org
*Subject: *Re: please check

> Hi Patrick,
>
> On Fri, May 02, 2014 at 10:57:38AM -0400, Patrick Hemmer wrote:
>> *From: *Willy Tarreau <w...@1wt.eu>
>> *Sent: * 2014-05-02 02:02:11 E
>> *To: *Rachel Chavez <rachel.chave...@gmail.com>
>> *CC: *haproxy@formilux.org
>> *Subject: *Re: please check
>>
>>> On Thu, May 01, 2014 at 03:44:46PM -0400, Rachel Chavez wrote:
>>>> The problem is:
>>>>
>>>> when client sends a request with incomplete body (it has content-length but
>>>> no body) then haproxy returns a 5XX error when it should be a client issue.
>>> It's a bit more complicated than that. When the request body flows from the
>>> client to the server, at any moment the server is free to respond (either
>>> with an error, a redirect, a timeout or whatever). So as soon as we start
>>> to forward a request body from the client to the server, we're *really*
>>> waiting for the server to send a verdict about that request.
>> At any moment the server is free to respond yes, but the server cannot
>> respond *properly* until it gets the complete request.
> Yes it can, redirects are the most common anticipated response, as the
> result of a POST to a page with an expired cookie. And the 302 is a
> clean response, it's not even an error.
I should have clarified what I meant by "properly" more. I didn't mean
that the server can't respond at all, as there are many cases it can,
some of which you point out. I meant that if the server is expecting a
request body, it can't respond with a 200 until it verifies that request
body.
>
>> If the response depends on the request payload, the server doesn't know
>> whether to respond with 200 or with a 400.
> With WAFs deployed massively on server infrastructures, 403 are quite
> common long before the whole data. 413 request entity too large appears
> quite commonly as well. 401 and 407 can also happen when authentication
> is needed.
>
>> RFC2616 covers this behavior in depth. See "8.2.3 Use of the 100
>> (Continue) Status". This section indicates that it should not be
>> expected for the server to respond without a request body unless the
>> client explicitly sends a "Expect: 100-continue"
> Well, 2616 is 15-years old now and pretty obsolete, which is why the
> HTTP-bis WG is working on refreshing this. New wording is clearer about
> how a request body is used :
>
>    o  A server MAY omit sending a 100 (Continue) response if it has
>       already received some or all of the message body for the
>       corresponding request, or if the framing indicates that there is
>       no message body.
>
> Note the "some or all".
I'm assuming you're quoting from:
http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-26#section-5.1.1

This only applies if the "Expect: 100-continue" was sent. "Expect:
100-continue" was meant to solve the issue where the client has a large
body, and wants to make sure that the server will accept the body before
sending it (and wasting bandwidth). Meaning that without sending
"Expect: 100-continue", it is expected that the server will not send a
response until the body has been sent.

>
> It's very tricky to find which side is responsible for a stalled upload.
> I've very commonly found that frozen servers, or those with deep request
> queues will stall during body transfers because they still didn't start
> to consume the part of the request that's queued into network buffers.
>
> All I mean is that it's unfortunately not *that* white and black. We
> *really* need to make a careful difference between what happens on the
> two sides. The (hard) goal I'm generally seeking is to do my best so
> that a misbehaving user doesn't make us believe that a server is going
> badly. That's not easy, considering for example the fact that the 501
> message could be understood as a server error while it's triggered by
> the client.
>
> In general (unless there's something wrong with the way client timeouts
> are reported in http_request_forward_body), client timeouts should be
> reported as such, and same for server timeouts. It's possible that there
> are corner cases, but we need to be extremely careful about them and not
> try to generalize.
I agree, a client timeout should be reported as such, and that's what
this is all about. If the client sends half the body (or no body), and
then freezes, the client timeout should kick in and send back a 408, not
the server timeout resulting in a 504.

I think in this regards it is very clear.
* The server may respond with the HTTP response status code any time it
feels like it.
* Enable the server timeout and disable the client timeout upon any of
the following:
    * The client sent "Expect: 100-continue" and has completed all headers
    * The complete client request has been sent, including body if
"Content-Length" > 0
    * Writing to the server socket would result in a blocking write
(indicating that the remote end is not processing).
* Enable the client timeout and disable the server timeout upon any of
the following:
    * New connection.
    * The server has responded to the "Expect: 100-continue".
    * The complete response has been sent, and "Connection: close" was
not set.
    * Writing to the client socket would result in a blocking write.
The only ambiguity is the "Connection: upgrade" "Upgrade: websocket", as
at that point the stream is interactive. I'm sure whatever haproxy does
here is the right behavior (whether it is to disable both timers, or
enable both timers).

Does this not cover all scenarios? I can't think of anything where this
would not result in the desired behavior.

-Patrick

Reply via email to