HTTP/2 and Websockets

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
82 messages Options
12345
Reply | Threaded
Open this post in threaded view
|

HTTP/2 and Websockets

Robert Collins
Has anyone done any specification on integrating websockets into
HTTP/2? I couldn't find a spec, so I poked around a bit...

It looks to me like there are three issues.

Firstly we should define the handshake in terms of a stream opening on
an existing HTTP/2 connection, and since Upgrade: is not permitted in
HTTP/2 ("
Note:HTTP/2 purposefully does not support upgrade to another protocol.
The handshake methods described in Section 3 are believed sufficient
to negotiate the use of alternative protocols.
")

its not clear to me if that means we need to define a new frame type,
or whether we can still use the Upgrade header sanely.


Secondly, we need to define websocket frame mappings. The least work,
and I suspect the easiest for implementors, would be to put all the
websocket frames into HTTP/2's data frames, without worrying about
frame alignment: just treat the fully open stream as a series of bytes
in the same way TCP is treated by the websocket spec.
I suspect however that a better result would be achieved by defining
custom HTTP/2 frames, since websockets already have the basic support
for multiplexing (large application writes can be fragmented into
smaller frames as needed), we shouldn't run into HOL blocking issues.

Lastly, it seems (to me) that it would be desirable to allow
PUSH_PROMISE setup of websockets connections, but the PUSH_PROMISE
state machine goes straight into half-closed, rather than into 'open',
and that prohibits doing websockets with a pushed connection. There
isn't any prose in HTTP/2 about /why/ the state machine does that :(.

-Rob

--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
Hi,

Since many modifications were made on on the HTTP/2 spec, some description may be obsolete. Please let me know if you find any flaw.

Firstly we should define the handshake in terms of a stream opening on
an existing HTTP/2 connection, and since Upgrade: is not permitted in
HTTP/2 ("
Note:HTTP/2 purposefully does not support upgrade to another protocol.
The handshake methods described in Section 3 are believed sufficient
to negotiate the use of alternative protocols.
")
its not clear to me if that means we need to define a new frame type,
or whether we can still use the Upgrade header sanely.
The above draft describes the negotiation scheme. Please take a look.

Secondly, we need to define websocket frame mappings. The least work,
and I suspect the easiest for implementors, would be to put all the
websocket frames into HTTP/2's data frames, without worrying about
frame alignment: just treat the fully open stream as a series of bytes
in the same way TCP is treated by the websocket spec.
I suspect however that a better result would be achieved by defining
custom HTTP/2 frames, since websockets already have the basic support
for multiplexing (large application writes can be fragmented into
smaller frames as needed), we shouldn't run into HOL blocking issues.
Yeah, we can't simply use DATA frames because intermediaries may buffer data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it was removed from the spec. Currently I think introducing a new frame type is the right way.
 
Lastly, it seems (to me) that it would be desirable to allow
PUSH_PROMISE setup of websockets connections
Can you tell me why it is desirable?

Thanks,


On Mon, Sep 29, 2014 at 12:10 PM, Robert Collins <[hidden email]> wrote:
Has anyone done any specification on integrating websockets into
HTTP/2? I couldn't find a spec, so I poked around a bit...

It looks to me like there are three issues.

Firstly we should define the handshake in terms of a stream opening on
an existing HTTP/2 connection, and since Upgrade: is not permitted in
HTTP/2 ("
Note:HTTP/2 purposefully does not support upgrade to another protocol.
The handshake methods described in Section 3 are believed sufficient
to negotiate the use of alternative protocols.
")

its not clear to me if that means we need to define a new frame type,
or whether we can still use the Upgrade header sanely.


Secondly, we need to define websocket frame mappings. The least work,
and I suspect the easiest for implementors, would be to put all the
websocket frames into HTTP/2's data frames, without worrying about
frame alignment: just treat the fully open stream as a series of bytes
in the same way TCP is treated by the websocket spec.
I suspect however that a better result would be achieved by defining
custom HTTP/2 frames, since websockets already have the basic support
for multiplexing (large application writes can be fragmented into
smaller frames as needed), we shouldn't run into HOL blocking issues.

Lastly, it seems (to me) that it would be desirable to allow
PUSH_PROMISE setup of websockets connections, but the PUSH_PROMISE
state machine goes straight into half-closed, rather than into 'open',
and that prohibits doing websockets with a pushed connection. There
isn't any prose in HTTP/2 about /why/ the state machine does that :(.

-Rob

--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud


Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Ilari Liusvaara
On Mon, Sep 29, 2014 at 02:26:34PM +0900, Yutaka Hirano wrote:
> Hi,
>
> I am proposing a spec draft:
> http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01 .
> Since many modifications were made on on the HTTP/2 spec, some description
> may be obsolete. Please let me know if you find any flaw.

The capability negotiation looks weird.

I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
the rest reserved for extension) from server (or from proxy towards
client).

After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
proxy knows the proxy/server can handle websockets (and is used via
:scheme 'ws'/'wss'). No need to ACK anything.

In the future, some more elaborate extensions might need to be enabled
from both sides, but be base functionality doesn't. Only features that
change existing semantics need to be acknowledged.

One example of something to signal from client to proxy/server would
be reverse connections (but this needs some way for proxies and browsers
to route the connection, maybe associated stream ID, and PUSH_PROMISE
can't be used due to its unidirectionality[1]).

Reverse connections can't be mapped to RFC 6455, so those would need
HTTP/2 path all the way between client and server.

> Yeah, we can't simply use DATA frames because intermediaries may buffer
> data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it
> was removed from the spec. Currently I think introducing a new frame type
> is the right way.

One way would be to take the base Websockets spec for data communications
and rip out everything unneeded and adapt some things:

- Server's/proxy(toward client) SETTINGS has notification about Websockets
  support.
- Client's opening handshake has no upgrade headers (upgrade or connection:
  upgrade). Instead it has :scheme set to either 'ws' or 'wss'.
- Client's opening handshake has :authority instead of host.
- Client's opening handshake has no Sec-websocket-key
- Server's opening handshake has 200 status instead of 101.
- Server's opening handshake has no Sec-websocket-accept
- Each DATA frame carries one websocket frame.
- FIN, RSVx and opcode are signaled as the first byte of DATA frame.
- There is no masking, and MASK is implcitly 0.
- Frame length is implicitly data frame length - 1.
- Zero-byte data frames are not valid.
- Proxies fragment or coalesce if needed (TODO: How to handle 16kB
  and up control frames?)
- Proxies can perform adaptation between RFC 6455 and Websockets over
  HTTP/2.
- No TLS handshakes are done (TLS is below HTTP/2).
- TCP connection is replaced by HTTP/2 stream.

This requires some support on proxies (e.g. priority boosting and
fragmenting), but proxies should know what they are dealing with,
and Websockets needs proxy support anyway (at least unless one does not
want to burn through sequence numbers really fast and to cause excessive
load on proxies).

Also, extensions that modify base header semantics (as opposed to just
using RSVx bits or adding their own header included in frame size)
don't work, but I think that is not a big problem. PMCE is OK.


[1] I earlier sent list of ideas for decoupling framing and HTTP layers,
PUSH_PROMISE is unidirectional even in that (that's the difference
between PUSH_PROMISE and HEADERS!).


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
Thank you for the comments!

We have been not working actively for months because of two reasons:
1) The http/2 spec was changing rapidly and we couldn't write a spec on top of it.
2) We weren't confident if wide range of people were interested in this protocol.

1) will be resolved soon, I hope. For 2), If you are interested in WebSocket over HTTP/2, it is very helpful to express it!
About one year ago, we were talking if we wanted perfect RFC6455 compatible WebSocket or not (i.e. full-extension support). IIRC most of us didn't want the full RFC6455 compatibility, but if you have any opinion, it is welcome.
In short, we would like to hear your voice.

I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
the rest reserved for extension) from server (or from proxy towards
client).
After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
proxy knows the proxy/server can handle websockets (and is used via
:scheme 'ws'/'wss'). No need to ACK anything.
My proposal doesn't need ACK.
The client sends a SETTINGS frame before sending the first handshake in the stream. After that, the client starts the usual WebSocket opening handshake.

One way would be to take the base Websockets spec for data communications
and rip out everything unneeded and adapt some things:
- Server's/proxy(toward client) SETTINGS has notification about Websockets
  support.
- Client's opening handshake has no upgrade headers (upgrade or connection:
  upgrade). Instead it has :scheme set to either 'ws' or 'wss'.
- Client's opening handshake has :authority instead of host.
- Client's opening handshake has no Sec-websocket-key
- Server's opening handshake has 200 status instead of 101.
- Server's opening handshake has no Sec-websocket-accept
- Each DATA frame carries one websocket frame.
- FIN, RSVx and opcode are signaled as the first byte of DATA frame.
- There is no masking, and MASK is implcitly 0.
- Frame length is implicitly data frame length - 1.
- Zero-byte data frames are not valid.
- Proxies fragment or coalesce if needed (TODO: How to handle 16kB
  and up control frames?)
- Proxies can perform adaptation between RFC 6455 and Websockets over
  HTTP/2.
- No TLS handshakes are done (TLS is below HTTP/2).
- TCP connection is replaced by HTTP/2 stream.
 
Given that we have SETTINGS_WEBSOCKET_CAPABLE, I would use a new frame type not to confuse intermediaries / endpoints. The actual data format will be discussed, but IMHO it is less important and can be discussed later.

Thanks,

On Mon, Sep 29, 2014 at 6:51 PM, Ilari Liusvaara <[hidden email]> wrote:
On Mon, Sep 29, 2014 at 02:26:34PM +0900, Yutaka Hirano wrote:
> Hi,
>
> I am proposing a spec draft:
> http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01 .
> Since many modifications were made on on the HTTP/2 spec, some description
> may be obsolete. Please let me know if you find any flaw.

The capability negotiation looks weird.

I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
the rest reserved for extension) from server (or from proxy towards
client).

After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
proxy knows the proxy/server can handle websockets (and is used via
:scheme 'ws'/'wss'). No need to ACK anything.

In the future, some more elaborate extensions might need to be enabled
from both sides, but be base functionality doesn't. Only features that
change existing semantics need to be acknowledged.

One example of something to signal from client to proxy/server would
be reverse connections (but this needs some way for proxies and browsers
to route the connection, maybe associated stream ID, and PUSH_PROMISE
can't be used due to its unidirectionality[1]).

Reverse connections can't be mapped to RFC 6455, so those would need
HTTP/2 path all the way between client and server.

> Yeah, we can't simply use DATA frames because intermediaries may buffer
> data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it
> was removed from the spec. Currently I think introducing a new frame type
> is the right way.

One way would be to take the base Websockets spec for data communications
and rip out everything unneeded and adapt some things:

- Server's/proxy(toward client) SETTINGS has notification about Websockets
  support.
- Client's opening handshake has no upgrade headers (upgrade or connection:
  upgrade). Instead it has :scheme set to either 'ws' or 'wss'.
- Client's opening handshake has :authority instead of host.
- Client's opening handshake has no Sec-websocket-key
- Server's opening handshake has 200 status instead of 101.
- Server's opening handshake has no Sec-websocket-accept
- Each DATA frame carries one websocket frame.
- FIN, RSVx and opcode are signaled as the first byte of DATA frame.
- There is no masking, and MASK is implcitly 0.
- Frame length is implicitly data frame length - 1.
- Zero-byte data frames are not valid.
- Proxies fragment or coalesce if needed (TODO: How to handle 16kB
  and up control frames?)
- Proxies can perform adaptation between RFC 6455 and Websockets over
  HTTP/2.
- No TLS handshakes are done (TLS is below HTTP/2).
- TCP connection is replaced by HTTP/2 stream.

This requires some support on proxies (e.g. priority boosting and
fragmenting), but proxies should know what they are dealing with,
and Websockets needs proxy support anyway (at least unless one does not
want to burn through sequence numbers really fast and to cause excessive
load on proxies).

Also, extensions that modify base header semantics (as opposed to just
using RSVx bits or adding their own header included in frame size)
don't work, but I think that is not a big problem. PMCE is OK.


[1] I earlier sent list of ideas for decoupling framing and HTTP layers,
PUSH_PROMISE is unidirectional even in that (that's the difference
between PUSH_PROMISE and HEADERS!).


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Greg Wilkins-3
I think this is a timely subject as I believe it is very important to take Yutaka's ideas forward to a working extension sooner rather than later.

My fear is that unless we test websocket over HTTP/2 before we go final, we may discover some fatal flaw that prevents efficient handling of websocket as a h2 stream.

Even if there are no nasties discovered, not having an extension defined at the start will mean that a lot of h2 infrastructure will get deployed without websocket support.  Once this occurs, it may be very difficult to get good websocket coverage for some time with an extension approach.   I fear that the response will be to come up with a websocket mapping that abuses the h2 protocol so that it can tunnel through websocket unaware intermediaries... and that is unlikely to be efficient because we have dropped end_segment semantics from h2 streams.

