Subject: Re: HTTP/2 extensions and proxies

From: "Nicolas Mailhot" <[email-masked]>
Date: Tue, 1 Oct 2013 10:37:40 +0200

Le Lun 30 septembre 2013 13:34, Amos Jeffries a écrit :
> On 30/09/2013 7:54 p.m., Gábor Molnár wrote:
>> Currently, "Implementations MUST ignore frames of unsupported or
>> unrecognized types.". As far as I see, the point of this is to enable
>> the extension of the protocol in a backwards compatible way.
>>
>> But what about proxies? Should they ignore unrecognized frames too, or
>> should they forward them? If they drop every unknown frame, it is not
>> possible to specify end-to-end extensions. Is this constraint
>> intentional? I think that end-to-end extensions would be useful, too,
>> e.g. WebSockets over HTTP2 if a HTTP2 proxy does not support
>> WebSockets explicitly.
>
> And if they pass all unknown frames it will not be possible to develope
> future hop-by-hop extensions.

However it would be a should at most since if you require a security node
to pass on blindly stuff it does not understand the requirement will just
be ignored.

> I think there needs to be a flag indicating which group the frame
> belongs to

There is definitely a need for frames to specify their actual destination,
and the content of those frames should be protected accordingly (ie enough
shared info other nodes know to whom the frame should be routed, and
evaluate if they want to authorise the routing, but actual content not
shared with every node only by emitter and destination)

-- 
Nicolas Mailhot

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 08:47:14 -0700

It is safer to mark that the unknown frame was passed through a proxy than
to mark things as hop-by-hop and end-to-end.
The former encourages proxies to filter. The latter does not.
-=R

On Mon, Sep 30, 2013 at 4:34 AM, Amos Jeffries <[email-masked]> wrote:

> I think there needs to be a flag indicating which group the frame belongs
> to or splitting the frame type value range into two segments.
> I suggest the uppermost bit of the frame type value be set to 1 on
> end-to-end frames.
>
> Amos
>
>
>

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 08:48:44 -0700

Uh, by that I mean that proxies are unlikely to treat either hop-by-hop or
end-to-end as special if there is no special marking for them, and that
instead marking that a header had been seen leads to better semantics.
-=R

On Tue, Oct 1, 2013 at 8:47 AM, Roberto Peon <[email-masked]> wrote:

> On Mon, Sep 30, 2013 at 4:34 AM, Amos Jeffries <[email-masked]>wrote:
>

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 09:42:12 -0700

> instead marking that a header had been seen leads to better semantics.

To make sure it's clear, what you're suggesting is that rather than
marking a static range of frame types as being "end-to-end" vs
"hop-by-hop" (as I suggested several months ago and Amos reiterated in
this thread), the idea would be for an intermediary to inspect each
frame and decide whether or not it wishes to pass the frame on or not,
and if it does, set a flag saying, essentially, "I passed this on
untouched". Is that accurate?

While I can certainly see advantages to that approach, I'm not clear
on why it allows for "better semantics". Please elaborate. For one,
the marking approach could easily lead to inconsistent handling of
extension frames across implementations and would make it impossible
for specs to define reliable normative handling requirements.

What I suggest is a variation on my original proposal:
https://github.com/http2/http2-spec/issues/95

1. Segment a range of FRAME type codes (0x00-7F) as being
"hop-by-hop", and a range as always end-to-end (0x80-FF), with an
upper segment of each (20 codes from each range) designated as
"private use" codes that cannot be registered in IANA.

2. When an endpoint encounters an unknown/unsupported hop-by-hop frame
on Stream #0, it MUST respond with a PROTOCOL_ERROR.

3. When an endpoint encounters an unknown/unsupported hop-by-hop frame
on a specific stream, it MUST respond with an RST_STREAM

4. When an endpoint encounters an unknown/unsupported end-to-end frame
on Stream #0, it MUST respond with a PROTOCOL_ERROR. (The requirement
is that End-to-End frames are *never* on Stream #0)

