On Tue, Dec 8, 2015 at 2:22 PM, Jacob Champion <champio...@gmail.com> wrote:

> I wrote this in response to Stefan's note on the zero-length request body
> limit for h2c Upgrades, then realized it would further fragment the
> (already massive) conversation, so here it is.
>

And I agree to keep the other thread as clean as possible, so to your
thoughts...


> Stefan wrote:
>
>> It is possible, but difficult to do unless you can read the body and
>>
> > set it aside somewhere. Which again imposes an arbitrary (for the
> > client) limit. Experience shows that this leads to design of clients
> > that work will in developments, but then encounter requests
> > usage/sites/servers that have other limits and break.
>

That's nonsense, of course.  Apache httpd server offers limits on the
number of incoming headers, the number of bytes in those headers, the
number of bytes in the request line, the length of the URI.  The maximum
request body length.  This is just one more limit, but not an actual
*limitation*, because the request will be processed, simply not by changing
protocols first, per RFC7230.

As I'll point out again in closing, h2c isn't defined by RFC7230, and if it
decides to ignore requests with bodies, that's up to mod_http2 and other
implementations.  But RFC7230 has nothing to say to h2c on this, and rather
encourages protocol implementors to accept already-read C-L or T-E: chunked
request bodies in a hand-over into their upgraded protocol.

This is true of other things about HTTP/1.1 too -- how does a client figure
> out what the maximum request size for a server is? -- but it's made harder
> in this case by the fact that
>
> 1) 100 Continue is sent whether the request is upgraded or not, which
> makes it impossible to use a continue handshake to quickly determine
> upgrade limits, and
>

There is no need for the client to determine the upgrade limit, because the
body of the request is sent.  If the server -arbitrarily- chooses to
satisfy it, there will be a 101 following the body transmission.  But the
spec makes absolutely clear that it is the server's prerogative to upgrade
or not, irrespective of the particular upgrade requested.

If the server demands that the upgrade happen, before a request can be
honored, it must reply with a 426 until the client offers to upgrade.  If
the client demands that the upgrade happen, it must perform the simplest
applicable request (e.g. OPTIONS *) with the desired upgrade semantics and
verify that the upgrade occurred.

2) returning 413 during an upgrade would be ambiguous anyway. Is the 413
> really related to the request target, or is it just because I tried to
> upgrade and my request was temporarily limited?
>

It never would.  The possible results are the normal response in http/1.1
protocol, or 426 to tell the client it still must change protocols first.

That new protocol can make whatever demands on the protocol it wants to.
That the only acceptable upgrade to h2c will be an OPTIONS * with no
request body.  Or that POST upgrades will be refused.  Our httpd http/1.1
server doesn't and cannot care, it can read-ahead the same network bucket
it was going to read anyways, and let the new protocol handler decide, very
early or very late in the cycle, whether the upgrade will happen.  If it
won't, httpd must continue to serve the response sticking to http/1.1.

It seems to me that we're missing something in HTTP/1.1 that would make
> these complex Upgrade scenarios robust. IIUC, the point of allowing request
> bodies during upgrades was to decrease the number of round trips, but if
> implementations can't actually make use of it in practice then that's not
> very useful...
>

Define complex, robust.  Request (upgrade: somespec) -> 100 continue ->
request body <- [ http/1.1 response | 101 - switching protocols <- new
protocol response ].

The spec spells it out.  That is as clear as it gets.  One will happen, or
the other.

If it were enough of a problem to fix (and I'm not claiming it is,
> necessarily), how would we fix it? Would we need a new 1xx response (e.g.
> 103 Upgrade Declined, with headers indicating the related protocol and the
> reason for the failure)? A new header in OPTIONS? Something else entirely?
>

I was thinking about this... even within the 100-continue it might be
possible to add some commentary / hint of what might happen next.  Request
and response headers may contain (comments).

Or is the correct "fix" to rearchitect so the limit during upgrades can be
> exactly the same as during a normal request?


RFC7230 is baked, expect no changes.  The request (including 100-continue +
body) is read, the protocol is switched if possible, otherwise the response
is sent in http/1.1.  Those are our constraints.

Is there an advantage to stating no body accepted when we are free to
either upgrade or stay with http/1.1, at our whim? I'd suggest not and will
strongly object to the TLS filter behaving this way. I'll let http/2
protocol gurus argue what happens to that spec, I'm agnostic.

Reply via email to