Cheers

PS. My real preference is that this group get's recharted to support both http and websocket semantics over h2 - and we go back to the drawing board with the framing layer using >1 examples to generalise from.



On 29 September 2014 21:36, Yutaka Hirano <[hidden email]> wrote:
Thank you for the comments!

We have been not working actively for months because of two reasons:
1) The http/2 spec was changing rapidly and we couldn't write a spec on top of it.
2) We weren't confident if wide range of people were interested in this protocol.

1) will be resolved soon, I hope. For 2), If you are interested in WebSocket over HTTP/2, it is very helpful to express it!
About one year ago, we were talking if we wanted perfect RFC6455 compatible WebSocket or not (i.e. full-extension support). IIRC most of us didn't want the full RFC6455 compatibility, but if you have any opinion, it is welcome.
In short, we would like to hear your voice.

I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
the rest reserved for extension) from server (or from proxy towards
client).
After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
proxy knows the proxy/server can handle websockets (and is used via
:scheme 'ws'/'wss'). No need to ACK anything.
My proposal doesn't need ACK.
The client sends a SETTINGS frame before sending the first handshake in the stream. After that, the client starts the usual WebSocket opening handshake.

One way would be to take the base Websockets spec for data communications
and rip out everything unneeded and adapt some things:
- Server's/proxy(toward client) SETTINGS has notification about Websockets
  support.
- Client's opening handshake has no upgrade headers (upgrade or connection:
  upgrade). Instead it has :scheme set to either 'ws' or 'wss'.
- Client's opening handshake has :authority instead of host.
- Client's opening handshake has no Sec-websocket-key
- Server's opening handshake has 200 status instead of 101.
- Server's opening handshake has no Sec-websocket-accept
- Each DATA frame carries one websocket frame.
- FIN, RSVx and opcode are signaled as the first byte of DATA frame.
- There is no masking, and MASK is implcitly 0.
- Frame length is implicitly data frame length - 1.
- Zero-byte data frames are not valid.
- Proxies fragment or coalesce if needed (TODO: How to handle 16kB
  and up control frames?)
- Proxies can perform adaptation between RFC 6455 and Websockets over
  HTTP/2.
- No TLS handshakes are done (TLS is below HTTP/2).
- TCP connection is replaced by HTTP/2 stream.
 
Given that we have SETTINGS_WEBSOCKET_CAPABLE, I would use a new frame type not to confuse intermediaries / endpoints. The actual data format will be discussed, but IMHO it is less important and can be discussed later.

Thanks,

On Mon, Sep 29, 2014 at 6:51 PM, Ilari Liusvaara <[hidden email]> wrote:
On Mon, Sep 29, 2014 at 02:26:34PM +0900, Yutaka Hirano wrote:
> Hi,
>
> I am proposing a spec draft:
> http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01 .
> Since many modifications were made on on the HTTP/2 spec, some description
> may be obsolete. Please let me know if you find any flaw.

The capability negotiation looks weird.

I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
the rest reserved for extension) from server (or from proxy towards
client).

After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
proxy knows the proxy/server can handle websockets (and is used via
:scheme 'ws'/'wss'). No need to ACK anything.

In the future, some more elaborate extensions might need to be enabled
from both sides, but be base functionality doesn't. Only features that
change existing semantics need to be acknowledged.

One example of something to signal from client to proxy/server would
be reverse connections (but this needs some way for proxies and browsers
to route the connection, maybe associated stream ID, and PUSH_PROMISE
can't be used due to its unidirectionality[1]).

Reverse connections can't be mapped to RFC 6455, so those would need
HTTP/2 path all the way between client and server.

> Yeah, we can't simply use DATA frames because intermediaries may buffer
> data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it
> was removed from the spec. Currently I think introducing a new frame type
> is the right way.

One way would be to take the base Websockets spec for data communications
and rip out everything unneeded and adapt some things:

- Server's/proxy(toward client) SETTINGS has notification about Websockets
  support.
- Client's opening handshake has no upgrade headers (upgrade or connection:
  upgrade). Instead it has :scheme set to either 'ws' or 'wss'.
- Client's opening handshake has :authority instead of host.
- Client's opening handshake has no Sec-websocket-key
- Server's opening handshake has 200 status instead of 101.
- Server's opening handshake has no Sec-websocket-accept
- Each DATA frame carries one websocket frame.
- FIN, RSVx and opcode are signaled as the first byte of DATA frame.
- There is no masking, and MASK is implcitly 0.
- Frame length is implicitly data frame length - 1.
- Zero-byte data frames are not valid.
- Proxies fragment or coalesce if needed (TODO: How to handle 16kB
  and up control frames?)
- Proxies can perform adaptation between RFC 6455 and Websockets over
  HTTP/2.
- No TLS handshakes are done (TLS is below HTTP/2).
- TCP connection is replaced by HTTP/2 stream.

This requires some support on proxies (e.g. priority boosting and
fragmenting), but proxies should know what they are dealing with,
and Websockets needs proxy support anyway (at least unless one does not
want to burn through sequence numbers really fast and to cause excessive
load on proxies).

Also, extensions that modify base header semantics (as opposed to just
using RSVx bits or adding their own header included in frame size)
don't work, but I think that is not a big problem. PMCE is OK.


[1] I earlier sent list of ideas for decoupling framing and HTTP layers,
PUSH_PROMISE is unidirectional even in that (that's the difference
between PUSH_PROMISE and HEADERS!).


-Ilari




--
Greg Wilkins <[hidden email]>
http://eclipse.org/jetty HTTP, SPDY, Websocket server and client that scales
http://www.webtide.com  advice and support for jetty and cometd.
Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Ilari Liusvaara
In reply to this post by Yutaka Hirano
On Mon, Sep 29, 2014 at 08:36:51PM +0900, Yutaka Hirano wrote:

> Thank you for the comments!
>
> We have been not working actively for months because of two reasons:
> 1) The http/2 spec was changing rapidly and we couldn't write a spec on top
> of it.
> 2) We weren't confident if wide range of people were interested in this
> protocol.
>
> 1) will be resolved soon, I hope. For 2), If you are interested in
> WebSocket over HTTP/2, it is very helpful to express it!
> About one year ago, we were talking if we wanted perfect RFC6455 compatible
> WebSocket or not (i.e. full-extension support). IIRC most of us didn't want
> the full RFC6455 compatibility, but if you have any opinion, it is welcome.
> In short, we would like to hear your voice.

Couple points:
- It was just quick sketch using the standard "first idea that isn't known
  broken" way of problem solving.
- That sketch does not have full RFC6455 compability. Some kinds of extensions
  don't work (PMCE just happens to work).
- Some obvious-looking mappings don't work. E.g. one can't map Websockets
  PING to HTTP/2 PING (different scope).
- There should not be lots of HTTP2 header frames. Those are rather heavy,
  and thus increase resource usage. Control frames could be a possiblity,
  but I'd rather not have data frames use those (which would exclude using
  headers for delimiting frames).
- Mapping control frames to headers would be a possiblity. But even so, the
  semantics would likely be close enough for automatic translation at proxy
  to be possible.
- Automatic translation between WS1 and WS2 could be useful together with
  proxies capable of HTTP1<->HTTP2 translation.

> I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
> > the rest reserved for extension) from server (or from proxy towards
> > client).
> > After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
> > proxy knows the proxy/server can handle websockets (and is used via
> > :scheme 'ws'/'wss'). No need to ACK anything.
>
> My proposal doesn't need ACK.
> The client sends a SETTINGS frame before sending the first handshake in the
> stream. After that, the client starts the usual WebSocket opening handshake.

The client needs to know if server supports WS2. Otherwise, the client could
send ws:// or wss:// URL to server that does not support WS2, and that is
"undefined behaviour" (HTTP 4xx/5xx, stream error, connection error(!) or
the worst of all, HTTP 200(!!!)).

I don't see any point in changing server behaviour based on
SETTINGS_WEBSOCKET_CAPABLE. Clients without WS2 support won't send WS2
handshakes. WS2-supporting clients may send those, to servers known to
support WS2.

Similar considerations apply for intermediaries.
 
> One way would be to take the base Websockets spec for data communications
> > and rip out everything unneeded and adapt some things:
>
> Given that we have SETTINGS_WEBSOCKET_CAPABLE, I would use a new frame type
> not to confuse intermediaries / endpoints. The actual data format will be
> discussed, but IMHO it is less important and can be discussed later.

I can't see how such confusion could happen. Intermediary/endpoint is
known WS2-capable and the stream is designated as WS2 in the opening
handshake.

Or is this about dealing with really buggy intermediaries/endpoints?


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Robert Collins
In reply to this post by Yutaka Hirano
On 29 September 2014 18:26, Yutaka Hirano <[hidden email]> wrote:
> Hi,
>
> I am proposing a spec draft:
> http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01 .
> Since many modifications were made on on the HTTP/2 spec, some description
> may be obsolete. Please let me know if you find any flaw.

Cool - I have some questions, below.

>> Secondly, we need to define websocket frame mappings. The least work,
>> and I suspect the easiest for implementors, would be to put all the
>> websocket frames into HTTP/2's data frames, without worrying about
>> frame alignment: just treat the fully open stream as a series of bytes
>> in the same way TCP is treated by the websocket spec.
>> I suspect however that a better result would be achieved by defining
>> custom HTTP/2 frames, since websockets already have the basic support
>> for multiplexing (large application writes can be fragmented into
>> smaller frames as needed), we shouldn't run into HOL blocking issues.
>
> Yeah, we can't simply use DATA frames because intermediaries may buffer
> data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it was
> removed from the spec. Currently I think introducing a new frame type is the
> right way.

I don't understand: DATA is subject to flow control, but I don't see
any prose about buffering (or not buffering) of DATA frames. Unless we
define a new frame time and explicitly prohibit buffering (but we need
to keep it flow controlled), I don't see what would be different. And
more importantly, intermediaries might still choose to buffer a new ws
frame type anyway: we know that what the spec requires and what people
do will differ :). All the implementor discussion I've seen during the
HTTP/2 discussions has focused on how intermediaries want to be
scalable: and buffering is anti-scaling. So - is it a pragmatic
concern, or do we expect DATA stream buffering to take place [outside
of protocol gateways converting to HTTP/1.1 where non upload can
require buffering - and note that such a gateway can't carry ws anyway
unless its aware of it, and if its aware of it, it can make sure it
does not buffer].

>>
>> Lastly, it seems (to me) that it would be desirable to allow
>> PUSH_PROMISE setup of websockets connections
>
> Can you tell me why it is desirable?

Same reason for PUSH_PROMISE of any stream, to avoid setup latency. If
the server is pushing down some javascript libraries that will want a
ws stream back to the same server, it could setup the stream in-line.

Ok, so my questions...

Firstly, I found the 'frame is overloaded, only specify when its
unambiguous' really hard for reading. I'd like to propose that we
fully qualify the frame type everywhere. 'h2 SETTINGS frame', 'ws
RST_STREAM frame' etc: doing otherwise requires a lot more mental
state, at least for me :).


3.2 seems like an antifeature: ALPN is for defining the base protocol
spoke, if you define a new ALPN name for things that speak websockets
over HTTP/2, but it still has all the same framing and flow control
etc, I think it just adds complexity.

There are two alternatives here:
 - ws[s] over TCP, RFC 6355, which using ALPN to select directly could
make sense [though nothing out there does it AFAIK?]
 - ws[s] over HTTP/2. which should be using ALPN to select *HTTP/2*,
since thats the protocol we need.

I say this because if adding ws to HTTP/2 makes a new ALPN, then when
we add a third thing (nt) we'll get:
h2
h2ws
h2nt
h2wsnt

And so on - its problematic :). And SETTING is sufficient to let us know.

Consider this: an h2 capable browser with ws over h2 support is asked
to connect to ws.example.com with ws. If it:
 - tries for h2
 - examines its peer setting for WEBSOCKET_CAPABLE
 - if present tries a HEADERS frame
 - if absent falls back to RFC6455

Then thats pretty sane IMO. If we get this deployed, it will work most
of the time, and when it doesn't, the fallback is there.

3.3
This section seems confused about the semantics of SETTING - see my
new post about clearing that up (whether I need the clearing up, or
the spec does :)).

Anyhow, settings is about advertising, not about negotiating - you
can't negotiate a path through an intermediary graph using it, because
there is no way for the intermediary to signal upstream that just one
client supports it and another doesn't. So the intermediary needs to
signal its support unconditionally. Likewise, the server can't use the
peer's WEBSOCKET_CAPABLE setting to replace the Sec-headers, because
a) a websocket capable browser might still have bad js executing and
trying to attack things, and b) an intermediary may be connecting
multiple different clients to the same server.