5. When an endpoint encounters an unknown/unsupported end-to-end frame
on a specific stream, the endpoint MUST either pass *all* unknown
frames through on that stream, or respond with an RST_STREAM
terminating the stream.

6. All end-to-end frames are subject to flow control.

The idea here is that extension hop-by-hop frames can only be reliably
sent on a connection if both endpoints agree to their use. This limits
the use of hop-by-hop extensions significantly but I don't see that as
being a bad thing.

It further requires that end-to-end frames are ALWAYS sent on a
stream. They are never on Stream #0.

Rule #6 is important because it keeps an intermediary from
accidentally altering the semantics of a stream. For instance, let's
suppose that a client sends a DATA frame, followed by an extension FOO
frame, followed by a final DATA frame. The intermediary has no idea
what the FOO frame is, what it's used for, or why it was sent. With
Roberto's suggested approach, the intermediary would have the option
of simply dropping the FOO frame entirely, while passing the two DATA
frames on unchanged. What the intermediary might not be aware of,
however, is how dropping that FOO frame could completely change the
semantics of the DATA. The better approach is for the intermediary to
make a strict choice of either allowing everything through untouched
(I don't know what this is, but I'm going to let someone else
downstream figure it out) or to reject everything (this stream
contains things I don't understand, so just to be safe I'm going to
reject the entire stream). That's the *only* reliably safe approach.

If it's absolutely necessary for a sender to know in advance how the
peer is going to act when encountering unknown end-to-end frames, then
a new SETTINGS option can be defined, e.g.

  SETTINGS_EXTENSION_REJECT = 0x00 = Pass thru all
  SETTINGS_EXTENSION_REJECT = 0x01 = Reject all

- James

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 11:11:54 -0700

Let me state my preferences in order:
A) The proxy (or server or client) advertises that it allows or disallows
non-standard probably via ALPN/NPN string.
  Endpoints ignore any frame-type they don't understand.

When the proxy has advertised that it uses the standard protocol version:
   No party shall create non-standard frames which, if dropped, would cause
any desynchronization errors.
   Proxies may drop what they see fit.

When the proxy (client/server, whatever) have advertised that it allows
non-standard protocol versions:
   Cients/servers may create non-standard frames.
   Proxies must not not modify any frame they don't understand.

B) Frames which have traversed a proxy are marked as having traversed a
proxy by flipping a bit.
  Endpoints ignore any frame-type they don't understand.
  Endpoints receiving point-to-point frames with this bit flipped must
ignore the frame.
  Proxies need not examine frame contents, except to flip this bit.

C)  Frames are marked with either hop-by-hop or end-to-end.
  Endpoints ignore any frame-type they don't understand.
  Proxies must examine frame contents and remove all hop-by-hop frames.

B or C are potentially helpful, but, in and of themselves don't solve the
fundamental problem:

Assuming that endpoints ignore any frame-type they don't understand (which
seems required without a central registry for extensions and corresponding
increase in handshake time or exponential blowup of ALPN/NPN strings), then
the main problem is really ensuring that nothing bad happens when such
frames are ignored and that, when frames successfully traverse a proxy,
then they will continue to successfully traverse that proxy.
Thus, a means of signaling the intent of the proxy (or server, whatever) to
allow extensions/experiments to traverse (or not) is interesting.

-=R

On Tue, Oct 1, 2013 at 9:42 AM, James M Snell <[email-masked]> wrote:

> belongs

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Oct 2013 12:11:57 -0700

Counterintuitively perhaps, we already have a way to deploy hop-by-hop
extensions. That relies on a chance to the negotiated protocol.

If we need end-to-end extensions, then intermediaries need to ignore, but
pass, unknown stuff. However, I think that we need to allow for
intermediaries that don't want to assume the risks associated with
extensions and allow intermediaries to drop unknown frames, but only if
they drop *all* unknown frames.

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 12:22:55 -0700

