Re: WebSocket2

Kari and other participants, which way do you think would be better:

RFC of Websocket2  updates RFC 7540 (HTTP/2)
RFC of Websocket2 registers new method.

Using it this way you proposed would it require adding
as well?

I think the SETTINGS_WEBSOCKET_CAPABLE can be included in the RFC and if
a middle box does not implement support for it, as long as it forwards
everything correctly
AND the response contains the sec-ws2-error header, there should not be

> > Ilari Liusvaara suggested sec-ws2-ack for check that
> > ":scheme" is not ignored (if I remember correctly).

If the websocket2 response returns the custom error header, this is similar
to the sec-ws2-ack.
Example on success we MUST return OKAY|SUCCESS.

sec-ws2-error: OKAY

Without this error header how can the client know what went wrong during
ws2 negotiation?


> Are you suggesting that the WS2/h2 should be indistinguishable from
HTTP1.1/h2 from
> intermediaries and server without knowledge of the websocket2- headers or
> application level knowledge? Or just suggesting that we can reduce
complexity by
> ignoring all the v2-v1 bridging at proxies?
> Do you have any strong opinion about how WS2 should be exposed on the web
> The WebSocket API, some brand new API? Or are you only interested in
defining a
> standardized messaging protocol to be layered over HTTP2 and QUIC to
utilize their
> power?

Standardized protocol or not is irrelevant.  I was simply considering the
and what would work.  QUIC uses different negotiation and transport frames
then HTTP/2
does (also QUIC does not have HTTP/2 SETTINGS frames). I was proposing
ideas at
tackling the problem to make WebSocket2 work across different transport

> > There is a particular use case where if you sent lots of small messages
that end
> > up in a single HTTP/2 DATA frame or a single system level packet, there
is an
> > overhead of 3 extra bytes and 6 for LZ4 compressed payloads.

> How does this 3 break down?

> Reading the following revised header proposal, I looks the minimum is 2
> - 2 LZ4 decompressed payload length field's length bits
> - 2 compression bits
> - 2 payload length field's length bits
> - 2 type bits
> - 1 octet at minimum for text and binary message
> and 2 + 4 (decompressed byte size) = 6 for LZ4?

I made a typo in the example:

> Now it can look like:
> b01010100 0x09 0x05 0xAE 0xB4

Should be b01010100 0x03 0x05 0xAE 0xB4

The old proposal used 32 bits for payload length and if LZ4 32 bits for
size. The new way I proposed specifies how many bits those will be by
setting bits
in the 8 bit header. So instead of forcing 32 bits always, we can have

Value of 0 in the payload length (bxxxx00xx) signifies no payload length.

The minimum size of a frame is 1 byte.  Which would be a text or binary
frame and
look like:


> To me, 4 octet fixed-length payload length header looks competitive for
> simplicity, but this variable length doesn't compared to the RFC 6455
> encoding. I understand it ended up to look weird, but it has good
> power and efficiency, and there're existing code resources developed for
> implementing RFC 6455. What do you think about just using RFC 6455's
length format?

On all accounts RFC 6455 payload length is great.  It also would free
up 2 bits in the header.

Since the MASK bit is gone (?), maybe it can gain an extra bit.  Also a
max payload size I think is too much, will we ever want to send any message
then 4.3~ gigabyte? I think a MAX_SIZE should be imposed, and one way to do
without imposing a MAX_SIZE spec is to use a defined amount of bits for the

Both the LZ4 decompressed size and Payload Length can be replaced with the
RFC 6455 way
if the mask bit can be freed.

> > Second last 2 RSV bits are for compression.   0 is no compression, 1 is
lz4, 2 is
deflate.  3 is reversed.

> Unless there we expect needs for switching between the two or more
> algorithms in a single connection, we don't need to give a dedicated bit
for each
> algorithm.

> The first 2 RSV bits could be also defined as generic compression
parameter field.