Here is an attempt at new prose:

3.3.  WebSocket over HTTP/2 capability

   Servers and intermediaries that can process WebSocket requests over
HTTP/2 MUST advertise the SETTINGS_WEBSOCKET_CAPABLE setting in their
SETTINGS frame.

   Websocket over HTTP/2 MUST NOT be attempted to peers that have not
set SETTINGS_WEBSOCKET_CAPABLE

   Clients do not need to advertise this capability as their making a
valid websockets request signals they are capable.

3.4 secure connection

   If the h2 connection is not secure, wss connections MUST NOT be
intiated over it.
   If the h2 connection is secure, both ws and wss connections MAY be
initiated over it.

3.5 Intermediaries

   Intermediaries that have advertised SETTINGS_WEBSOCKET_CAPABLE may
receive websocket requests which are for origins that do not advertise
SETTINGS_WEBSOCKET_CAPABLE (or may not even support HTTP/2). For
example, it is nearly certain that a forward proxy that speaks HTTP/2
will receive requests for origins that have not yet upgraded to
HTTP/2.

  In such a situation Intermediaries MUST either: initiate a RFC6455
websocket connection with the origin, and translate frames between the
two sides in conformance with both RFC6455 and this RFC. Or they may
return 501 (Not Implemented) to indicate that they cannot forward the
request.

  To illustrate: consider a Client(C), a websocket aware Proxy(P) and
a Server(S).
  P will include SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from P to C.
  C sees that P is capable, and initiates a websocket connection over
HTTP/2 to Origin S.
  P initiates an HTTP/2 connection with S
  S is a baseline HTTP/2 server and does not include
SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from S to P.
  At this point P can either error with 501, signalling that this
particular request cannot be carried, or it can fall back to RFC6455
on behalf of the client.

4.1
You say we can skip "Upgrade, Connection, Sec-WebSocket-Key, and
Sec-WebSocket-Version", because we don't need to do verification. I
think this prose is missing an explanation of why we don't need to do
verification.

There are two failure modes RFC6455 talks about:
A - connections to existing SMTP etc servers
B - submitting data from FORM posts to ws servers

The former is guarded against by looking for a ws specific handshake
from the server.
The latter is guarded against by looking for a ws specific header from
the client *which Javascript APIs do not permit javascript code to
set*.

Your draft defines ws over existing HTTP/2 connections and also new
connections to HTTP/2 endpoints. If we limit ourselves to just ws[s]
over existing HTTP/2 connections, then we maybe we can say:
A) is protected against by RFC6455, and any new connection made for ws
should follow that spec with one exception: If the server negotiates
as a valid HTTP/2 endpoint, then the SETTINGS_WEBSOCKET_CAPABLE
setting from the server is inspected to determine if ws over HTTP/2
can be used - and that supplances the server side calculation that was
used to prove websocket readiness in RFC6455.

B)  the presence of Sec-Websocket-Key and Sec-WebSocket-Version is
used to ensure that a WS endpoint doesn't get form data posted to it.
I see no replacement for that in your draft: we need to keep it,
because its protecting against javascript programming models. (Unless
I've missed something?)

4.2
'"101" or "101 Switching Protocols"' - AIUI in HTTP/2 the reason text
is gone. The status pseudo header is numeric only.

4.2.1 - the ALTSVC draft suggests doing this gracefully - e.g.
openning up the new connection then dropping the old one. We should
include a reason for not following that advice.

5.
There's nothing specified here - neither what frame types we need to
add, nor discussion on the [in]applicability of HTTP/2 DATA. I'd like
to try to use HTTP/2 data I think - the discussion about frame type
compatibility makes me think that we'll be more compatible with
RFC6455 if we just tunnel over the h2 DATA frame: remember that
RFC6455 targetted TCP as a transport, and a series of h2 DATA frames
is most analogous to that. In particular, if we use dedicated control
frames, we could hit out of order behaviour with control frames
forward before DATA frames, because DATA frames are flow controlled:
it will be more complex to specify, and I don't see a benefit.

7
I'm not aware of any equivalent to the masking in HTTP/2, and there is
no discussion of BEAST in the HTTP/2 spec: if we're delegating to
HTTP/2 to solve those issues, I think we need to talk about that now
:)


-Rob

--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Ilari Liusvaara
On Tue, Sep 30, 2014 at 10:46:08AM +1300, Robert Collins wrote:
>
> 7
> I'm not aware of any equivalent to the masking in HTTP/2, and there is
> no discussion of BEAST in the HTTP/2 spec: if we're delegating to
> HTTP/2 to solve those issues, I think we need to talk about that now
> :)
>

HTTP/2 uses TLS 1.2, which is not vulernable to BEAST (it was fixed
in 1.1).


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
In reply to this post by Ilari Liusvaara
On Mon, Sep 29, 2014 at 08:36:51PM +0900, Yutaka Hirano wrote:
> Thank you for the comments!
>
> We have been not working actively for months because of two reasons:
> 1) The http/2 spec was changing rapidly and we couldn't write a spec on top
> of it.
> 2) We weren't confident if wide range of people were interested in this
> protocol.
>
> 1) will be resolved soon, I hope. For 2), If you are interested in
> WebSocket over HTTP/2, it is very helpful to express it!
> About one year ago, we were talking if we wanted perfect RFC6455 compatible
> WebSocket or not (i.e. full-extension support). IIRC most of us didn't want
> the full RFC6455 compatibility, but if you have any opinion, it is welcome.
> In short, we would like to hear your voice.
Couple points:
- It was just quick sketch using the standard "first idea that isn't known
  broken" way of problem solving.
- That sketch does not have full RFC6455 compability. Some kinds of extensions
  don't work (PMCE just happens to work).
- Some obvious-looking mappings don't work. E.g. one can't map Websockets
  PING to HTTP/2 PING (different scope).
- There should not be lots of HTTP2 header frames. Those are rather heavy,
  and thus increase resource usage. Control frames could be a possiblity,
  but I'd rather not have data frames use those (which would exclude using
  headers for delimiting frames).
- Mapping control frames to headers would be a possiblity. But even so, the
  semantics would likely be close enough for automatic translation at proxy
  to be possible.
- Automatic translation between WS1 and WS2 could be useful together with
  proxies capable of HTTP1<->HTTP2 translation.
"Full RFC6455 compatibility" means that the WebSocket over HTTP/2 can express any data represented by the native WebSocket. For example, we can't modify any WebSocket frame boundary if we decide to respect RFC6455. Please see the long discussion starting from: http://www.ietf.org/mail-archive/web/hybi/current/msg10266.html .
My opinion is we don't have to keep the full RFC6455 compatibility and hence we can't have a general translation.
 

> I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
> > the rest reserved for extension) from server (or from proxy towards
> > client).
> > After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
> > proxy knows the proxy/server can handle websockets (and is used via
> > :scheme 'ws'/'wss'). No need to ACK anything.
>
> My proposal doesn't need ACK.
> The client sends a SETTINGS frame before sending the first handshake in the
> stream. After that, the client starts the usual WebSocket opening handshake.
The client needs to know if server supports WS2. Otherwise, the client could
send ws:// or wss:// URL to server that does not support WS2, and that is
"undefined behaviour" (HTTP 4xx/5xx, stream error, connection error(!) or
the worst of all, HTTP 200(!!!)).
I don't see any point in changing server behaviour based on
SETTINGS_WEBSOCKET_CAPABLE. Clients without WS2 support won't send WS2
handshakes. WS2-supporting clients may send those, to servers known to
support WS2.
Similar considerations apply for intermediaries.
Yeah, In my proposal, the client knows the server's preference via ALPN (or ALT-SVC). That way, we can create a WebSocket connection without introducing an additional RTT in typical cases.
The design principal there is
 - We don't want to introduce an additional RTT if the server doesn't implement WebSocket over HTTP/2.
 - We don't want to introduce an additional RTT in typical cases if the server implement WebSocket over HTTP/2.
SETTINGS_WEBSOCKET_CAPABLE is needed for the complete communication path including intermediaries (and for introducing new frame types).
 

> One way would be to take the base Websockets spec for data communications
> > and rip out everything unneeded and adapt some things:
>
> Given that we have SETTINGS_WEBSOCKET_CAPABLE, I would use a new frame type
> not to confuse intermediaries / endpoints. The actual data format will be
> discussed, but IMHO it is less important and can be discussed later.
I can't see how such confusion could happen. Intermediary/endpoint is
known WS2-capable and the stream is designated as WS2 in the opening
handshake.
Or is this about dealing with really buggy intermediaries/endpoints?
One of lessons learned from the existing WebSocket is that many intermediaries interpret what they should not interpret. See http://w2spconf.com/2011/papers/websocket.pdf for example.
As the HTTP/2 spec allows us to create new frame types, doing so looks safer.

 

On Tue, Sep 30, 2014 at 4:36 AM, Ilari Liusvaara <[hidden email]> wrote:
On Mon, Sep 29, 2014 at 08:36:51PM +0900, Yutaka Hirano wrote:
> Thank you for the comments!
>
> We have been not working actively for months because of two reasons:
> 1) The http/2 spec was changing rapidly and we couldn't write a spec on top
> of it.
> 2) We weren't confident if wide range of people were interested in this
> protocol.
>
> 1) will be resolved soon, I hope. For 2), If you are interested in
> WebSocket over HTTP/2, it is very helpful to express it!
> About one year ago, we were talking if we wanted perfect RFC6455 compatible
> WebSocket or not (i.e. full-extension support). IIRC most of us didn't want
> the full RFC6455 compatibility, but if you have any opinion, it is welcome.
> In short, we would like to hear your voice.

Couple points:
- It was just quick sketch using the standard "first idea that isn't known
  broken" way of problem solving.
- That sketch does not have full RFC6455 compability. Some kinds of extensions
  don't work (PMCE just happens to work).
- Some obvious-looking mappings don't work. E.g. one can't map Websockets
  PING to HTTP/2 PING (different scope).
- There should not be lots of HTTP2 header frames. Those are rather heavy,
  and thus increase resource usage. Control frames could be a possiblity,
  but I'd rather not have data frames use those (which would exclude using
  headers for delimiting frames).
- Mapping control frames to headers would be a possiblity. But even so, the
  semantics would likely be close enough for automatic translation at proxy
  to be possible.
- Automatic translation between WS1 and WS2 could be useful together with
  proxies capable of HTTP1<->HTTP2 translation.

> I would just signal SETTINGS_WEBSOCKET_CAPABLE with 0x1-bit set to 1 (and
> > the rest reserved for extension) from server (or from proxy towards
> > client).
> > After receiving SETTINGS_WEBSOCKET_CAPABLE with 0x1 flag, the client/
> > proxy knows the proxy/server can handle websockets (and is used via
> > :scheme 'ws'/'wss'). No need to ACK anything.
>
> My proposal doesn't need ACK.
> The client sends a SETTINGS frame before sending the first handshake in the
> stream. After that, the client starts the usual WebSocket opening handshake.

The client needs to know if server supports WS2. Otherwise, the client could
send ws:// or wss:// URL to server that does not support WS2, and that is
"undefined behaviour" (HTTP 4xx/5xx, stream error, connection error(!) or
the worst of all, HTTP 200(!!!)).

I don't see any point in changing server behaviour based on
SETTINGS_WEBSOCKET_CAPABLE. Clients without WS2 support won't send WS2
handshakes. WS2-supporting clients may send those, to servers known to
support WS2.

Similar considerations apply for intermediaries.

> One way would be to take the base Websockets spec for data communications
> > and rip out everything unneeded and adapt some things:
>
> Given that we have SETTINGS_WEBSOCKET_CAPABLE, I would use a new frame type
> not to confuse intermediaries / endpoints. The actual data format will be
> discussed, but IMHO it is less important and can be discussed later.

I can't see how such confusion could happen. Intermediary/endpoint is
known WS2-capable and the stream is designated as WS2 in the opening
handshake.

Or is this about dealing with really buggy intermediaries/endpoints?


-Ilari

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
In reply to this post by Robert Collins
Thank you for the comments!

If you find small problems (like 4.2 and 4.2.1), creating issues on github (https://github.com/yutakahirano/ws-over-http2) also works.
 
I don't understand: DATA is subject to flow control, but I don't see
any prose about buffering (or not buffering) of DATA frames.
As it is not explicitly prohibited, intermediaries may buffer data, I think. From the WebSocket point of view, we want intermediaries flush the buffered data at each message end.
 
Unless we
define a new frame time and explicitly prohibit buffering (but we need
to keep it flow controlled), I don't see what would be different. And
more importantly, intermediaries might still choose to buffer a new ws
frame type anyway: we know that what the spec requires and what people
do will differ :).
As we send SETTINGS_WEBSOCKET_CAPABLE to notify that the HTTP/2 connection can be used for WebSocket and we use a new frame type, I hope intermediaries can deal with it. IIUC an HTTP/2 extension can create a new frame type, but cannot modify the meaning of existing frame types (e.g. DATA). Even if it is allowed, I would create a new frame type not to confuse implementers and [non-confirming] intermediaries. 