On Tue, Oct 1, 2013 at 12:11 PM, Martin Thomson
<[email-masked]> wrote:
>[snip]
> extensions and allow intermediaries to drop unknown frames, but only if they
> drop *all* unknown frames.

-1 .. if the intermediary needs to drop unknown frames, then it needs
to RST_STREAM. Allowing the intermediary to silently drop frames
midstream can lead to potential disaster. Either let everything thru,
or let nothing thru. Period.

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 12:31:28 -0700

Doing a RST_STREAM (which, arguably would be insufficient for the kind of
error that you're talking about) unnecessarily removes the ability to
experiment with hint-like extensions, as I've said a number of times before.

If a proxy hasn't stated that it will not drop frames, then the only
non-standard frames allowed are those which, if dropped, cause no
desynchronization.
As an example, frames that state priority in some new way should be
perfectly safe and allowed. If dropped, no correctness is sacrificed.

-=R

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 12:57:32 -0700

> experiment with hint-like extensions, as I've said a number of times before.

And as I have demonstrated a number of times before, taking the
approach you suggest unnecessarily removes the ability to experiment
with non-hint-like extensions. Given that the intermediary has no way
of knowing what it is dealing with, the safest and only reliable
option is to apply an All or Nothing policy.

The RST_STREAM is more than sufficient for the kind of error I'm
talking about. Specifically, it says, "I received something on this
stream I didn't expect and don't want, so I'm terminating the stream".
I fail to see how that is insufficient.

That said, however, you and I have had this conversation before and I
have no desire to go around on it again. Left only to you and I we
likely would not come to an agreement.

- James

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 13:40:18 -0700

I think you're missing what I'm saying, or I'm not saying it clearly enough.
I'll try to restate.

In mode 1, where the proxy has negotiated "http2" and has NOT negotiated
"experimental-http2"
The proxy MAY remove frames it does not understand.
Endpoints MUST NOT emit frames which, if removed, would desynchronize state.
A proxy which exists for security reasons would likely chose this mode.

In mode 2, where the proxy HAS negotiated "experimental-http2",
The proxy MUST NOT remove unknown frames*.
Endpoints MAY emit frames which, if removed, would desynchronize state.
A proxy which exists for performance reasons might chose this mode.
This mode allows for arbitrary experimentation, including state-m

*Perhaps there is a point-to-point or end-to-end bit or whatever, but if
so, that is in addition to the above, and cannot supplant it.

Neither end-to-end nor point-to-point signifies that removal would cause
state desynchronization, and in the end, this is what we care about.
-=R

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 14:44:29 -0700

> I think you're missing what I'm saying, or I'm not saying it clearly enough.

I'm very clear about what you're suggesting...

> This mode allows for arbitrary experimentation, including state-m

What I'm saying is that these "modes" would apply only to hop-by-hop
frames that affect connection state. For end-to-end frames sent on a
stream, however, it ought to be possible to send them in either mode
with the All or Nothing semantics I've described.

- James

> *Perhaps there is a point-to-point or end-to-end bit or whatever, but if so,
> that is in addition to the above, and cannot supplant it.
>

---

From: Roberto Peon <[email-masked]>
Date: Tue, 1 Oct 2013 14:55:49 -0700

By 'All or Nothing', do you mean 'proxy drops all unknown' or 'proxy never
drops unknown', or is it some other meaning?
-=R

On Tue, Oct 1, 2013 at 2:44 PM, James M Snell <[email-masked]> wrote:

> so,
> >> >> > If we need end-to-end extensions, then intermediaries need to
> ignore,
> >> >> > but
> >> >> > extensions and allow intermediaries to drop unknown frames, but
> only
> >> >> > if
> >> >> > they

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 16:34:01 -0700

I mean that when the proxy encounters unknown end to end frames on a
stream, it chooses to either allow them thru, or closes the stream.
On Oct 1, 2013 2:55 PM, "Roberto Peon" <[email-masked]> wrote:

>> >> > Doing a RST_STREAM (which, arguably would be insufficient for the
>> kind
>> >> > of

---

From: Amos Jeffries <[email-masked]>
Date: Wed, 02 Oct 2013 13:59:17 +1300

On 2/10/2013 7:11 a.m., Roberto Peon wrote:
> A) The proxy (or server or client) advertises that it allows or 
> disallows non-standard probably via ALPN/NPN string.
>    No party shall create non-standard frames which, if dropped, would 
> cause any desynchronization errors.
> When the proxy (client/server, whatever) have advertised that it 
> allows non-standard protocol versions:

As an implementer looking at the above there is no reason for me to 
write code that only advertises the standard version without extensions. 
If I did there would very shortly be a customer request to add something 
so I may as well solve a lot of pain and potential customer loss just 
advertising the extension support.

Which brings to the problem with this one...  extensions are rarely 
packed in nice protocol name bunches. Most of the extensions to HTTP/1 
have been single headers tacked on one at a time. Do you plan to have 
ALPN/NPN listing all the individual non-standard headers supported for 
each hop? That is what is waiting at the end of this slippery slope.

>
> B) Frames which have traversed a proxy are marked as having traversed 
> a proxy by flipping a bit.

