Re: WebSocket2

Van Catha <> Mon, 03 October 2016 16:44 UTC

Return-Path: <>
Received: from localhost (localhost []) by (Postfix) with ESMTP id 3CC7512940E for <>; Mon, 3 Oct 2016 09:44:20 -0700 (PDT)
X-Virus-Scanned: amavisd-new at
X-Spam-Flag: NO
X-Spam-Score: -9.305
X-Spam-Status: No, score=-9.305 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_ADSP_CUSTOM_MED=0.001, DKIM_SIGNED=0.1, HEADER_FROM_DIFFERENT_DOMAINS=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_SORBS_SPAM=0.5, RP_MATCHES_RCVD=-2.996, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001, T_DKIM_INVALID=0.01] autolearn=ham autolearn_force=no
Authentication-Results: (amavisd-new); dkim=fail (2048-bit key) reason="fail (body has been altered)"
Received: from ([]) by localhost ( []) (amavisd-new, port 10024) with ESMTP id IWIDmEN7PmCJ for <>; Mon, 3 Oct 2016 09:44:18 -0700 (PDT)
Received: from ( []) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) by (Postfix) with ESMTPS id 567FF12940C for <>; Mon, 3 Oct 2016 09:44:17 -0700 (PDT)
Received: from lists by with local (Exim 4.80) (envelope-from <>) id 1br6Hh-00030s-1l for; Mon, 03 Oct 2016 16:40:09 +0000
Resent-Date: Mon, 03 Oct 2016 16:40:09 +0000
Resent-Message-Id: <>
Received: from ([]) by with esmtps (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1br6Hc-0002Sl-Q5 for; Mon, 03 Oct 2016 16:40:04 +0000
Received: from ([]) by with esmtps (TLS1.2:RSA_AES_128_CBC_SHA1:128) (Exim 4.80) (envelope-from <>) id 1br6HY-0004ed-JR for; Mon, 03 Oct 2016 16:40:02 +0000
Received: by with SMTP id n189so94741180qke.0 for <>; Mon, 03 Oct 2016 09:39:40 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=OdbETiNcyx6GNmGae4DDhG/mJdKerV47aqkq4mE04ow=; b=zMhyGVcx9AaVzEpOgVwGIpcJUnpFJRYBH42fA8L6AgCZtTp1O9fqa2UeKbfphDrUQD b7bNidEZN7GVuo6Vt0ehavQgHPKHh+6gRBN2gS0MEghYHPj0W7MTNNoLhMvEERyDiOGC DMHXFGOByYkX4ni8IlM/s1WYvY2PGxuXwz6gG2qotZfdsvjV4q87N7sMwLO73pyroqtj 8m0UvEAKsJyLF8jDq+0QuHWly6t7YY3/yVo/3wr+3wfe00ZOPGK9Y5cAXStj5KgDLq/r g2EdXwKgw4G/9IrA+Nel31HBLvUgIiKQZF+gc1WN8YsIW6jsRNXHyixzPDSA20snRkmk M3IA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=OdbETiNcyx6GNmGae4DDhG/mJdKerV47aqkq4mE04ow=; b=TG+lqqIt+MXhZRpHWOK1NQTFVkTyJpmifiKfGCSxQGpCfEdR2yd8dPPmxc8d5lELJk inW62IaTLVMXikAml6sjtXKyBlIUGvLasuDcnUo/7rpavl6uTN7AvELg0MUfN2p4Le2O U7fCAimMSPlYRxnwwswpU3v3P61Udf5o6Sigvf/NoSkoEdFUz9YhV7cpJgxTg0I0YWH8 XQtdbn09QE3qtU99tsdbnkCpqiJLRlc352cxwIiQJhfXe5iyGSxpCdOuEA0JeisbIHnW Kz+QAs7hK3tAQgvQwqtocVYz+PVdP7Nc/osLujTv8bT+MSCHtVQLBArMFNAxOcFH+1RK 6/eA==
X-Gm-Message-State: AA6/9RmZLelVL3/8kjfVpuhrgUTcbrkIUEtk32q2IXo3FOIV6xmYt0JK4/h6FOsTdj++MTd/sRpchJszgwYMbw==
X-Received: by with SMTP id z198mr20482212qka.194.1475512774662; Mon, 03 Oct 2016 09:39:34 -0700 (PDT)
MIME-Version: 1.0
Received: by with HTTP; Mon, 3 Oct 2016 09:39:34 -0700 (PDT)
In-Reply-To: <>
References: <> <> <> <> <> <> <> <>
From: Van Catha <>
Date: Mon, 3 Oct 2016 12:39:34 -0400
Message-ID: <>
To: Kari Hurtta <>
Cc: Ilari Liusvaara <>, HTTP working group mailing list <>
Content-Type: multipart/alternative; boundary=001a114a7972cba0f1053df89601
Received-SPF: pass client-ip=;;
X-W3C-Hub-Spam-Status: No, score=-4.7
X-W3C-Scan-Sig: 1br6HY-0004ed-JR 03364334c2f6a21a54d4a12265bc3c01
Subject: Re: WebSocket2
Archived-At: <>
X-Mailing-List: <> archive/latest/32453
Precedence: list
List-Id: <>
List-Help: <>
List-Post: <>
List-Unsubscribe: <>

Amos Jeffries

> I believe the relevant expert(s) are reading this thread already.
> That is the more likely reason a negotiated extension is unlikely to
> happen. If it is not needed at all, then it might be easier not to bother.

I was not aware using a custom method was allowed, if that is the case,
CONNECT, UPGRADE, WS2, etc all work.

Kari Hurtta

> Well, I think the following would work and avoid SETTINGS:
> -> :method ws2
> -> :scheme wss
> -> :authority foo.example
> -> :path /bar
> -> <optional extra parameters, e.g. compression support>
> <- :status 200
> <- sec-ws2-ack 1
> <- <optional negotiated extras>

> And unsuccessful request would elict a HTTP response code:
> - 405 for endpoint not supporting Websockets2
> - 404 for endpoit does not exist
> - 403 for "I don't want to talk to you"
> - 401 for "identify yourself".

> As for 301/302/307/308 responses, redirect across schemes would be
> error (channel open failed). And one would need to be very careful about
> redirects out of server's authority (probably channel open failed).

This looks really optimal.

> ( if :scheme is wss, then proxy gets
>   :method = CONNECT
>   :authority = foo.example:443
>   and there is no :scheme or :path
> )

Again a good option.


About Proxies:
I assumed the concern was with forward / reverse proxies like NGINX
forwarding http/2 to http.

Afaik HTTP/2 browser only allow using TLS, so a HTTP transparent proxy will
not be able to "proxy" anything unless the reverse proxy serves a MITM
certificate.  I do not think this is a common enough use case.

About Settings frame:
If the idea behind this is to make WebSocket2 compatible over HTTP/1.1 then
that is part of the reasons why I advocate to avoid SETTINGS frame.

If WebSocket2 can be negotiated and used in such a way to avoid locking to
the transport layer, it can easily be used in HTTP/1.1 as well.

An option is to define a WebSocket2 spec RFC, then define individual RFCs
for WebSocket2 over X|Y|Z.

About New HTTP/2 Frame Type:
If a new frame type is to be introduced it severly complicates things, as
anything WebSocket2 related to this frame is not applicable. This new frame
type would fulfill the role of data streaming.  It should be applicable not
only to websockets2 but also to HTTP/1.1's Chunked-Encoding.

There would be no standard on using this new frame type, and
implementations that build off HTTP/2 such as QUIC would be left in the
dark on how to use it.

Also HTTP/1.1 would have no chance at getting WebSocket2. If such a need
were to ever exist, currently I am not considering it at any priority level.

About Payload Length optimizations:
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.

Using flags to specify how many bits the payload size is we can remove some
flexibily but also decrease final system level packet size:

RSV now becomes 6 bits.
TYPE now becomes 2 bits. We have room for 1 more frame type.

Last 2 RSV bits are Payload Length. 0 for no length (error frame), 1 for 1
byte, 2 for 2 byte, 3 for 4 byte.

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

First 2 RSV bits are decompressed payload size in the case of LZ4 or
reserved for future use by compression.

This also has the benefit of not requiring to keep a serverside state for
LZ4 compressed payloads; for anyone that would have a sane usecase for that

Before a small LZ4 Text frame looked like this:
b00000000 0x00 0x00 0x00 0x09 0x00 0x00 0x00 0x05 0xAE 0xB4

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

>From 11 bytes down to 5.

The reason I think a 32bit UINT max is a good top value is that gives you
about 4G~ of a maximum payload.  If you have a payload greater than 4G
there is no sane way a client API can process that. Even 4G is way too much

Where to go from here:
What do you think if I update the RFC with contributors for the new
handshaking we discussed and possibly this new way to do the payload if we
all like it?

A possible approach is to break up the WebSocket2 framing into its own RFC,
will cover compression methods and framing.

A seperate RFC would cover transporting WebSocket2 over HTTP/2, now this
seperate RFC can involve custom HTTP/2 frame types, header based
authentication, negotiating compression, custom settings frames, proxy
support, etc?

On Mon, Oct 3, 2016 at 12:40 AM, Kari Hurtta <>

> Ilari Liusvaara <>om>: (Sun Oct  2 20:19:05 2016)
> > > > Well, I think the following would work and avoid SETTINGS:
> > > >
> > > > -> :method ws2
> > > > -> :scheme wss
> > > > -> :authority foo.example
> > > > -> :path /bar
> > > > -> <optional extra parameters, e.g. compression support>
> > > > <- :status 200
> > > > <- sec-ws2-ack 1
> > > > <- <optional negotiated extras>
> > >
> > > If we can also assume that proxy does not ignore
> > >    :method = ws2
> > >    :scheme = ws
> > > then this may work.
> >
> > Oh yeah, that only works against dodgily implemented origins, not WS2-
> > unsupporting proxies (that do something else than just realtime
> > forwarding of unknown methods).
> >
> >
> > If one is worried about the latter, one would need the SETTING then
> > (one only needs to have server end signal support, since it is a
> > capability server has that client may or may not use)..
> >
> If forward proxy (= proxy configured on browser) supports both http and
> ftp,
> then it is checking :scheme. If it supports only http (and tunneling with
> CONNECT), then it can be lazy.
> Reverse proxies (which DNS gives from :authority) are more likely
> to be lazy.  These are either http/2 ⇒ http/1.1 or http/2 ⇒ http/2.
> Reverse proxies may be also TLS termination point. So wss is not tunneled.
> "Transparent" proxies; then perhaps SETTINGS does not work either.
> > -Ilari
> / Kari Hurtta