All the implementor discussion I've seen during the
HTTP/2 discussions has focused on how intermediaries want to be
scalable: and buffering is anti-scaling. So - is it a pragmatic
concern, or do we expect DATA stream buffering to take place [outside
of protocol gateways converting to HTTP/1.1 where non upload can
require buffering - and note that such a gateway can't carry ws anyway
unless its aware of it, and if its aware of it, it can make sure it
does not buffer].
>>
>> Lastly, it seems (to me) that it would be desirable to allow
>> PUSH_PROMISE setup of websockets connections
>
> Can you tell me why it is desirable?
Same reason for PUSH_PROMISE of any stream, to avoid setup latency. If
the server is pushing down some javascript libraries that will want a
ws stream back to the same server, it could setup the stream in-line.
Ah, I see, but I don't have the answer.


Ok, so my questions...
Firstly, I found the 'frame is overloaded, only specify when its
unambiguous' really hard for reading. I'd like to propose that we
fully qualify the frame type everywhere. 'h2 SETTINGS frame', 'ws
RST_STREAM frame' etc: doing otherwise requires a lot more mental
state, at least for me :).

3.2 seems like an antifeature: ALPN is for defining the base protocol
spoke, if you define a new ALPN name for things that speak websockets
over HTTP/2, but it still has all the same framing and flow control
etc, I think it just adds complexity.
There are two alternatives here:
 - ws[s] over TCP, RFC 6355, which using ALPN to select directly could
make sense [though nothing out there does it AFAIK?]
 - ws[s] over HTTP/2. which should be using ALPN to select *HTTP/2*,
since thats the protocol we need.
I say this because if adding ws to HTTP/2 makes a new ALPN, then when
we add a third thing (nt) we'll get:
h2
h2ws
h2nt
h2wsnt
And so on - its problematic :). And SETTING is sufficient to let us know.
The problem is, we have the native WebSocket (h1ws). There are four possibilities:
 - The server prefers h2 over h1 and h2ws over h1ws
 - The server prefers h2 over h1 and h1ws over h2ws
 - The server prefers h1 over h2 and h2ws over h1ws
 - The server prefers h1 over h2 and h1ws over h2ws
The ALPN things are required to deal with the complex situation without introducing a new RTT.

If nt doesn't have h1nt, we don't have to introduce h2nt ALPN protocol - Just sending SETTINGS frame and starting a handshake is enough.
Even if nt does have h1nt, we don't have to introduce h2wsnt. h2xx is needed only when the first stream in the h2 connection is intended to use xx protocol. We can't have a "wsnt" stream.
 
Consider this: an h2 capable browser with ws over h2 support is asked
to connect to ws.example.com with ws. If it:
 - tries for h2
 - examines its peer setting for WEBSOCKET_CAPABLE
 - if present tries a HEADERS frame
 - if absent falls back to RFC6455
Then thats pretty sane IMO. If we get this deployed, it will work most
of the time, and when it doesn't, the fallback is there.
That depends on the question: How common is a server to prefer h2 over h1 and h1ws over h2ws?
I thought it was not so uncommon, so wrote the negotiation using ALPN. If we get a consensus that it is very rare, we can use a simpler solution.
 

3.3
This section seems confused about the semantics of SETTING - see my
new post about clearing that up (whether I need the clearing up, or
the spec does :)).
Hmm, I thought that when one endpoint  sends a SETTINGS frame, each intermediary must relay the frame if (and only if) it understand the value, is that right?
 
Anyhow, settings is about advertising, not about negotiating - you
can't negotiate a path through an intermediary graph using it, because
there is no way for the intermediary to signal upstream that just one
client supports it and another doesn't. So the intermediary needs to
signal its support unconditionally. Likewise, the server can't use the
peer's WEBSOCKET_CAPABLE setting to replace the Sec-headers, because
a) a websocket capable browser might still have bad js executing and
trying to attack things, and b) an intermediary may be connecting
multiple different clients to the same server.
I didn't intend to replace Sec-headers with WebSocket_CAPABLE. :scheme header replaces Sec-headers.
 

Here is an attempt at new prose:
3.3.  WebSocket over HTTP/2 capability
   Servers and intermediaries that can process WebSocket requests over
HTTP/2 MUST advertise the SETTINGS_WEBSOCKET_CAPABLE setting in their
SETTINGS frame.
   Websocket over HTTP/2 MUST NOT be attempted to peers that have not
set SETTINGS_WEBSOCKET_CAPABLE
   Clients do not need to advertise this capability as their making a
valid websockets request signals they are capable.
3.4 secure connection
   If the h2 connection is not secure, wss connections MUST NOT be
intiated over it.
   If the h2 connection is secure, both ws and wss connections MAY be
initiated over it.
3.5 Intermediaries
   Intermediaries that have advertised SETTINGS_WEBSOCKET_CAPABLE may
receive websocket requests which are for origins that do not advertise
SETTINGS_WEBSOCKET_CAPABLE (or may not even support HTTP/2). For
example, it is nearly certain that a forward proxy that speaks HTTP/2
will receive requests for origins that have not yet upgraded to
HTTP/2.
  In such a situation Intermediaries MUST either: initiate a RFC6455
websocket connection with the origin, and translate frames between the
two sides in conformance with both RFC6455 and this RFC. Or they may
return 501 (Not Implemented) to indicate that they cannot forward the
request.
  To illustrate: consider a Client(C), a websocket aware Proxy(P) and
a Server(S).
  P will include SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from P to C.
  C sees that P is capable, and initiates a websocket connection over
HTTP/2 to Origin S.
  P initiates an HTTP/2 connection with S
  S is a baseline HTTP/2 server and does not include
SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from S to P.
  At this point P can either error with 501, signalling that this
particular request cannot be carried, or it can fall back to RFC6455
on behalf of the client.
4.1
You say we can skip "Upgrade, Connection, Sec-WebSocket-Key, and
Sec-WebSocket-Version", because we don't need to do verification. I
think this prose is missing an explanation of why we don't need to do
verification.
There are two failure modes RFC6455 talks about:
A - connections to existing SMTP etc servers
B - submitting data from FORM posts to ws servers
The former is guarded against by looking for a ws specific handshake
from the server.
The latter is guarded against by looking for a ws specific header from
the client *which Javascript APIs do not permit javascript code to
set*.
Your draft defines ws over existing HTTP/2 connections and also new
connections to HTTP/2 endpoints. If we limit ourselves to just ws[s]
over existing HTTP/2 connections, then we maybe we can say:
A) is protected against by RFC6455, and any new connection made for ws
should follow that spec with one exception: If the server negotiates
as a valid HTTP/2 endpoint, then the SETTINGS_WEBSOCKET_CAPABLE
setting from the server is inspected to determine if ws over HTTP/2
can be used - and that supplances the server side calculation that was
used to prove websocket readiness in RFC6455.
B)  the presence of Sec-Websocket-Key and Sec-WebSocket-Version is
used to ensure that a WS endpoint doesn't get form data posted to it.
I see no replacement for that in your draft: we need to keep it,
because its protecting against javascript programming models. (Unless
I've missed something?)
As we have :scheme and HEADERS is decoupled from the body, I think we don't need Sec-headers. They are needed because non-confirming endpoints mistakenly recognize HTTP-like structure that are generated by the script, but It will not happen with H2.


4.2
'"101" or "101 Switching Protocols"' - AIUI in HTTP/2 the reason text
is gone. The status pseudo header is numeric only.
Thanks, I will update.
 
4.2.1 - the ALTSVC draft suggests doing this gracefully - e.g.
openning up the new connection then dropping the old one. We should
include a reason for not following that advice.
I will update.
 

5.
There's nothing specified here - neither what frame types we need to
add, nor discussion on the [in]applicability of HTTP/2 DATA. I'd like
to try to use HTTP/2 data I think - the discussion about frame type
compatibility makes me think that we'll be more compatible with
RFC6455 if we just tunnel over the h2 DATA frame: remember that
RFC6455 targetted TCP as a transport, and a series of h2 DATA frames
is most analogous to that. In particular, if we use dedicated control
frames, we could hit out of order behaviour with control frames
forward before DATA frames, because DATA frames are flow controlled:
it will be more complex to specify, and I don't see a benefit.
Everyone is excited about the data framing, but what to represent is much more important than how to represent it, I think.


7
I'm not aware of any equivalent to the masking in HTTP/2, and there is
no discussion of BEAST in the HTTP/2 spec: if we're delegating to
HTTP/2 to solve those issues, I think we need to talk about that now
:)
Yeah, I exactly delegate to HTTP/2. I'm certain that If we are in danger, HTTP/2 is, too. I'm not certain if we are in danger.
Most of WebSocket-related security bugs were caused by making [non-conforming] intermediaries / endpoints that don't understand WebSocket interpret the data as HTTP. So I don't want to give them any chance of confusion. That is another reason why I don't like using h2 DATA frames.
 

On Tue, Sep 30, 2014 at 6:46 AM, Robert Collins <[hidden email]> wrote:
On 29 September 2014 18:26, Yutaka Hirano <[hidden email]> wrote:
> Hi,
>
> I am proposing a spec draft:
> http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01 .
> Since many modifications were made on on the HTTP/2 spec, some description
> may be obsolete. Please let me know if you find any flaw.

Cool - I have some questions, below.

>> Secondly, we need to define websocket frame mappings. The least work,
>> and I suspect the easiest for implementors, would be to put all the
>> websocket frames into HTTP/2's data frames, without worrying about
>> frame alignment: just treat the fully open stream as a series of bytes
>> in the same way TCP is treated by the websocket spec.
>> I suspect however that a better result would be achieved by defining
>> custom HTTP/2 frames, since websockets already have the basic support
>> for multiplexing (large application writes can be fragmented into
>> smaller frames as needed), we shouldn't run into HOL blocking issues.
>
> Yeah, we can't simply use DATA frames because intermediaries may buffer
> data. The HTTP/2 spec had "MSG_DONE" once and I wanted to use it, but it was
> removed from the spec. Currently I think introducing a new frame type is the
> right way.

I don't understand: DATA is subject to flow control, but I don't see
any prose about buffering (or not buffering) of DATA frames. Unless we
define a new frame time and explicitly prohibit buffering (but we need
to keep it flow controlled), I don't see what would be different. And
more importantly, intermediaries might still choose to buffer a new ws
frame type anyway: we know that what the spec requires and what people
do will differ :). All the implementor discussion I've seen during the
HTTP/2 discussions has focused on how intermediaries want to be
scalable: and buffering is anti-scaling. So - is it a pragmatic
concern, or do we expect DATA stream buffering to take place [outside
of protocol gateways converting to HTTP/1.1 where non upload can
require buffering - and note that such a gateway can't carry ws anyway
unless its aware of it, and if its aware of it, it can make sure it
does not buffer].

>>
>> Lastly, it seems (to me) that it would be desirable to allow
>> PUSH_PROMISE setup of websockets connections
>
> Can you tell me why it is desirable?

Same reason for PUSH_PROMISE of any stream, to avoid setup latency. If
the server is pushing down some javascript libraries that will want a
ws stream back to the same server, it could setup the stream in-line.

Ok, so my questions...

Firstly, I found the 'frame is overloaded, only specify when its
unambiguous' really hard for reading. I'd like to propose that we
fully qualify the frame type everywhere. 'h2 SETTINGS frame', 'ws
RST_STREAM frame' etc: doing otherwise requires a lot more mental
state, at least for me :).


3.2 seems like an antifeature: ALPN is for defining the base protocol
spoke, if you define a new ALPN name for things that speak websockets
over HTTP/2, but it still has all the same framing and flow control
etc, I think it just adds complexity.

There are two alternatives here:
 - ws[s] over TCP, RFC 6355, which using ALPN to select directly could
make sense [though nothing out there does it AFAIK?]
 - ws[s] over HTTP/2. which should be using ALPN to select *HTTP/2*,
since thats the protocol we need.

I say this because if adding ws to HTTP/2 makes a new ALPN, then when
we add a third thing (nt) we'll get:
h2
h2ws
h2nt
h2wsnt

And so on - its problematic :). And SETTING is sufficient to let us know.

Consider this: an h2 capable browser with ws over h2 support is asked
to connect to ws.example.com with ws. If it:
 - tries for h2
 - examines its peer setting for WEBSOCKET_CAPABLE
 - if present tries a HEADERS frame
 - if absent falls back to RFC6455