When there are two proxies involved and only the second one understands 
the frame type. What happens?
  - at best a waste of bandwidth and CPU passing the frame along. 
Because as a hop-by-hop the second proxy knows enough to identify that 
it was not supposed to be received. In the same way responsible HTTP/1.1 
proxies deal with Expect: emitted by HTTP/1.0 hops today.

What if the frame type was somebodies equivalent of Expect: or Keep-Alive: ?

What types of proxy are expected to flip bits? not all proxies are equal 
even today. Some just take the traffic stream and relay it to an 
upstream (think load balancers, request/stream routers, tunnels, etc). 
How do these middleware types identify whether they are to flip the bit, 
ignore the bit, or drop the frame?

  (C) solves all these issues by making them irrelevant with a single 
rule that applies to all endpoints. There is no restriction that frames 
with what we are calling the end-to-end bit are actually end-to-end, 
just that they are treated as if they were by hops that dont understand 
them.

>   Proxies must examine frame contents and remove all hop-by-hop frames.

Strawman here with "examine frame contents" ... "examine frame type" is 
the proposal. When the marker is in the type code itself, as proposed, 
they have to do that examining anyway to figure out whether the frame is 
supported or not. There is *zero* additional work required, and this can 
also be implemented on a read-only buffer.

Also, and this affects all the proposals so far;
    what happens when a frame has minor corruption in the type field 
value making it "unknown type"?

Amos

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Oct 2013 21:08:37 -0700

On 1 October 2013 12:22, James M Snell <[email-masked]> wrote:
> Either let everything thru,

That's exactly what I said, isn't it?

---

From: James M Snell <[email-masked]>
Date: Tue, 1 Oct 2013 21:16:28 -0700

Variation on it. From what I saw, you said:

"If we need end-to-end extensions, then intermediaries need to ignore,
but pass, unknown stuff. However, I think that we need to allow for
intermediaries that don't want to assume the risks associated with
extensions and allow intermediaries to drop unknown frames, but only
if they drop *all* unknown frames."

The language in this I don't like is "drop unknown frames". It's not
clear what "drop" means.

What I'm saying is, you either pass the unknown end-to-end frames
through or send an RST_STREAM... meaning, if you encounter an unknown
frame on a stream and you don't intend to pass it through, you drop
the entire stream, and not just that frame.

- James

---

From: Martin Thomson <[email-masked]>
Date: Tue, 1 Oct 2013 21:34:00 -0700

> the entire stream, and not just that frame.

Maybe.  That seems like a pretty harsh way to discourage use of
extensions.  It does allow for the discovery of an extension-blocking
intermediary, but maybe there are better ways to expose that
information than RST_STREAM.  (You need a new RST_STREAM code for
this, certainly.)

---

From: Mike Bishop <[email-masked]>
Date: Wed, 2 Oct 2013 17:20:18 +0000

