Subject: #458: Requirements upon proxies for Expect

From: Mark Nottingham <[email-masked]>
Date: Thu, 30 May 2013 19:27:33 +1000

Hi Willy,

On 20/04/2013, at 7:18 PM, Willy Tarreau <[email-masked]> wrote:

> On Sat, Apr 20, 2013 at 07:00:19PM +1000, Mark Nottingham wrote:
>> p2 5.1.1 "Requirements for HTP/1.1 proxies" bullet one effectively requires
>> proxies to forward ALL requests with Expect: 100-continue if the inbound
>> server is HTTP/1.1 -- even if the request is a GET.
>> 
>> I know that this isn't the intent, but that's how it reads; suggest
>> qualifying this to only apply to requests with bodies.
> 
> Do you see any risk in applying this to any request ? I've been thinking
> in the past about the possibility to use Expect to send non-idempotent
> requests over existing connections without fearing the risk of a broken
> connection, but the stupid situation where a client sends an empty POST
> with Expect is still problematic. All this to say that there might be
> some usages of Expect that are not covered here and not problematic
> either.

Sorry, I'm not following you here. What do you want to do?

>> The next bullet requires proxies to respond with a 417 if the inbound server
>> is HTTP/1.0. Just curious here - why? Wouldn't the maximally interoperable
>> thing be to generate a 100-continue yourself? While the client *could*
>> resubmit the request, they probably won't, because as far as they know, the
>> origin told them not to.
> 
> That's exactly what I thought as well when reading this point ! And FWIW,
> haproxy does so when it needs to parse part of the request body to pick
> a server. I think that was the exact intended purpose of skipping as
> many "100" responses as needed BTW.

OK. How do other folks feel about this? I think the proposal is to change:

> If the proxy knows that the version of the next-hop server is HTTP/1.0 or lower, it must not forward the request, and it must respond with a 417 (Expectation Failed) status code.

to:

"""
If the proxy knows that the version of the next-hop server is HTTP/1.0 or lower, it MAY either respond with a 417 (Expectation Failed) without forwarding the request, or with a 100 (Continue) status code while forwarding it.
"""

Note that this is applying to proxies, NOT gateways (like haproxy), which AFAICT don't have any requirements applying to them. Hmm.

I'd also really like to see us define what "final status code" means; is it just 417? Any 4xx or 5xx status? Any non-1xx status?

Cheers,

--
Mark Nottingham   http://www.mnot.net/

---

From: Willy Tarreau <[email-masked]>
Date: Fri, 31 May 2013 08:13:29 +0200

Hi Mark,

> Sorry, I'm not following you here. What do you want to do?

It took me some time to remember this discussion :-)

The idea was that when you want to heavily reuse connections between
a gateway and servers (let's say an LB and several servers), you can
multiplex requests over existing connections. But it's not allowed to
do this with non-idempotent requests, and it's always at risk. Since
these non-idempotent requests are mostly POST, a workaround against
the limitation can be to send Expect: 100-continue with all non-
idempotent requests, so that the connection is "tested" before the
body is sent. A corner case remains, where a POST request has an
empty body (maybe when uploading an empty file, I don't know), because
if I'm sending "expect: 100-continue" with "content-length: 0", the
server can only reply immediately, otherwise after it sends 100, it
will not receive anything. One alternative is to use chunked encoding
and to send 0 CRLF after receiving 100.

Now as always, all it turns to is to know if a POST with content-length 0
has an empty body or no body at all :-)

> > If the proxy knows that the version of the next-hop server is HTTP/1.0 or
> > lower, it must not forward the request, and it must respond with a 417
> > (Expectation Failed) status code.
> 
> to:
> 
> """
> If the proxy knows that the version of the next-hop server is HTTP/1.0 or
> lower, it MAY either respond with a 417 (Expectation Failed) without
> forwarding the request, or with a 100 (Continue) status code while forwarding
> it.
> """

I think it's better, but still I don't see the issue which could be caused
by a proxy returning 100 when the server is known to be 1.1. I tend to
consider that expect:100 is more related to the connection than to the
whole path, eventhough it's still not hop-by-hop in its definition. After
all, the first goal is to avoid uselessly sending huge amounts of data.
And the fact that we define the behaviour of each element in the chain
for this expect and 100 tends to confirm this hop-by-hop behaviour.

> Note that this is applying to proxies, NOT gateways (like haproxy), which
> AFAICT don't have any requirements applying to them. Hmm.

I understand, but some proxies will analyse posted contents to detect
malware activity or information leaks etc... and will have to send 100
themselves anyway.

> I'd also really like to see us define what "final status code" means; is it
> just 417? Any 4xx or 5xx status? Any non-1xx status?

I think that since only 1xx are non-final, final are all other ones, but
you're right, we should define this term.

Willy