Then thats pretty sane IMO. If we get this deployed, it will work most
of the time, and when it doesn't, the fallback is there.

3.3
This section seems confused about the semantics of SETTING - see my
new post about clearing that up (whether I need the clearing up, or
the spec does :)).

Anyhow, settings is about advertising, not about negotiating - you
can't negotiate a path through an intermediary graph using it, because
there is no way for the intermediary to signal upstream that just one
client supports it and another doesn't. So the intermediary needs to
signal its support unconditionally. Likewise, the server can't use the
peer's WEBSOCKET_CAPABLE setting to replace the Sec-headers, because
a) a websocket capable browser might still have bad js executing and
trying to attack things, and b) an intermediary may be connecting
multiple different clients to the same server.

Here is an attempt at new prose:

3.3.  WebSocket over HTTP/2 capability

   Servers and intermediaries that can process WebSocket requests over
HTTP/2 MUST advertise the SETTINGS_WEBSOCKET_CAPABLE setting in their
SETTINGS frame.

   Websocket over HTTP/2 MUST NOT be attempted to peers that have not
set SETTINGS_WEBSOCKET_CAPABLE

   Clients do not need to advertise this capability as their making a
valid websockets request signals they are capable.

3.4 secure connection

   If the h2 connection is not secure, wss connections MUST NOT be
intiated over it.
   If the h2 connection is secure, both ws and wss connections MAY be
initiated over it.

3.5 Intermediaries

   Intermediaries that have advertised SETTINGS_WEBSOCKET_CAPABLE may
receive websocket requests which are for origins that do not advertise
SETTINGS_WEBSOCKET_CAPABLE (or may not even support HTTP/2). For
example, it is nearly certain that a forward proxy that speaks HTTP/2
will receive requests for origins that have not yet upgraded to
HTTP/2.

  In such a situation Intermediaries MUST either: initiate a RFC6455
websocket connection with the origin, and translate frames between the
two sides in conformance with both RFC6455 and this RFC. Or they may
return 501 (Not Implemented) to indicate that they cannot forward the
request.

  To illustrate: consider a Client(C), a websocket aware Proxy(P) and
a Server(S).
  P will include SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from P to C.
  C sees that P is capable, and initiates a websocket connection over
HTTP/2 to Origin S.
  P initiates an HTTP/2 connection with S
  S is a baseline HTTP/2 server and does not include
SETTINGS_WEBSOCKET_CAPABLE in its SETTINGS frame from S to P.
  At this point P can either error with 501, signalling that this
particular request cannot be carried, or it can fall back to RFC6455
on behalf of the client.

4.1
You say we can skip "Upgrade, Connection, Sec-WebSocket-Key, and
Sec-WebSocket-Version", because we don't need to do verification. I
think this prose is missing an explanation of why we don't need to do
verification.

There are two failure modes RFC6455 talks about:
A - connections to existing SMTP etc servers
B - submitting data from FORM posts to ws servers

The former is guarded against by looking for a ws specific handshake
from the server.
The latter is guarded against by looking for a ws specific header from
the client *which Javascript APIs do not permit javascript code to
set*.

Your draft defines ws over existing HTTP/2 connections and also new
connections to HTTP/2 endpoints. If we limit ourselves to just ws[s]
over existing HTTP/2 connections, then we maybe we can say:
A) is protected against by RFC6455, and any new connection made for ws
should follow that spec with one exception: If the server negotiates
as a valid HTTP/2 endpoint, then the SETTINGS_WEBSOCKET_CAPABLE
setting from the server is inspected to determine if ws over HTTP/2
can be used - and that supplances the server side calculation that was
used to prove websocket readiness in RFC6455.

B)  the presence of Sec-Websocket-Key and Sec-WebSocket-Version is
used to ensure that a WS endpoint doesn't get form data posted to it.
I see no replacement for that in your draft: we need to keep it,
because its protecting against javascript programming models. (Unless
I've missed something?)

4.2
'"101" or "101 Switching Protocols"' - AIUI in HTTP/2 the reason text
is gone. The status pseudo header is numeric only.

4.2.1 - the ALTSVC draft suggests doing this gracefully - e.g.
openning up the new connection then dropping the old one. We should
include a reason for not following that advice.

5.
There's nothing specified here - neither what frame types we need to
add, nor discussion on the [in]applicability of HTTP/2 DATA. I'd like
to try to use HTTP/2 data I think - the discussion about frame type
compatibility makes me think that we'll be more compatible with
RFC6455 if we just tunnel over the h2 DATA frame: remember that
RFC6455 targetted TCP as a transport, and a series of h2 DATA frames
is most analogous to that. In particular, if we use dedicated control
frames, we could hit out of order behaviour with control frames
forward before DATA frames, because DATA frames are flow controlled:
it will be more complex to specify, and I don't see a benefit.

7
I'm not aware of any equivalent to the masking in HTTP/2, and there is
no discussion of BEAST in the HTTP/2 spec: if we're delegating to
HTTP/2 to solve those issues, I think we need to talk about that now
:)


-Rob

--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Amos Jeffries-2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 1/10/2014 8:53 p.m., Yutaka Hirano wrote:

> Thank you for the comments!
>
> If you find small problems (like 4.2 and 4.2.1), creating issues on
> github ( https://github.com/yutakahirano/ws-over-http2) also
> works.
>
>
>> I don't understand: DATA is subject to flow control, but I don't
>> see any prose about buffering (or not buffering) of DATA frames.
>
> As it is not explicitly prohibited, intermediaries may buffer data,
> I think. From the WebSocket point of view, we want intermediaries
> flush the buffered data at each message end.
>
>
>> Unless we define a new frame time and explicitly prohibit
>> buffering (but we need to keep it flow controlled), I don't see
>> what would be different. And more importantly, intermediaries
>> might still choose to buffer a new ws frame type anyway: we know
>> that what the spec requires and what people do will differ :).
>
> As we send SETTINGS_WEBSOCKET_CAPABLE to notify that the HTTP/2
> connection can be used for WebSocket and we use a new frame type, I
> hope intermediaries can deal with it. IIUC an HTTP/2 extension can
> create a new frame type, but cannot modify the meaning of existing
> frame types (e.g. DATA). Even if it is allowed, I would create a
> new frame type not to confuse implementers and [non-confirming]
> intermediaries.
>
> All the implementor discussion I've seen during the
>> HTTP/2 discussions has focused on how intermediaries want to be
>> scalable: and buffering is anti-scaling. So - is it a pragmatic
>> concern, or do we expect DATA stream buffering to take place
>> [outside of protocol gateways converting to HTTP/1.1 where non
>> upload can require buffering - and note that such a gateway can't
>> carry ws anyway unless its aware of it, and if its aware of it,
>> it can make sure it does not buffer].


I think the problem is not buffering in HTTP/2 per-se but the DATA
frame (de-)aggregation that can happen if the frames are buffered by
general network conditions (ie in TCP bottlenecks). This would not be
good for a 1:1 relationship between DATA and ws frames.

Amos
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iQEcBAEBAgAGBQJUK9lgAAoJELJo5wb/XPRjtOEH/i4U3IrX/rjrjZE0dENA1LEF
ifCyjiiWCUIZBBGSW+hzYdFwVRLLhxyHg2vsIQMwpVnTXZzs1QfcAKKl4pJBqscQ
Q92B+fgJZvNmmakrh9mNBA4AVuxDuYm2EYbvAZiSnroxKbYBwdxQMK1ex9reHaY1
TNvlYJyhUX6RQZAllaIxaidEFKazTe1nwzVEuVv80isQtZBqmVL4qhgVw6okf6GP
QzTXHHH1HuaopsJe225RcZaH36NZAtFPJz7DaDbynGLHQqWZg3CVKWKiEYu9GJQe
qa1GVvETgAw40f8AVldTi6AMBsGdZK72dOGTafQoRzv5BMctqqqEofqpmkRC7OY=
=08a0
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Robert Collins
On 1 October 2014 23:37, Amos Jeffries <[hidden email]> wrote:

>> All the implementor discussion I've seen during the
>>> HTTP/2 discussions has focused on how intermediaries want to be
>>> scalable: and buffering is anti-scaling. So - is it a pragmatic
>>> concern, or do we expect DATA stream buffering to take place
>>> [outside of protocol gateways converting to HTTP/1.1 where non
>>> upload can require buffering - and note that such a gateway can't
>>> carry ws anyway unless its aware of it, and if its aware of it,
>>> it can make sure it does not buffer].
>
>
> I think the problem is not buffering in HTTP/2 per-se but the DATA
> frame (de-)aggregation that can happen if the frames are buffered by
> general network conditions (ie in TCP bottlenecks). This would not be
> good for a 1:1 relationship between DATA and ws frames.
>
> Amos

So hang on a second here. If we say that ws frames can't be split over
multiple HTTP/2 frames that implies that we have to buffer them until
there is enough in the window to transmit a potentially very large
packet all at once. It also conflicts with RFC6455 - the specific
intent there is to not be a stream based system.

I was suggesting that we just treat the HTTP/2 stream like the TCP
connection in RFC 6455 - the conversation from stream to message based
semantics and so on can take place above that in the ws implementation
- and that we should still apply the transmission windows etc to ws
streams.

-Rob



--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
I was suggesting that we just treat the HTTP/2 stream like the TCP
connection in RFC 6455 - the conversation from stream to message based
semantics and so on can take place above that in the ws implementation
- and that we should still apply the transmission windows etc to ws
streams.
As I said, I would like a guarantee that intermediaries do not buffer data across the message boundary. END_SEGMENT was a mechanism to archive this, but it was gone. So I want to specify a new frame type (WEBSOCKET_DATA) to guarantee that (Note: I'm not sure if tunneling is good or bad, but forbidding buffering across the message boundary is important in any case).


On Tue, Oct 14, 2014 at 7:01 PM, Robert Collins <[hidden email]> wrote:
On 1 October 2014 23:37, Amos Jeffries <[hidden email]> wrote:

>> All the implementor discussion I've seen during the
>>> HTTP/2 discussions has focused on how intermediaries want to be
>>> scalable: and buffering is anti-scaling. So - is it a pragmatic
>>> concern, or do we expect DATA stream buffering to take place
>>> [outside of protocol gateways converting to HTTP/1.1 where non
>>> upload can require buffering - and note that such a gateway can't
>>> carry ws anyway unless its aware of it, and if its aware of it,
>>> it can make sure it does not buffer].
>
>
> I think the problem is not buffering in HTTP/2 per-se but the DATA
> frame (de-)aggregation that can happen if the frames are buffered by
> general network conditions (ie in TCP bottlenecks). This would not be
> good for a 1:1 relationship between DATA and ws frames.
>
> Amos

So hang on a second here. If we say that ws frames can't be split over
multiple HTTP/2 frames that implies that we have to buffer them until
there is enough in the window to transmit a potentially very large
packet all at once. It also conflicts with RFC6455 - the specific
intent there is to not be a stream based system.

I was suggesting that we just treat the HTTP/2 stream like the TCP
connection in RFC 6455 - the conversation from stream to message based
semantics and so on can take place above that in the ws implementation
- and that we should still apply the transmission windows etc to ws
streams.

-Rob



--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud


Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Amos Jeffries-2
In reply to this post by Robert Collins
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 14/10/2014 11:01 p.m., Robert Collins wrote:

> On 1 October 2014 23:37, Amos Jeffries wrote:
>
>>> All the implementor discussion I've seen during the
>>>> HTTP/2 discussions has focused on how intermediaries want to
>>>> be scalable: and buffering is anti-scaling. So - is it a
>>>> pragmatic concern, or do we expect DATA stream buffering to
>>>> take place [outside of protocol gateways converting to
>>>> HTTP/1.1 where non upload can require buffering - and note
>>>> that such a gateway can't carry ws anyway unless its aware of
>>>> it, and if its aware of it, it can make sure it does not
>>>> buffer].
>>
>>
>> I think the problem is not buffering in HTTP/2 per-se but the
>> DATA frame (de-)aggregation that can happen if the frames are
>> buffered by general network conditions (ie in TCP bottlenecks).
>> This would not be good for a 1:1 relationship between DATA and ws
>> frames.
>>
>> Amos
>
> So hang on a second here. If we say that ws frames can't be split
> over multiple HTTP/2 frames that implies that we have to buffer
> them until there is enough in the window to transmit a potentially
> very large packet all at once. It also conflicts with RFC6455 - the
> specific intent there is to not be a stream based system.

If a ws frame *has* to be that long, not doing so would block the
entire HTTP/2 connection until all bytes of that frame were delivered
anyway. So you trade off buffering that single frame at the sender,
versus blocking all HTTP/2 traffic end-to-end.

If the ws data is so critical to get transmitted fast why is that
single ws frame so large to begin with? surely it would be transmitted
faster as a sequence of WS + *WSDATA frames emited as the payload was
available to send.

>
> I was suggesting that we just treat the HTTP/2 stream like the TCP
> connection in RFC 6455 - the conversation from stream to message
> based semantics and so on can take place above that in the ws
> implementation - and that we should still apply the transmission
> windows etc to ws streams.

If you do that you loose any and all benefits from HTTP/2 frames.
Everything from ws frame headers to data content becomes semantically
identical to the opaque payload of a DATA frame on an HTTP/2 CONNECT
request. I believe Yutaka is seeking to get away from that situation
where DATA frames may be split, joined or buffered at any point.

Amos

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)