ALPN identifiers are a non-starter -- it would make the list of identifiers explode.  If I support extensions A, B, and C then I have to advertise support for:

*       H2

*       H2+ExtA

*       H2+ExtB

*       H2+ExtC

*       H2+ExtA+ExtB

*       H2+ExtA+ExtC

*       H2+ExtB+ExtC

*       H2+ExtA+ExtB+ExtC

...and the number grows exponentially as more extensions exist.  Plus doubled, with Gabriel & Roberto's draft on H2 vs. H2c.

Limiting extensions to things that can be ignored really bounds what they're able to do.  It seems more likely we'd need to advertise support for extensions through SETTINGS or a new negotiation frame type, and only send the extension frames if the negotiation succeeded.  There still needs to be a way for an extension to be identified end-to-end or hop-by-hop even if you don't understand it, so that an intermediary which doesn't know about a given extension can know authoritatively whether it should still negotiate it and pass it through, or not negotiate it.

-----Original Message-----
From: Amos Jeffries [mailto:[email-masked]]
Sent: Tuesday, October 1, 2013 5:59 PM
To: Roberto Peon
Cc: James M Snell; HTTP Working Group
Subject: Re: HTTP/2 extensions and proxies

>    Proxies must not not modify any frame they don't understand.

As an implementer looking at the above there is no reason for me to write code that only advertises the standard version without extensions.

If I did there would very shortly be a customer request to add something so I may as well solve a lot of pain and potential customer loss just advertising the extension support.

Which brings to the problem with this one...  extensions are rarely packed in nice protocol name bunches. Most of the extensions to HTTP/1 have been single headers tacked on one at a time. Do you plan to have ALPN/NPN listing all the individual non-standard headers supported for each hop? That is what is waiting at the end of this slippery slope.

When there are two proxies involved and only the second one understands the frame type. What happens?

Because as a hop-by-hop the second proxy knows enough to identify that it was not supposed to be received. In the same way responsible HTTP/1.1 proxies deal with Expect: emitted by HTTP/1.0 hops today.

What types of proxy are expected to flip bits? not all proxies are equal even today. Some just take the traffic stream and relay it to an upstream (think load balancers, request/stream routers, tunnels, etc).

How do these middleware types identify whether they are to flip the bit, ignore the bit, or drop the frame?

  (C) solves all these issues by making them irrelevant with a single rule that applies to all endpoints. There is no restriction that frames with what we are calling the end-to-end bit are actually end-to-end, just that they are treated as if they were by hops that dont understand them.

>   Proxies must examine frame contents and remove all hop-by-hop frames.

Strawman here with "examine frame contents" ... "examine frame type" is the proposal. When the marker is in the type code itself, as proposed, they have to do that examining anyway to figure out whether the frame is supported or not. There is *zero* additional work required, and this can also be implemented on a read-only buffer.

    what happens when a frame has minor corruption in the type field value making it "unknown type"?

Amos

---

From: Roberto Peon <[email-masked]>
Date: Wed, 2 Oct 2013 10:30:49 -0700

The idea isn't to list every extension, but rather to only have 'h2' and
'e-h2'.
We reduce this more by asserting that any endpoint sending 'e-h2' must be
able to recieve 'h2', and that any endpoint receiving 'e-h2' MUST be able
to reply with 'h2' (i.e 'e-h2' implies 'h2')

You are right that, if every extension was put in there, there would be an
exponential explosion. That would be silly.
Unfortunately "MUST NOT be silly", is apparently a difficult directive to
follow (as my wife can tell you), and better language, if possible is
useful. :)

The primary design-space constraint is that there should be zero addtional
RTTs of overhead for negotiating this stuff. That implies NPN/ALPN. Taking
another RTT for negotiation is likely a non-starter-- the cost in latency
is likely to exceed the benefit of the negotiation.
Not sticking this in NPN/ALPN suffers from potentially the same exponential
size explosion if a similar formatting is used.
-=R

