Subject: Expect/Continue and Removing 1xx Final Status codes from HTTP/2

From: Mark Nottingham <[email-masked]>
Date: Mon, 14 Oct 2013 17:43:30 -0700

At last week's Interim in Seattle, we discussed how we'll handle Expect/Continue in HTTP/2.0.

  https://github.com/http2/http2-spec/issues/18

The plan so far has been to NOT accommodate Expect/Continue on the wire, instead requiring software that receives an Expect header before an HTTP/2.0 hop to synthesise a 100 Continue response.

For example, a 1.1 -> 2.0 intermediary would immediately send a 100 Continue response and forward the request.

Likewise, a 2.0 client API that receives "Expect: 100-continue" in a request header block would synthesise a 100 Continue response and forward the request.

The thinking behind this is that HTTP/2 provides tools that allow the server to avoid wasting bandwidth without sacrificing the connection if it wants to reject the request. To wit, it can send a final response and then reset the stream. Likewise, the client can flow control the tentative request for a RT before utilising full bandwidth, in anticipation of a potential final response rejecting the request.

In addition, we discussed 1xx (non-final) status codes more generally.

  https://github.com/http2/http2-spec/issues/264

The feeling in the room in Seattle AIUI was that non-final status codes are a signalling mechanism that is no longer necessary in HTTP/2, since the framing layer can do a better job at these tasks. As such, we do not plan to accommodate non-final status codes (1xx) in HTTP/2.0, but instead will give advice about how they can be handled by intermediaries doing transitions between 1.x and 2.x (with one example above). 

I have action items to write up detailed proposals for both of these issues. Before that happens, we wanted to make sure a wider audience was aware of this and comfortable with it, since this is a fairly big change. What do people think?

Regards,

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

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 15 Oct 2013 06:45:57 +0200

Hi Mark,

> The plan so far has been to NOT accommodate Expect/Continue on the wire, instead requiring software that receives an Expect header before an HTTP/2.0 hop to synthesise a 100 Continue response.
(...)
> What do people think?

I fully support this for the exact reasons you mentionned.

Best regards,
Willy

---

From: Amos Jeffries <[email-masked]>
Date: Tue, 15 Oct 2013 18:47:04 +1300

> I fully support this for the exact reasons you mentionned.

The proposal is fine from a HTTP/1->HTTP/2 gateway standpoint. But there 
are some issues that need to be clarified before I would be happy 
agreeing to it...

What is the proposal for replacing Upgrade+101 status in HTTP/2 ? Some 
kind of yet to be defined frame?

For Upgrade we have the multiple proxy case.  Where a gateway is not 
able to perform the Upgrade itself, but is capable of switching to an 
opaque tunnel and forwarding bytes to some upstream which *might*. In 
HTTP/1-only world we passed on the request assured that the peer would 
understand it, but in the new world the upstream may not necessarily 
speak HTTP/1.
  So what HTTP/2 feature is to be used to negotiate between two HTTP/2 
peers for converting the stream to an opaque set of DATA and having the 
upstream perform the Upgrade?

What is the proposal for HTTP2->HTTP/1 gateways to save bandwidth where 
Expect:100-continue was previously working?
    Do 2->1 protocol gateways always use Expect:100-continue on the 
HTTP/1 mapping? or are we all expected to be happy with a single HTTP/2 
hop somewhere on the chain resulting in HTTP/1 backend hops being 
flooded with avoidable payload?

I am generally in agreement with the removal of this one provided the 
texts is clear that this is not a *removal* as such, but a replacement 
with native HTTP/2 framing flow control meeting the same need. That will 
help prevent the obvious requests to get it "re-added". But the above 
question still does have to be met or HTTP/2 will be casuing more damage 
than broken HTTP/1 support already is.

Amos

---

From: Michael Sweet <[email-masked]>
Date: Tue, 15 Oct 2013 05:08:41 -0700

Agreed, +1

> I fully support this for the exact reasons you mentionned.

_________________________________________________________
Michael Sweet, Senior Printing System Engineer, PWG Chair

---

From: Mark Nottingham <[email-masked]>
Date: Tue, 22 Oct 2013 16:56:04 +1100

Hi Amos,

On 15/10/2013, at 4:47 PM, Amos Jeffries <[email-masked]> wrote:

> The proposal is fine from a HTTP/1->HTTP/2 gateway standpoint. But there are some issues that need to be clarified before I would be happy agreeing to it...
> 
> What is the proposal for replacing Upgrade+101 status in HTTP/2 ? Some kind of yet to be defined frame?

There will be no replacement on the wire; protocol negotiation is being moved "before" HTTP/2, and so we expect the negotiation mechanisms to be useful for several versions of HTTP.