iQEcBAEBAgAGBQJUPQJMAAoJELJo5wb/XPRjgOYH/1nA7VOhJ0tzslcadEPD3Hzl
mUWos3c+s2v2lZ2Ao5QglHIjH4FrCR9clyMaf4GyC9YsU4jaJ9nWQvw1MWFS00NG
B2VXS0kIk5M0wqPaSLApVsXv0lHesGwGhqmgDm/vRMCOV5rdwp7FV1Bh3qNY0SuM
frf/OKHz4VPSzzyec6kdBncjGCO8DGxWnraVDSu++Lil918ww5mbfo/kcTms4ykK
usYr6+jMi+CzK50+XB5AfxmIILBXKcgnhJGeRYUbpK2ecF15bBuZ6eZBIe9DHaeG
rCDqqZ2w9Rl54M3Ml34hrmtZ0Wv5EbdFcmvwRs9E+af4bOUuHee9tNTtZ/2/jSY=
=xNsZ
-----END PGP SIGNATURE-----

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Robert Collins
On 15 October 2014 00:00, Amos Jeffries <[hidden email]> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>> On 1 October 2014 23:37, Amos Jeffries wrote:
>>
>>>> All the implementor discussion I've seen during the
>>>>> HTTP/2 discussions has focused on how intermediaries want to
>>>>> be scalable: and buffering is anti-scaling. So - is it a
>>>>> pragmatic concern, or do we expect DATA stream buffering to
>>>>> take place [outside of protocol gateways converting to
>>>>> HTTP/1.1 where non upload can require buffering - and note
>>>>> that such a gateway can't carry ws anyway unless its aware of
>>>>> it, and if its aware of it, it can make sure it does not
>>>>> buffer].
>>>
>>>
>>> I think the problem is not buffering in HTTP/2 per-se but the
>>> DATA frame (de-)aggregation that can happen if the frames are
>>> buffered by general network conditions (ie in TCP bottlenecks).
>>> This would not be good for a 1:1 relationship between DATA and ws
>>> frames.
>>>
>>> Amos
>>
>> So hang on a second here. If we say that ws frames can't be split
>> over multiple HTTP/2 frames that implies that we have to buffer
>> them until there is enough in the window to transmit a potentially
>> very large packet all at once. It also conflicts with RFC6455 - the
>> specific intent there is to not be a stream based system.
>
> If a ws frame *has* to be that long, not doing so would block the
> entire HTTP/2 connection until all bytes of that frame were delivered
> anyway. So you trade off buffering that single frame at the sender,
> versus blocking all HTTP/2 traffic end-to-end.
>
> If the ws data is so critical to get transmitted fast why is that
> single ws frame so large to begin with? surely it would be transmitted
> faster as a sequence of WS + *WSDATA frames emited as the payload was
> available to send.

I agree that its inconsistent which is why I don't think it matters
and mapping down to h2 frames as a sequence of octets would be fine.
But you seem to both agree with my reasoning and disagree with my
conclusion. This is confusing.

>> I was suggesting that we just treat the HTTP/2 stream like the TCP
>> connection in RFC 6455 - the conversation from stream to message
>> based semantics and so on can take place above that in the ws
>> implementation - and that we should still apply the transmission
>> windows etc to ws streams.
>
> If you do that you loose any and all benefits from HTTP/2 frames.
> Everything from ws frame headers to data content becomes semantically
> identical to the opaque payload of a DATA frame on an HTTP/2 CONNECT
> request. I believe Yutaka is seeking to get away from that situation
> where DATA frames may be split, joined or buffered at any point.