On Wed, Oct 2, 2013 at 10:20 AM, Mike Bishop
<[email-masked]>wrote:

>  ALPN identifiers are a non-starter -- it would make the list of
> identifiers explode.  If I support extensions A, B, and C then I have to
> advertise support for:****
>
> **·       **H2****
>
> **·       **H2+ExtA****
>
> **·       **H2+ExtB****
>
> **·       **H2+ExtC****
>
> **·       **H2+ExtA+ExtB****
>
> **·       **H2+ExtA+ExtC****
>
> **·       **H2+ExtB+ExtC****
>
> **·       **H2+ExtA+ExtB+ExtC****
>
> ...and the number grows exponentially as more extensions exist.  Plus
> doubled, with Gabriel & Roberto’s draft on H2 vs. H2c.****
>
> ** **
>
> Limiting extensions to things that can be ignored really bounds what
> they’re able to do.  It seems more likely we’d need to advertise support
> for extensions through SETTINGS or a new negotiation frame type, and only
> send the extension frames if the negotiation succeeded.  There still needs
> to be a way for an extension to be identified end-to-end or hop-by-hop even
> if you don’t understand it, so that an intermediary which doesn’t know
> about a given extension can know authoritatively whether it should still
> negotiate it and pass it through, or not negotiate it.****
>
> ** **
>
> ** **
> On 2/10/2013 7:11 a.m., Roberto Peon wrote:****
>
> > Let me state my preferences in order:****
>
> > A) The proxy (or server or client) advertises that it allows or ****
>
> > disallows non-standard probably via ALPN/NPN string.****
>
> >   Endpoints ignore any frame-type they don't understand.****
>
> >** **
>
> ****
> >    No party shall create non-standard frames which, if dropped, would **
> **
>
> > cause any desynchronization errors.****
>
> >    Proxies may drop what they see fit.****
>
> >** **
>
> > When the proxy (client/server, whatever) have advertised that it ****
>
> > allows non-standard protocol versions:****
>
> >    Cients/servers may create non-standard frames.****
>
> >    Proxies must not not modify any frame they don't understand.****
>
> ** **
>
> ** **
>
> As an implementer looking at the above there is no reason for me to write
> code that only advertises the standard version without extensions. ****
>
> advertising the extension support.****
>
> ** **
>
> Which brings to the problem with this one...  extensions are rarely packed
> in nice protocol name bunches. Most of the extensions to HTTP/1 have been
> single headers tacked on one at a time. Do you plan to have ALPN/NPN
> listing all the individual non-standard headers supported for each hop?
> That is what is waiting at the end of this slippery slope.****
>
> ** **
>
> ** **
>
> >** **
>
> > B) Frames which have traversed a proxy are marked as having traversed **
> **
>
> > a proxy by flipping a bit.****
>
> >   Endpoints ignore any frame-type they don't understand.****
>
> >   Endpoints receiving point-to-point frames with this bit flipped must *
> ***
>
> > ignore the frame.****
>
> >   Proxies need not examine frame contents, except to flip this bit.****
>
> >** **
>
> ** **
>
> the frame type. What happens?****
>
>   - at best a waste of bandwidth and CPU passing the frame along. ****
>
> Because as a hop-by-hop the second proxy knows enough to identify that it
> was not supposed to be received. In the same way responsible HTTP/1.1
> proxies deal with Expect: emitted by HTTP/1.0 hops today.****
>
> ** **
>
> What if the frame type was somebodies equivalent of Expect: or Keep-Alive:
> ?****
>
> ** **
>
> even today. Some just take the traffic stream and relay it to an upstream
> (think load balancers, request/stream routers, tunnels, etc). ****
>
> ignore the bit, or drop the frame?****
>
> ** **
>
>   (C) solves all these issues by making them irrelevant with a single rule
> that applies to all endpoints. There is no restriction that frames with
> what we are calling the end-to-end bit are actually end-to-end, just that
> they are treated as if they were by hops that dont understand them.****
>
> ** **
>
> ** **
>
> > C)  Frames are marked with either hop-by-hop or end-to-end.****
>
> >   Endpoints ignore any frame-type they don't understand.****
>
> >   Proxies must examine frame contents and remove all hop-by-hop frames.*
> ***
>
> ** **
>
> the proposal. When the marker is in the type code itself, as proposed, they
> have to do that examining anyway to figure out whether the frame is
> also be implemented on a read-only buffer.****
>
> ** **
>
> ** **
>
> Also, and this affects all the proposals so far;****
>
>     what happens when a frame has minor corruption in the type field value
> making it "unknown type"?****
>
> ** **
>
> Amos****
>
> ** **
>