I thought about this, and it does add a nice amount of flexibility at the
cost of 2
bits.  For example if your streaming LZ4 compressed data which is often
1000 bytes+ per message but
occasionally get a less than 20 byte message (that gets framed), specifying
to not
compress that frame would see a performance/+size benefit.

I think we can all agree we do not want to handle decompression in the

On Wed, Oct 5, 2016 at 1:28 AM, Takeshi Yoshino <> wrote:

> Hi Kari,
> I just remembered that you gave some feedback to Yutaka's proposal in
> 2014. Thanks.
> On Wed, Oct 5, 2016 at 12:20 AM, Kari Hurtta <
> > wrote:
> <snip>
>> I contemplated SETTINGS as:
>>   from HTTP/2 server ⇒  HTTP/1 client direction
>>   ∘ Promises that HTTP/2 server checks ":scheme"
>>     (and specially "wss" and "ws")
>>   ∘ Acknowledges that DATA frames for
>>     ":scheme" = "wss" and "ws" are handled
>>     as bidirectional traffic (similar than
>>     ":method" = "CONNECT").
>>     In other words these DATA drames do
>>     NOT form HTTP request body from client
>>     and DATA drames do not form
>>     HTTP response body from server
>>     (on cases ":scheme" = "wss" and "ws").
>>     not promise that HTTP/2 server
>>     accepts ":scheme" = "wss" or "ws".
> Yutaka's proposal tried to represent the same guarantee by using the
> combination of the client to server direction SETTINGS and the response
> status code.
> I chatted with Yutaka offline. He don't remember the background fully, but
> we guess we chose to let the client send SETTINGS because we want to start
> sending WebSocket handshake before waiting for response from the server to
> reduce the initial latency. Such an attempt may result in failure, but
> worth doing for some latency sensitive applications.
> There're two approaches to realize this:
> (a) let the server send SETTINGS and let the client send handshake
> speculatively without waiting for the SETTINGS
> (b) let the client send SETTINGS and then send handshake speculatively,
> and let the server determine the response status code based on whether or
> not it has received SETTINGS as specified in Yutaka's I-D.
> (a) still gives the client path check result before receiving the
> WebSocket handshake response, but it's not good that the server cannot know
> whether the path was good or not before accepting the WebSocket handshake.
> One more thing to note is that we were investigating whether we could
> relax the requirement of the WebSocket API that messages cannot be sent
> before receiving handshake response, when h2 is used. The server needs to
> process these speculative messages without determining whether the the path
> was good for WS/h2 if we adopt (a).
> One small benefit of (b) is that there wouldn't be any
> SETTINGS_WEBSOCKET_CAPABLE traffic if the client doesn't want to use WS.
> Now I think combining (a) and (b) is the best given the concern that the
> server may forget to investigate the SETTINGS correctly but still reply to
> a WebSocket handshake with non 501 status code.
> <snip>
>> > :scheme is needed, yes.
>> >
>> > Not sure about need for "sec-ws2-ack". For WebSocket/TCP, we employed
>> the
>> > Sec-WebSocket-Key/Accept challenge/response in order to prevent the
>> > WebSocket protocol from being abused for cross protocol attacks e.g.
>> SMTP.
>> > If all the intermediaries and servers correctly investigate the :scheme
>> > header and don't get confused, "sec-ws2-ack" is unnecessary. Regarding
>> > ws/h2-RFC6455 bridging, a correctly implemented intermediary facing
>> ws/h2
>> > capable node and ws/h2 non-capable node would just perform RFC 6455
>> > handshake as Kari suggested. So, no problem.
>> Ilari Liusvaara suggested sec-ws2-ack for check that
>> ":scheme" is not ignored (if I remember correctly).
> Yeah. I understood so and therefore I said "If all the intermediaries and
> servers correctly investigate the :scheme header and don't get confused,".
> <snip>

Received on Wednesday, 5 October 2016 16:29:36 UTC