Sorry, I just don't follow that. We have a primitive which appears to
fit ws entirely, with the only caveat being that we haven't defined
the mapping from the high level frames to the h2 primitives. If the
spec identifies how ws is negotiated and framed within h2, its not
opaque at all. And ws implementations that support raw ws (which
they'll do for quite some time...) have to deal with tcp which offers
no better semantics than this.

-Rob

--
Robert Collins <[hidden email]>
Distinguished Technologist
HP Converged Cloud

Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Andy Green


On 21 November 2014 04:11:53 GMT+08:00, Robert Collins <[hidden email]> wrote:

>On 15 October 2014 00:00, Amos Jeffries <[hidden email]> wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>>> On 1 October 2014 23:37, Amos Jeffries wrote:
>>>
>>>>> All the implementor discussion I've seen during the
>>>>>> HTTP/2 discussions has focused on how intermediaries want to
>>>>>> be scalable: and buffering is anti-scaling. So - is it a
>>>>>> pragmatic concern, or do we expect DATA stream buffering to
>>>>>> take place [outside of protocol gateways converting to
>>>>>> HTTP/1.1 where non upload can require buffering - and note
>>>>>> that such a gateway can't carry ws anyway unless its aware of
>>>>>> it, and if its aware of it, it can make sure it does not
>>>>>> buffer].
>>>>
>>>>
>>>> I think the problem is not buffering in HTTP/2 per-se but the
>>>> DATA frame (de-)aggregation that can happen if the frames are
>>>> buffered by general network conditions (ie in TCP bottlenecks).
>>>> This would not be good for a 1:1 relationship between DATA and ws
>>>> frames.
>>>>
>>>> Amos
>>>
>>> So hang on a second here. If we say that ws frames can't be split
>>> over multiple HTTP/2 frames that implies that we have to buffer
>>> them until there is enough in the window to transmit a potentially
>>> very large packet all at once. It also conflicts with RFC6455 - the
>>> specific intent there is to not be a stream based system.
>>
>> If a ws frame *has* to be that long, not doing so would block the
>> entire HTTP/2 connection until all bytes of that frame were delivered
>> anyway. So you trade off buffering that single frame at the sender,
>> versus blocking all HTTP/2 traffic end-to-end.
>>
>> If the ws data is so critical to get transmitted fast why is that
>> single ws frame so large to begin with? surely it would be
>transmitted
>> faster as a sequence of WS + *WSDATA frames emited as the payload was
>> available to send.
>
>I agree that its inconsistent which is why I don't think it matters

I am the author of libwebsockets, we are adding http2 support at the moment.  The basic http2 serving is done and works for http, but we're all dressed up and nowhere to go in terms of treating websocket connections as just another kind of http2, since the framing is "TBD".  I am sorry I am a bit late to the party.

I think you have to take the atomic large ws frame thing as a genuine problem because http2 has the transmit credit concept.  So even if you buffered one ws frame, you can't sit there spewing as much http2 DATA frame as it needs to atomically encapsulate it, without sizing your http2 frame to suit the tx credit.

But it's OK because the implementation can transparently fragment the ws data using the ws message semantics... I think there's no choice but to take that approach.

Otherwise you get into being able to DoS even an http2 "big pipe aggregation" by just one mux element spewing an endless ws frame and blocking every other mux'd connection... it cannot be right.

>and mapping down to h2 frames as a sequence of octets would be fine.
>But you seem to both agree with my reasoning and disagree with my
>conclusion. This is confusing.
>
>>> I was suggesting that we just treat the HTTP/2 stream like the TCP
>>> connection in RFC 6455 - the conversation from stream to message
>>> based semantics and so on can take place above that in the ws
>>> implementation - and that we should still apply the transmission
>>> windows etc to ws streams.

Yes ---^ this is how it has to be I think.

>> If you do that you loose any and all benefits from HTTP/2 frames.
>> Everything from ws frame headers to data content becomes semantically
>> identical to the opaque payload of a DATA frame on an HTTP/2 CONNECT
>> request. I believe Yutaka is seeking to get away from that situation
>> where DATA frames may be split, joined or buffered at any point.
>
>Sorry, I just don't follow that. We have a primitive which appears to
>fit ws entirely, with the only caveat being that we haven't defined
>the mapping from the high level frames to the h2 primitives. If the

Yeah.

>spec identifies how ws is negotiated and framed within h2, its not
>opaque at all. And ws implementations that support raw ws (which
>they'll do for quite some time...) have to deal with tcp which offers
>no better semantics than this.

Right now if I understood it the ws connections can still negotiate themselves transparently inside http2 mux connections, using the RFC6455 upgrade on their individual session ID, do the extra RTT and tx data masking.

Formalizing how to encapsulate the same thing in http2 doesn't buy much above that... the benefit we can get is map the RFC6455 framing on to http2 native framing and get rid of the duplication simple encapsulation has (for many small frames, it would be really painful overhead actually).  So if we will do anything, it should indeed be define how to map RFC6455 framing on http2 framing.

I guess it can be done in parallel with http2 coming to an end rather than trying to block it, just by defining some new optional frame types...

-Andy

>-Rob


Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano
I think you have to take the atomic large ws frame thing as a genuine problem because http2 has the transmit credit concept.  So even if you buffered one ws frame, you can't sit there spewing as much http2 DATA frame as it needs to atomically encapsulate it, without sizing your http2 frame to suit the tx credit.
But it's OK because the implementation can transparently fragment the ws data using the ws message semantics... I think there's no choice but to take that approach.
Sorry I don't understand what you are proposing. Can you explain?

I guess it can be done in parallel with http2 coming to an end rather than trying to block it, just by defining some new optional frame types...
I agree to define a ws-dedicated frame type and use it.


On Fri, Nov 21, 2014 at 10:47 AM, Andy Green <[hidden email]> wrote:


On 21 November 2014 04:11:53 GMT+08:00, Robert Collins <[hidden email]> wrote:
>On 15 October 2014 00:00, Amos Jeffries <[hidden email]> wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>>> On 1 October 2014 23:37, Amos Jeffries wrote:
>>>
>>>>> All the implementor discussion I've seen during the
>>>>>> HTTP/2 discussions has focused on how intermediaries want to
>>>>>> be scalable: and buffering is anti-scaling. So - is it a
>>>>>> pragmatic concern, or do we expect DATA stream buffering to
>>>>>> take place [outside of protocol gateways converting to
>>>>>> HTTP/1.1 where non upload can require buffering - and note
>>>>>> that such a gateway can't carry ws anyway unless its aware of
>>>>>> it, and if its aware of it, it can make sure it does not
>>>>>> buffer].
>>>>
>>>>
>>>> I think the problem is not buffering in HTTP/2 per-se but the
>>>> DATA frame (de-)aggregation that can happen if the frames are
>>>> buffered by general network conditions (ie in TCP bottlenecks).
>>>> This would not be good for a 1:1 relationship between DATA and ws
>>>> frames.
>>>>
>>>> Amos
>>>
>>> So hang on a second here. If we say that ws frames can't be split
>>> over multiple HTTP/2 frames that implies that we have to buffer
>>> them until there is enough in the window to transmit a potentially
>>> very large packet all at once. It also conflicts with RFC6455 - the
>>> specific intent there is to not be a stream based system.
>>
>> If a ws frame *has* to be that long, not doing so would block the
>> entire HTTP/2 connection until all bytes of that frame were delivered
>> anyway. So you trade off buffering that single frame at the sender,
>> versus blocking all HTTP/2 traffic end-to-end.
>>
>> If the ws data is so critical to get transmitted fast why is that
>> single ws frame so large to begin with? surely it would be
>transmitted
>> faster as a sequence of WS + *WSDATA frames emited as the payload was
>> available to send.
>
>I agree that its inconsistent which is why I don't think it matters

I am the author of libwebsockets, we are adding http2 support at the moment.  The basic http2 serving is done and works for http, but we're all dressed up and nowhere to go in terms of treating websocket connections as just another kind of http2, since the framing is "TBD".  I am sorry I am a bit late to the party.

I think you have to take the atomic large ws frame thing as a genuine problem because http2 has the transmit credit concept.  So even if you buffered one ws frame, you can't sit there spewing as much http2 DATA frame as it needs to atomically encapsulate it, without sizing your http2 frame to suit the tx credit.

But it's OK because the implementation can transparently fragment the ws data using the ws message semantics... I think there's no choice but to take that approach.

Otherwise you get into being able to DoS even an http2 "big pipe aggregation" by just one mux element spewing an endless ws frame and blocking every other mux'd connection... it cannot be right.

>and mapping down to h2 frames as a sequence of octets would be fine.
>But you seem to both agree with my reasoning and disagree with my
>conclusion. This is confusing.
>
>>> I was suggesting that we just treat the HTTP/2 stream like the TCP
>>> connection in RFC 6455 - the conversation from stream to message
>>> based semantics and so on can take place above that in the ws
>>> implementation - and that we should still apply the transmission
>>> windows etc to ws streams.

Yes ---^ this is how it has to be I think.

>> If you do that you loose any and all benefits from HTTP/2 frames.
>> Everything from ws frame headers to data content becomes semantically
>> identical to the opaque payload of a DATA frame on an HTTP/2 CONNECT
>> request. I believe Yutaka is seeking to get away from that situation
>> where DATA frames may be split, joined or buffered at any point.
>
>Sorry, I just don't follow that. We have a primitive which appears to
>fit ws entirely, with the only caveat being that we haven't defined
>the mapping from the high level frames to the h2 primitives. If the

Yeah.

>spec identifies how ws is negotiated and framed within h2, its not
>opaque at all. And ws implementations that support raw ws (which
>they'll do for quite some time...) have to deal with tcp which offers
>no better semantics than this.

Right now if I understood it the ws connections can still negotiate themselves transparently inside http2 mux connections, using the RFC6455 upgrade on their individual session ID, do the extra RTT and tx data masking.

Formalizing how to encapsulate the same thing in http2 doesn't buy much above that... the benefit we can get is map the RFC6455 framing on to http2 native framing and get rid of the duplication simple encapsulation has (for many small frames, it would be really painful overhead actually).  So if we will do anything, it should indeed be define how to map RFC6455 framing on http2 framing.

I guess it can be done in parallel with http2 coming to an end rather than trying to block it, just by defining some new optional frame types...

-Andy

>-Rob



Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Andy Green


On 21 November 2014 10:02:28 GMT+08:00, Yutaka Hirano <[hidden email]> wrote:

>>
>> I think you have to take the atomic large ws frame thing as a genuine
>> problem because http2 has the transmit credit concept.  So even if
>you
>> buffered one ws frame, you can't sit there spewing as much http2 DATA
>frame
>> as it needs to atomically encapsulate it, without sizing your http2
>frame
>> to suit the tx credit.
>> But it's OK because the implementation can transparently fragment the
>ws
>> data using the ws message semantics... I think there's no choice but
>to
>> take that approach.
>
>Sorry I don't understand what you are proposing. Can you explain?

I'm agreeing with what was already written by someone else on the thread.

Talking about buffering huge ws frames until you have enough to issue it all in one big http2 DATA frame will not fly.

If you're using this putative ws-over-http2 scheme, and you get given a huge ws frame to transmit, you should fragment it using RFC6455 message semantics to some implementation-defined limit that is friendly for mux'd http2 transport.

>I guess it can be done in parallel with http2 coming to an end rather
>than
>> trying to block it, just by defining some new optional frame types...
>
>I agree to define a ws-dedicated frame type and use it.

Super... has anyone proposed how to map RFC6455 to http2 framing in detail yet?

-Andy

>
>On Fri, Nov 21, 2014 at 10:47 AM, Andy Green <[hidden email]> wrote:
>
>>
>>
>> On 21 November 2014 04:11:53 GMT+08:00, Robert Collins <
>> [hidden email]> wrote:
>> >On 15 October 2014 00:00, Amos Jeffries <[hidden email]>
>wrote:
>> >> -----BEGIN PGP SIGNED MESSAGE-----
>> >> Hash: SHA1
>> >>
>> >> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>> >>> On 1 October 2014 23:37, Amos Jeffries wrote:
>> >>>
>> >>>>> All the implementor discussion I've seen during the
>> >>>>>> HTTP/2 discussions has focused on how intermediaries want to
>> >>>>>> be scalable: and buffering is anti-scaling. So - is it a
>> >>>>>> pragmatic concern, or do we expect DATA stream buffering to
>> >>>>>> take place [outside of protocol gateways converting to
>> >>>>>> HTTP/1.1 where non upload can require buffering - and note
>> >>>>>> that such a gateway can't carry ws anyway unless its aware of
>> >>>>>> it, and if its aware of it, it can make sure it does not
>> >>>>>> buffer].
>> >>>>
>> >>>>
>> >>>> I think the problem is not buffering in HTTP/2 per-se but the
>> >>>> DATA frame (de-)aggregation that can happen if the frames are
>> >>>> buffered by general network conditions (ie in TCP bottlenecks).
>> >>>> This would not be good for a 1:1 relationship between DATA and
>ws
>> >>>> frames.
>> >>>>
>> >>>> Amos
>> >>>
>> >>> So hang on a second here. If we say that ws frames can't be split
>> >>> over multiple HTTP/2 frames that implies that we have to buffer
>> >>> them until there is enough in the window to transmit a
>potentially
>> >>> very large packet all at once. It also conflicts with RFC6455 -
>the
>> >>> specific intent there is to not be a stream based system.
>> >>
>> >> If a ws frame *has* to be that long, not doing so would block the
>> >> entire HTTP/2 connection until all bytes of that frame were
>delivered
>> >> anyway. So you trade off buffering that single frame at the
>sender,
>> >> versus blocking all HTTP/2 traffic end-to-end.
>> >>
>> >> If the ws data is so critical to get transmitted fast why is that
>> >> single ws frame so large to begin with? surely it would be
>> >transmitted
>> >> faster as a sequence of WS + *WSDATA frames emited as the payload
>was
>> >> available to send.
>> >
>> >I agree that its inconsistent which is why I don't think it matters
>>
>> I am the author of libwebsockets, we are adding http2 support at the
>> moment.  The basic http2 serving is done and works for http, but
>we're all
>> dressed up and nowhere to go in terms of treating websocket
>connections as
>> just another kind of http2, since the framing is "TBD".  I am sorry I
>am a
>> bit late to the party.
>>
>> I think you have to take the atomic large ws frame thing as a genuine
>> problem because http2 has the transmit credit concept.  So even if
>you
>> buffered one ws frame, you can't sit there spewing as much http2 DATA
>frame
>> as it needs to atomically encapsulate it, without sizing your http2
>frame
>> to suit the tx credit.
>>
>> But it's OK because the implementation can transparently fragment the
>ws
>> data using the ws message semantics... I think there's no choice but
>to
>> take that approach.
>>
>> Otherwise you get into being able to DoS even an http2 "big pipe
>> aggregation" by just one mux element spewing an endless ws frame and
>> blocking every other mux'd connection... it cannot be right.
>>
>> >and mapping down to h2 frames as a sequence of octets would be fine.
>> >But you seem to both agree with my reasoning and disagree with my
>> >conclusion. This is confusing.
>> >
>> >>> I was suggesting that we just treat the HTTP/2 stream like the
>TCP
>> >>> connection in RFC 6455 - the conversation from stream to message
>> >>> based semantics and so on can take place above that in the ws
>> >>> implementation - and that we should still apply the transmission
>> >>> windows etc to ws streams.
>>
>> Yes ---^ this is how it has to be I think.
>>
>> >> If you do that you loose any and all benefits from HTTP/2 frames.
>> >> Everything from ws frame headers to data content becomes
>semantically
>> >> identical to the opaque payload of a DATA frame on an HTTP/2
>CONNECT
>> >> request. I believe Yutaka is seeking to get away from that
>situation
>> >> where DATA frames may be split, joined or buffered at any point.
>> >
>> >Sorry, I just don't follow that. We have a primitive which appears
>to
>> >fit ws entirely, with the only caveat being that we haven't defined
>> >the mapping from the high level frames to the h2 primitives. If the
>>
>> Yeah.
>>
>> >spec identifies how ws is negotiated and framed within h2, its not
>> >opaque at all. And ws implementations that support raw ws (which
>> >they'll do for quite some time...) have to deal with tcp which
>offers
>> >no better semantics than this.
>>
>> Right now if I understood it the ws connections can still negotiate
>> themselves transparently inside http2 mux connections, using the
>RFC6455
>> upgrade on their individual session ID, do the extra RTT and tx data
>> masking.
>>
>> Formalizing how to encapsulate the same thing in http2 doesn't buy
>much
>> above that... the benefit we can get is map the RFC6455 framing on to
>http2
>> native framing and get rid of the duplication simple encapsulation
>has (for
>> many small frames, it would be really painful overhead actually).  So
>if we
>> will do anything, it should indeed be define how to map RFC6455
>framing on
>> http2 framing.
>>
>> I guess it can be done in parallel with http2 coming to an end rather
>than
>> trying to block it, just by defining some new optional frame types...
>>
>> -Andy
>>
>> >-Rob
>>
>>
>>


Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Yutaka Hirano


On Fri, Nov 21, 2014 at 11:42 AM, Andy Green <[hidden email]> wrote:


On 21 November 2014 10:02:28 GMT+08:00, Yutaka Hirano <[hidden email]> wrote:
>>
>> I think you have to take the atomic large ws frame thing as a genuine
>> problem because http2 has the transmit credit concept.  So even if
>you
>> buffered one ws frame, you can't sit there spewing as much http2 DATA
>frame
>> as it needs to atomically encapsulate it, without sizing your http2
>frame
>> to suit the tx credit.
>> But it's OK because the implementation can transparently fragment the
>ws
>> data using the ws message semantics... I think there's no choice but
>to
>> take that approach.
>
>Sorry I don't understand what you are proposing. Can you explain?

I'm agreeing with what was already written by someone else on the thread.

Talking about buffering huge ws frames until you have enough to issue it all in one big http2 DATA frame will not fly.

If you're using this putative ws-over-http2 scheme, and you get given a huge ws frame to transmit, you should fragment it using RFC6455 message semantics to some implementation-defined limit that is friendly for mux'd http2 transport.
Thanks.

Strictly speaking, RFC6455 allows an extension to give meaning to WebSocket frames, so merging / fragmenting frames breaks such extensions.
We discussed this problem in HyBi and many of us said "don't care".
In any case, an http/2 frame cannot be bigger than 2^24 (or 2^14 without an explicit permission), so I think we don't have to worry about DoS.
 

>I guess it can be done in parallel with http2 coming to an end rather
>than
>> trying to block it, just by defining some new optional frame types...
>
>I agree to define a ws-dedicated frame type and use it.

Super... has anyone proposed how to map RFC6455 to http2 framing in detail yet?
I think not.
I did list several ways at [1], but I deleted it from the next version[2] because HTTP/2 situation had changed.

 

-Andy

>
>On Fri, Nov 21, 2014 at 10:47 AM, Andy Green <[hidden email]> wrote:
>
>>
>>
>> On 21 November 2014 04:11:53 GMT+08:00, Robert Collins <
>> [hidden email]> wrote:
>> >On 15 October 2014 00:00, Amos Jeffries <[hidden email]>
>wrote:
>> >> -----BEGIN PGP SIGNED MESSAGE-----
>> >> Hash: SHA1
>> >>
>> >> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>> >>> On 1 October 2014 23:37, Amos Jeffries wrote:
>> >>>
>> >>>>> All the implementor discussion I've seen during the
>> >>>>>> HTTP/2 discussions has focused on how intermediaries want to
>> >>>>>> be scalable: and buffering is anti-scaling. So - is it a
>> >>>>>> pragmatic concern, or do we expect DATA stream buffering to
>> >>>>>> take place [outside of protocol gateways converting to
>> >>>>>> HTTP/1.1 where non upload can require buffering - and note
>> >>>>>> that such a gateway can't carry ws anyway unless its aware of
>> >>>>>> it, and if its aware of it, it can make sure it does not
>> >>>>>> buffer].
>> >>>>
>> >>>>
>> >>>> I think the problem is not buffering in HTTP/2 per-se but the
>> >>>> DATA frame (de-)aggregation that can happen if the frames are
>> >>>> buffered by general network conditions (ie in TCP bottlenecks).
>> >>>> This would not be good for a 1:1 relationship between DATA and
>ws
>> >>>> frames.
>> >>>>
>> >>>> Amos
>> >>>
>> >>> So hang on a second here. If we say that ws frames can't be split
>> >>> over multiple HTTP/2 frames that implies that we have to buffer
>> >>> them until there is enough in the window to transmit a
>potentially
>> >>> very large packet all at once. It also conflicts with RFC6455 -
>the
>> >>> specific intent there is to not be a stream based system.
>> >>
>> >> If a ws frame *has* to be that long, not doing so would block the
>> >> entire HTTP/2 connection until all bytes of that frame were
>delivered
>> >> anyway. So you trade off buffering that single frame at the
>sender,
>> >> versus blocking all HTTP/2 traffic end-to-end.
>> >>
>> >> If the ws data is so critical to get transmitted fast why is that
>> >> single ws frame so large to begin with? surely it would be
>> >transmitted
>> >> faster as a sequence of WS + *WSDATA frames emited as the payload
>was
>> >> available to send.
>> >
>> >I agree that its inconsistent which is why I don't think it matters
>>
>> I am the author of libwebsockets, we are adding http2 support at the
>> moment.  The basic http2 serving is done and works for http, but
>we're all
>> dressed up and nowhere to go in terms of treating websocket
>connections as
>> just another kind of http2, since the framing is "TBD".  I am sorry I
>am a
>> bit late to the party.
>>
>> I think you have to take the atomic large ws frame thing as a genuine
>> problem because http2 has the transmit credit concept.  So even if
>you
>> buffered one ws frame, you can't sit there spewing as much http2 DATA
>frame
>> as it needs to atomically encapsulate it, without sizing your http2
>frame
>> to suit the tx credit.
>>
>> But it's OK because the implementation can transparently fragment the
>ws
>> data using the ws message semantics... I think there's no choice but
>to
>> take that approach.
>>
>> Otherwise you get into being able to DoS even an http2 "big pipe
>> aggregation" by just one mux element spewing an endless ws frame and
>> blocking every other mux'd connection... it cannot be right.
>>
>> >and mapping down to h2 frames as a sequence of octets would be fine.
>> >But you seem to both agree with my reasoning and disagree with my
>> >conclusion. This is confusing.
>> >
>> >>> I was suggesting that we just treat the HTTP/2 stream like the
>TCP
>> >>> connection in RFC 6455 - the conversation from stream to message
>> >>> based semantics and so on can take place above that in the ws
>> >>> implementation - and that we should still apply the transmission
>> >>> windows etc to ws streams.
>>
>> Yes ---^ this is how it has to be I think.
>>
>> >> If you do that you loose any and all benefits from HTTP/2 frames.
>> >> Everything from ws frame headers to data content becomes
>semantically
>> >> identical to the opaque payload of a DATA frame on an HTTP/2
>CONNECT
>> >> request. I believe Yutaka is seeking to get away from that
>situation
>> >> where DATA frames may be split, joined or buffered at any point.
>> >
>> >Sorry, I just don't follow that. We have a primitive which appears
>to
>> >fit ws entirely, with the only caveat being that we haven't defined
>> >the mapping from the high level frames to the h2 primitives. If the
>>
>> Yeah.
>>
>> >spec identifies how ws is negotiated and framed within h2, its not
>> >opaque at all. And ws implementations that support raw ws (which
>> >they'll do for quite some time...) have to deal with tcp which
>offers
>> >no better semantics than this.
>>
>> Right now if I understood it the ws connections can still negotiate
>> themselves transparently inside http2 mux connections, using the
>RFC6455
>> upgrade on their individual session ID, do the extra RTT and tx data
>> masking.
>>
>> Formalizing how to encapsulate the same thing in http2 doesn't buy
>much
>> above that... the benefit we can get is map the RFC6455 framing on to
>http2
>> native framing and get rid of the duplication simple encapsulation
>has (for
>> many small frames, it would be really painful overhead actually).  So
>if we
>> will do anything, it should indeed be define how to map RFC6455
>framing on
>> http2 framing.
>>
>> I guess it can be done in parallel with http2 coming to an end rather
>than
>> trying to block it, just by defining some new optional frame types...
>>
>> -Andy
>>
>> >-Rob
>>
>>
>>


Reply | Threaded
Open this post in threaded view
|

Re: HTTP/2 and Websockets

Andy Green


On 21 November 2014 11:30:46 GMT+08:00, Yutaka Hirano <[hidden email]> wrote:

>On Fri, Nov 21, 2014 at 11:42 AM, Andy Green <[hidden email]> wrote:
>
>>
>>
>> On 21 November 2014 10:02:28 GMT+08:00, Yutaka Hirano
><[hidden email]>
>> wrote:
>> >>
>> >> I think you have to take the atomic large ws frame thing as a
>genuine
>> >> problem because http2 has the transmit credit concept.  So even if
>> >you
>> >> buffered one ws frame, you can't sit there spewing as much http2
>DATA
>> >frame
>> >> as it needs to atomically encapsulate it, without sizing your
>http2
>> >frame
>> >> to suit the tx credit.
>> >> But it's OK because the implementation can transparently fragment
>the
>> >ws
>> >> data using the ws message semantics... I think there's no choice
>but
>> >to
>> >> take that approach.
>> >
>> >Sorry I don't understand what you are proposing. Can you explain?
>>
>> I'm agreeing with what was already written by someone else on the
>thread.
>>
>> Talking about buffering huge ws frames until you have enough to issue
>it
>> all in one big http2 DATA frame will not fly.
>>
>> If you're using this putative ws-over-http2 scheme, and you get given
>a
>> huge ws frame to transmit, you should fragment it using RFC6455
>message
>> semantics to some implementation-defined limit that is friendly for
>mux'd
>> http2 transport.
>>
>Thanks.
>
>Strictly speaking, RFC6455 allows an extension to give meaning to
>WebSocket
>frames, so merging / fragmenting frames breaks such extensions.
>We discussed this problem in HyBi and many of us said "don't care".

Yeah extensions except for compression have just not come into existence.

So I also see it as don't care.  I'm not even sure it's true since the intention during ws discussion was an intermediary can fragment frames same as how tcp packets may be fragmented.

>In any case, an http/2 frame cannot be bigger than 2^24 (or 2^14
>without an
>explicit permission), so I think we don't have to worry about DoS.

... I don't see that.  If I keep spamming 16MB frames even on one stream on a consumer link your latency goes to pieces and if something is doing multiple instances of it even a big pipe will feel pain.

>> >I guess it can be done in parallel with http2 coming to an end
>rather
>> >than
>> >> trying to block it, just by defining some new optional frame
>types...
>> >
>> >I agree to define a ws-dedicated frame type and use it.
>>
>> Super... has anyone proposed how to map RFC6455 to http2 framing in
>detail
>> yet?
>>
>I think not.
>I did list several ways at [1], but I deleted it from the next

Alright I will go look at these.

The discussion is moribund somebody should probably issue a 'stalking horse' since it's easier for people to jump in and tell you you're doing it wrong ^^

-Andy

>version[2]
>because HTTP/2 situation had changed.
>
>1:
>http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-00
>2:
>http://tools.ietf.org/html/draft-hirano-httpbis-websocket-over-http2-01
>
>
>>
>> -Andy
>>
>> >
>> >On Fri, Nov 21, 2014 at 10:47 AM, Andy Green <[hidden email]>
>wrote:
>> >
>> >>
>> >>
>> >> On 21 November 2014 04:11:53 GMT+08:00, Robert Collins <
>> >> [hidden email]> wrote:
>> >> >On 15 October 2014 00:00, Amos Jeffries <[hidden email]>
>> >wrote:
>> >> >> -----BEGIN PGP SIGNED MESSAGE-----
>> >> >> Hash: SHA1
>> >> >>
>> >> >> On 14/10/2014 11:01 p.m., Robert Collins wrote:
>> >> >>> On 1 October 2014 23:37, Amos Jeffries wrote:
>> >> >>>
>> >> >>>>> All the implementor discussion I've seen during the
>> >> >>>>>> HTTP/2 discussions has focused on how intermediaries want
>to
>> >> >>>>>> be scalable: and buffering is anti-scaling. So - is it a
>> >> >>>>>> pragmatic concern, or do we expect DATA stream buffering to
>> >> >>>>>> take place [outside of protocol gateways converting to
>> >> >>>>>> HTTP/1.1 where non upload can require buffering - and note
>> >> >>>>>> that such a gateway can't carry ws anyway unless its aware
>of
>> >> >>>>>> it, and if its aware of it, it can make sure it does not
>> >> >>>>>> buffer].
>> >> >>>>
>> >> >>>>
>> >> >>>> I think the problem is not buffering in HTTP/2 per-se but the
>> >> >>>> DATA frame (de-)aggregation that can happen if the frames are
>> >> >>>> buffered by general network conditions (ie in TCP
>bottlenecks).
>> >> >>>> This would not be good for a 1:1 relationship between DATA
>and
>> >ws
>> >> >>>> frames.
>> >> >>>>
>> >> >>>> Amos
>> >> >>>
>> >> >>> So hang on a second here. If we say that ws frames can't be
>split
>> >> >>> over multiple HTTP/2 frames that implies that we have to
>buffer
>> >> >>> them until there is enough in the window to transmit a
>> >potentially
>> >> >>> very large packet all at once. It also conflicts with RFC6455
>-
>> >the
>> >> >>> specific intent there is to not be a stream based system.
>> >> >>
>> >> >> If a ws frame *has* to be that long, not doing so would block
>the
>> >> >> entire HTTP/2 connection until all bytes of that frame were
>> >delivered
>> >> >> anyway. So you trade off buffering that single frame at the
>> >sender,
>> >> >> versus blocking all HTTP/2 traffic end-to-end.
>> >> >>
>> >> >> If the ws data is so critical to get transmitted fast why is
>that
>> >> >> single ws frame so large to begin with? surely it would be
>> >> >transmitted
>> >> >> faster as a sequence of WS + *WSDATA frames emited as the
>payload
>> >was
>> >> >> available to send.
>> >> >
>> >> >I agree that its inconsistent which is why I don't think it
>matters
>> >>
>> >> I am the author of libwebsockets, we are adding http2 support at
>the
>> >> moment.  The basic http2 serving is done and works for http, but
>> >we're all
>> >> dressed up and nowhere to go in terms of treating websocket
>> >connections as
>> >> just another kind of http2, since the framing is "TBD".  I am
>sorry I
>> >am a
>> >> bit late to the party.
>> >>
>> >> I think you have to take the atomic large ws frame thing as a
>genuine
>> >> problem because http2 has the transmit credit concept.  So even if
>> >you
>> >> buffered one ws frame, you can't sit there spewing as much http2
>DATA
>> >frame
>> >> as it needs to atomically encapsulate it, without sizing your
>http2
>> >frame
>> >> to suit the tx credit.
>> >>
>> >> But it's OK because the implementation can transparently fragment
>the
>> >ws
>> >> data using the ws message semantics... I think there's no choice
>but
>> >to
>> >> take that approach.
>> >>
>> >> Otherwise you get into being able to DoS even an http2 "big pipe
>> >> aggregation" by just one mux element spewing an endless ws frame
>and
>> >> blocking every other mux'd connection... it cannot be right.
>> >>
>> >> >and mapping down to h2 frames as a sequence of octets would be
>fine.
>> >> >But you seem to both agree with my reasoning and disagree with my
>> >> >conclusion. This is confusing.
>> >> >
>> >> >>> I was suggesting that we just treat the HTTP/2 stream like the
>> >TCP
>> >> >>> connection in RFC 6455 - the conversation from stream to
>message
>> >> >>> based semantics and so on can take place above that in the ws
>> >> >>> implementation - and that we should still apply the
>transmission
>> >> >>> windows etc to ws streams.
>> >>
>> >> Yes ---^ this is how it has to be I think.
>> >>
>> >> >> If you do that you loose any and all benefits from HTTP/2
>frames.
>> >> >> Everything from ws frame headers to data content becomes
>> >semantically
>> >> >> identical to the opaque payload of a DATA frame on an HTTP/2
>> >CONNECT
>> >> >> request. I believe Yutaka is seeking to get away from that
>> >situation
>> >> >> where DATA frames may be split, joined or buffered at any
>point.
>> >> >
>> >> >Sorry, I just don't follow that. We have a primitive which
>appears
>> >to
>> >> >fit ws entirely, with the only caveat being that we haven't
>defined
>> >> >the mapping from the high level frames to the h2 primitives. If
>the
>> >>
>> >> Yeah.
>> >>
>> >> >spec identifies how ws is negotiated and framed within h2, its
>not
>> >> >opaque at all. And ws implementations that support raw ws (which
>> >> >they'll do for quite some time...) have to deal with tcp which
>> >offers
>> >> >no better semantics than this.
>> >>
>> >> Right now if I understood it the ws connections can still
>negotiate
>> >> themselves transparently inside http2 mux connections, using the
>> >RFC6455
>> >> upgrade on their individual session ID, do the extra RTT and tx
>data
>> >> masking.
>> >>
>> >> Formalizing how to encapsulate the same thing in http2 doesn't buy
>> >much
>> >> above that... the benefit we can get is map the RFC6455 framing on
>to
>> >http2
>> >> native framing and get rid of the duplication simple encapsulation
>> >has (for
>> >> many small frames, it would be really painful overhead actually).
>So
>> >if we
>> >> will do anything, it should indeed be define how to map RFC6455
>> >framing on
>> >> http2 framing.
>> >>
>> >> I guess it can be done in parallel with http2 coming to an end
>rather
>> >than
>> >> trying to block it, just by defining some new optional frame
>types...
>> >>
>> >> -Andy
>> >>
>> >> >-Rob
>> >>
>> >>
>> >>
>>
>>


12345