---

From: Eliot Lear <[email-masked]>
Date: Wed, 02 Oct 2013 19:33:07 +0200

Why not just define an optional capabilities exchange mechanism on
Channel 0?

Eliot

On 10/2/13 7:20 PM, Mike Bishop wrote:
> identifiers explode.  If I support extensions A, B, and C then I have
> to advertise support for:
>
> ·       H2
>
> ·       H2+ExtA
>
> ·       H2+ExtB
>
> ·       H2+ExtC
>
> ·       H2+ExtA+ExtB
>
> ·       H2+ExtA+ExtC
>
> ·       H2+ExtB+ExtC
>
> ·       H2+ExtA+ExtB+ExtC
>
> doubled, with Gabriel & Roberto’s draft on H2 vs. H2c.
>
>  
>
> they’re able to do.  It seems more likely we’d need to advertise
> support for extensions through SETTINGS or a new negotiation frame
> type, and only send the extension frames if the negotiation
> succeeded.  There still needs to be a way for an extension to be
> identified end-to-end or hop-by-hop even if you don’t understand it,
> so that an intermediary which doesn’t know about a given extension can
> know authoritatively whether it should still negotiate it and pass it
> through, or not negotiate it.
>
>  
>
> If I did there would very shortly be a customer request to add
> something so I may as well solve a lot of pain and potential customer
> loss just advertising the extension support.
>
>  
>
> When there are two proxies involved and only the second one
> understands the frame type. What happens?
>
> it was not supposed to be received. In the same way responsible
> HTTP/1.1 proxies deal with Expect: emitted by HTTP/1.0 hops today.
>
>  
>
> What types of proxy are expected to flip bits? not all proxies are
> equal even today. Some just take the traffic stream and relay it to an
> rule that applies to all endpoints. There is no restriction that
> frames with what we are calling the end-to-end bit are actually
> end-to-end, just that they are treated as if they were by hops that
> dont understand them.
>
>  
>
>  
>
> Strawman here with "examine frame contents" ... "examine frame type"
> is the proposal. When the marker is in the type code itself, as
> proposed, they have to do that examining anyway to figure out whether
> the frame is supported or not. There is *zero* additional work
> required, and this can also be implemented on a read-only buffer.
>
>  
>
>  
>

---

From: James M Snell <[email-masked]>
Date: Wed, 2 Oct 2013 10:37:19 -0700

+1...

This discussion needs to be split into two distinct elements:

1. Identification of hop-by-hop vs. end-to-end frames.

2. Handling of unknown frame types.

For 1, I believe the suggestion that I made originally (that was
reiterated in this thread) is appropriate. Specifically, We designate
the highest order bit in the type value as the "end-to-end" bit. (if
set, the frame type is end-to-end). Additional constraints ought to
include: (a) end-to-end frames MUST be sent on a stream and (b)
end-to-end frames MUST be subject to flow control.

For 2, I believe the handling I've already described is the most
appropriate. Allowing an intermediary to blindly remove individual
unknown frames from a stream is very dangerous, especially if the
intermediary has no idea why those frames exist.

- James