> For Upgrade we have the multiple proxy case.  Where a gateway

I think you mean "proxy" here

> is not able to perform the Upgrade itself, but is capable of switching to an opaque tunnel and forwarding bytes to some upstream which *might*. In HTTP/1-only world we passed on the request assured that the peer

you mean the upstream proxy?

> would understand it, but in the new world the upstream may not necessarily speak HTTP/1.

Why? For the foreseeable future, it'll need to.

> So what HTTP/2 feature is to be used to negotiate between two HTTP/2 peers for converting the stream to an opaque set of DATA and having the upstream perform the Upgrade?

I think you're making an argument that HTTP/2 needs something like CONNECT, not that we need Upgrade (if I understand correctly). And, maybe doing some endgame planning on how this protocol will work without HTTP/1 generally.

> What is the proposal for HTTP2->HTTP/1 gateways to save bandwidth where Expect:100-continue was previously working?
>   Do 2->1 protocol gateways always use Expect:100-continue on the HTTP/1 mapping? or are we all expected to be happy with a single HTTP/2 hop somewhere on the chain resulting in HTTP/1 backend hops being flooded with avoidable payload?

I'm inclined to specify some heuristics about payload size (where available; it usually is, thanks to most servers requiring C-L) and use of Expect: 100-continue.

> I am generally in agreement with the removal of this one provided the texts is clear that this is not a *removal* as such, but a replacement with native HTTP/2 framing flow control meeting the same need. That will help prevent the obvious requests to get it "re-added". But the above question still does have to be met or HTTP/2 will be casuing more damage than broken HTTP/1 support already is.

Agreed.

Cheers,

---

From: Willy Tarreau <[email-masked]>
Date: Tue, 22 Oct 2013 08:38:47 +0200

Hi Mark,

On Tue, Oct 22, 2013 at 04:56:04PM +1100, Mark Nottingham wrote:
> > are some issues that need to be clarified before I would be happy agreeing
> > to it...
> > 
> There will be no replacement on the wire; protocol negotiation is being moved
> "before" HTTP/2, and so we expect the negotiation mechanisms to be useful for
> several versions of HTTP.

Indeed in my opinion, the intent of 100-continue is more a connection-centric
despite being implemented end-to-end. But the fact that anyone in the middle
can send it proves it's not completely end-to-end. For 101 it's different
though.

> > is not able to perform the Upgrade itself, but is capable of switching to
> > an opaque tunnel and forwarding bytes to some upstream which *might*. In
> > HTTP/1-only world we passed on the request assured that the peer
> 

No I really think Amos was talking about a gateway in front of a proxy.
Put haproxy in front of a squid farm for example, that's something common.
Haproxy will understand the Upgrade+101 and will obey by maintaining an
opaque tunnel between the client and the "server" (haproxy's next hop,
here one of the squid). Haproxy in the middle doesn't need to know the
upper protocol, it just knows that both sides agree on the protocol and
that all they want is to speak in this new language.

> Why? For the foreseeable future, it'll need to.

Indeed I fail to see the problematic case, considering that we don't need
to upgrade from 1.1 to 1.1, so the upgrade will be from 1 to 2, thus we
won't see 100 passing through anymore.

> > So what HTTP/2 feature is to be used to negotiate between two HTTP/2 peers
> > for converting the stream to an opaque set of DATA and having the upstream
> > perform the Upgrade?
> 
> I think you're making an argument that HTTP/2 needs something like CONNECT,
> not that we need Upgrade (if I understand correctly). And, maybe doing some
> endgame planning on how this protocol will work without HTTP/1 generally.
> 
> >   Do 2->1 protocol gateways always use Expect:100-continue on the HTTP/1
> >   mapping? or are we all expected to be happy with a single HTTP/2 hop
> >   somewhere on the chain resulting in HTTP/1 backend hops being flooded
> >   with avoidable payload?
> 
> I'm inclined to specify some heuristics about payload size (where available;
> it usually is, thanks to most servers requiring C-L) and use of Expect:
> 100-continue.

Probably we should consult the browser guys and suggest implementing the
same heuristics they've been using for ages on this.

Willy

---

From: Ilari Liusvaara <[email-masked]>
Date: Tue, 22 Oct 2013 10:18:07 +0300

> There will be no replacement on the wire; protocol negotiation is being moved "before" HTTP/2, and so we expect the negotiation mechanisms to be useful for several versions of HTTP.

What about websockets? Hybi WG has elminated some muxing features
waiting for HTTP/2.0 (or that's at least how I interpretted some comments
there).

Yes, defining "light"[1] version of websockets would be very easy:

- Method is "WEBSOCKETS"
- Sec-Websocket-Key and Sec-Websocket-Accept are not used.
- Upgrade is not performed.
- Masking is not performed nor required.
- Format of DATA frame:
  - First byte of websockets main frame header (type and reserved bits)
  - Everything after main frame header.
  - No padding.

But what other uses of Upgrade: are there (including non-standardized
uses)?

> I think you're making an argument that HTTP/2 needs something like CONNECT, not that we need Upgrade (if I understand correctly). And, maybe doing some endgame planning on how this protocol will wo…

Saying that servers and proxies MAY respond to what looks like HTTP/1.X
request-line by something like:

505 HTTP/1.X not supported HTTP/2.0

And half-closing the connection?

HTTP/1.X request lines are regular, so that shouldn't be that hard
to implement.

> > I am generally in agreement with the removal of this one provided the texts is clear that this is not a *removal* as such, but a replacement with native HTTP/2 framing flow control meeting the sa…

What is the replacement for applications that POST/PUT large streams?
Having to buffer lots of data (I have seen this in one application,
it breaks if dataset is larger than the buffer)?

It gets even worse: The application may not be even aware of HTTP/2.0,
but using HTTP/1.1 proxy, and now the forged 100 breaks it (yes, it
would break if server was 1.0, but who uses 1.0+HTTP-AUTH?).

[1] Restrictions on extensions being:
- No extensions requiring main header changes.
  - Using RSV bits OK.
  - Adding extension header is OK if counted in size field.
- No extensions requiring >16,382 byte frame payloads.

The proposed payload compression extension does meet
those constraints. And one would expect most extensions
do.

-Ilari

---

From: Amos Jeffries <[email-masked]>
Date: Thu, 24 Oct 2013 01:51:33 +1300

> But what other uses of Upgrade: are there (including non-standardized

Yes these were more what I was referring to than CONNECT. Currently the 
HTTP/1.1 proxies can relay such Upgrade to a custom upstream service 
that performs it. The proposal as it stands will remove that ability for 
HTTP/2.

Yes I know it sounds very close to CONNECT behaviour, but it *is* subtly 
different.

The case which I'm recalling is two company POP locations using HTTP 
proxies (Squid at one end at least) to relay traffic over port 80 in 
HTTP form. When the devices in one POP are hardware embeded and report 
in some foreign non-HTTP protocol. The proxy closest to them has a 
separate translator device it relays what appear to be normal HTTP 
requests to and sometimes gets back a mix of HTTP final status or 101 
for the end-to-end response in some gobbledygook. Either way none of the 
regular HTTP proxy can natively translate nor tell whether the 101 is 
the right response to deliver to that particular request and the 
Upgrade: contents can only be generated properly at the client.

I am thinking a mechanism supporting this style of use-case will be 
necessary and could be quite useful for two main reasons:
* non-CONNECT methods allocate safety, idempotency and other handling 
semantics properties to the opaque tunneled data without revealing 
anything in it directly.
* it helps enable the purging of CONNECT from both HTTP/2 and HTTP/1

Amos

---

From: Mark Nottingham <[email-masked]>
Date: Fri, 25 Oct 2013 14:20:10 +1100

On 23 Oct 2013, at 11:51 pm, Amos Jeffries <[email-masked]> wrote:

>> - Method is “WEBSOCKETS"

If we want to do WebSockets over 2.0 (and that’s been discussed many times), the assumption AFAIK has been that iit’ll be a new protocol identifier. A new method would be problematic for many reasons.

> Yes these were more what I was referring to than CONNECT. Currently the HTTP/1.1 proxies can relay such Upgrade to a custom upstream service that performs it. The proposal as it stands will remove that ability for HTTP/2.
> 
> Yes I know it sounds very close to CONNECT behaviour, but it *is* subtly different.
> 
> The case which I'm recalling is two company POP locations using HTTP proxies (Squid at one end at least) to relay traffic over port 80 in HTTP form. When the devices in one POP are hardware embeded and report in some foreign non-HTTP protocol. The proxy closest to them has a separate translator device it relays what appear to be normal HTTP requests to and sometimes gets back a mix of HTTP final status or 101 for the end-to-end response in some gobbledygook. Either way none of the regular HTTP proxy can natively translate nor tell whether the 101 is the right response to deliver to that particular request and the Upgrade: contents can only be generated properly at the client.

This sounds like protocol abuse, or at the very best, a horrible idea. We don’t have to support every pathological use of HTTP (thank goodness).

> I am thinking a mechanism supporting this style of use-case will be necessary and could be quite useful for two main reasons:
> * non-CONNECT methods allocate safety, idempotency and other handling semantics properties to the opaque tunneled data without revealing anything in it directly.