On Wed, Oct 2, 2013 at 10:20 AM, Mike Bishop
<[email-masked]> wrote:
> ALPN identifiers are a non-starter -- it would make the list of identifiers
> explode.  If I support extensions A, B, and C then I have to advertise
> support for:
>
> ·       H2
>
> ·       H2+ExtA
>
> ·       H2+ExtB
>
> ·       H2+ExtC
>
> ·       H2+ExtA+ExtB
>
> ·       H2+ExtA+ExtC
>
> ·       H2+ExtB+ExtC
>
> ·       H2+ExtA+ExtB+ExtC
>
> Limiting extensions to things that can be ignored really bounds what they’re
> able to do.  It seems more likely we’d need to advertise support for
> extensions through SETTINGS or a new negotiation frame type, and only send
> the extension frames if the negotiation succeeded.  There still needs to be
> a way for an extension to be identified end-to-end or hop-by-hop even if you
> don’t understand it, so that an intermediary which doesn’t know about a
> given extension can know authoritatively whether it should still negotiate
> it and pass it through, or not negotiate it.
>
>
>
> code that only advertises the standard version without extensions.
>
> If I did there would very shortly be a customer request to add something so
> I may as well solve a lot of pain and potential customer loss just
> single headers tacked on one at a time. Do you plan to have ALPN/NPN listing
> all the individual non-standard headers supported for each hop? That is what
> is waiting at the end of this slippery slope.
>
>
>
>
>
>>
>
> (think load balancers, request/stream routers, tunnels, etc).
>
> that applies to all endpoints. There is no restriction that frames with what
> we are calling the end-to-end bit are actually end-to-end, just that they
> are treated as if they were by hops that dont understand them.
>
>
>
>
>
> Strawman here with "examine frame contents" ... "examine frame type" is the
> proposal. When the marker is in the type code itself, as proposed, they have
> to do that examining anyway to figure out whether the frame is supported or
> not. There is *zero* additional work required, and this can also be
> implemented on a read-only buffer.
>
>
>
>
>
> making it "unknown type"?
>
>
>
> Amos
>
>

---

From: Eliot Lear <[email-masked]>
Date: Wed, 02 Oct 2013 20:02:19 +0200

> Why not just define an optional capabilities exchange mechanism on

Having seen Roberto's design constraint, nevermind.

---

From: Mike Bishop <[email-masked]>
Date: Wed, 2 Oct 2013 20:33:02 +0000

Which still might be a valid option, even if as Roberto points out it's not the ideal area of the solution space.  Similar to Upgrade, the first request(s) is/are made using vanilla HTTP plus any non-breaking extensions.  After one RTT, you know which breaking extensions are safe to use.

Sent from Windows Mail

From: Eliot Lear<mailto:[email-masked]>
Sent: ?Wednesday?, ?October? ?2?, ?2013 ?11?:?02? ?AM
To: Eliot Lear<mailto:[email-masked]>
Cc: Mike Bishop<mailto:[email-masked]>, Amos Jeffries<mailto:[email-masked]>, Roberto Peon<mailto:[email-masked]>, James M Snell<mailto:[email-masked]>, [email-masked]<mailto:[email-masked]>

On 10/2/13 7:33 PM, Eliot Lear wrote:
Why not just define an optional capabilities exchange mechanism on Channel 0?

---

From: Amos Jeffries <[email-masked]>
Date: Thu, 03 Oct 2013 22:34:54 +1300

> intermediary has no idea why those frames exist.

For those objecting, in addition to the above. Keep in mind that "end" 
has a flexible definition.

A proxy MAY generate or remove an end-to-end frame IF (and _only_ if) is 
fully supports the frames feature and has full understanding of the 
consequences of doing so.

For example DATA frames are end-to-end yet a proxy MAY erase some 
received by buffering and aggregating the payloads into larger DATA 
frames sent.

And alternative way of thinking about it is a drop-by-default / 
pass-by-default bit embeded in the frame type code. No fancy behaviour 
necessary, just obey the flag if specific rules are unknown.

Amos

> On Wed, Oct 2, 2013 at 10:20 AM, Mike Bishop wrote: