Subject: Call for Adoption: Bootstrapping WebSockets with HTTP/2

From: Mark Nottingham <[email-masked]>
Date: Wed, 22 Nov 2017 18:35:09 +1100

As discussed in Singapore, this is a Call for Adoption of Bootstrapping WebSockets with HTTP/2:
  https://tools.ietf.org/html/draft-mcmanus-httpbis-h2-websockets-02

So far there seems to be strong interest in this draft; please forward any further thoughts (both for or against) on list in the next week, when we'll make a decision.

Cheers,

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

---

From: Andy Green <[email-masked]>
Date: Wed, 22 Nov 2017 16:47:16 +0800

On November 22, 2017 3:35:09 PM GMT+08:00, Mark Nottingham <[email-masked]> wrote:
>So far there seems to be strong interest in this draft; please forward
>any further thoughts (both for or against) on list in the next week,
>when we'll make a decision.

For great justice!

I have already pushed a server-side implementation of -02 draft on libwebsockets in the expectation a client implementation for it will appear soon so it can be tested.

-Andy

---

From: Willy Tarreau <[email-masked]>
Date: Wed, 22 Nov 2017 10:01:03 +0100

On Wed, Nov 22, 2017 at 06:35:09PM +1100, Mark Nottingham wrote:
> So far there seems to be strong interest in this draft; please forward any
> further thoughts (both for or against) on list in the next week, when we'll
> make a decision.

Let's adopt it and close the gap between h1 and h2!

Willy

---

From: Lucas Pardue <[email-masked]>
Date: Wed, 22 Nov 2017 09:44:29 +0000

I support the idea and would be interested in experimenting with this at the (web)application layer.

> -----Original Message-----
> From: Mark Nottingham [mailto:[email-masked]]
> Sent: 22 November 2017 07:35
> To: HTTP Working Group <[email-masked]>
> Subject: Call for Adoption: Bootstrapping WebSockets with HTTP/2
>

---

From: Stefan Eissing <[email-masked]>
Date: Wed, 22 Nov 2017 11:12:23 +0100

+1

> Am 22.11.2017 um 10:01 schrieb Willy Tarreau <[email-masked]>:
>

---

From: Göran Eriksson AP <[email-masked]>
Date: Wed, 22 Nov 2017 12:37:26 +0000

+1

Please clarify relation, if any, to grpc, https://github.com/improbable-eng/grpc-web

Regards
Göran

On 2017-11-22, 08:43, "Mark Nottingham" <[email-masked]> wrote:

---

From: Salvatore Loreto <[email-masked]>
Date: Wed, 22 Nov 2017 13:54:19 +0000

+1

-----Original Message-----
From: Willy Tarreau [mailto:[email-masked]] 
Sent: den 22 november 2017 10:01
To: Mark Nottingham <[email-masked]>
Cc: HTTP Working Group <[email-masked]>
Subject: Re: Call for Adoption: Bootstrapping WebSockets with HTTP/2

Willy

---

From: James M Snell <[email-masked]>
Date: Wed, 22 Nov 2017 06:14:52 -0800

While our policy is not to impl protocol features until they go to rfc, I
will plan on implementing the extended CONNECT protocol bits in node.js
core assuming this moves forward. I will leave the higher level websockets
specific bits to userland to implement.

---

From: Wenbo Zhu <[email-masked]>
Date: Wed, 22 Nov 2017 10:16:38 -0800

> Please clarify relation, if any, to grpc, https://github.com/improbable-

I authored the grpc-web spec
<https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md>.

For this audience (http-wg, hybi), grpc-web is mainly a F/W concern.

> any further thoughts (both for or against) on list in the next week, when
> we'll make a decision.
>
>

---

From: Wenbo Zhu <[email-masked]>
Date: Wed, 22 Nov 2017 10:29:54 -0800

+1   on this note.

Given HTTP/1.1 or RFC6455 won't go away, a direct tunneling approach
actually simplifies the Web (considering all the frameworks/proxies out
there) v.s. defining a more lightweight wire format for Websockets over
http/2.

With the introduction of "extended connect method", the title could have
read s/websockets/TCP protocols/ ... ?

Also, for section 4, could rationales on not defining a new method be
summarized?

Thanks.

On Wed, Nov 22, 2017 at 1:01 AM, Willy Tarreau <[email-masked]> wrote:

> any

---

From: Loïc Hoguin <[email-masked]>
Date: Fri, 24 Nov 2017 10:52:42 +0100

Hello,

> So far there seems to be strong interest in this draft; please forward any further thoughts (both for or against) on list in the next week, when we'll make a decision.

I've been putting some thoughts into implementing this and there's one 
difference betwwen h1-websocket and h2-websocket that I'm uneasy about: 
in h1 the server could receive a Websocket upgrade request, ignore it 
and send a normal 200 response with a representation of the resource. In 
h2 it can only error out.

I feel that this difference in behavior ought to be pointed out in the 
RFC because depending on how the server is implemented you need to be 
careful about this.

For example my server currently receives a Websocket upgrade request and 
starts processing it like any normal request (h1 or h2): by passing it 
to user code and letting the user decide what to do: upgrade or not. The 
user could very well send a 200 response here.

Now with h2 I would like to keep this same interface however I cannot 
allow sending a 200 response anymore because a 200 response to CONNECT 
means we accept the Websocket connection. If I see the user try to 
handle the request as a normal HTTP request I have to fail the CONNECT, 
otherwise proceed with the upgrade. This is in contrast with h1 where 
the user can do what they want without such restrictions.

To summarize:

- h1 ws upgrade: OK to either upgrade or ignore the upgrade and send 200
- h2 ws upgrade: upgrade is via a 200 response, can't ignore the upgrade 
request and respond with a representation of the resource, be careful!

***

I also have a nitpick:

    [RFC6455] requires the use of Connection and Upgrade headers that are
    not part of HTTP/2.  They MUST not be included in the CONNECT request
    defined here.

Probably should be a "MUST NOT".

Thanks,

-- 
Loïc Hoguin
https://ninenines.eu

---

From: Andy Green <[email-masked]>
Date: Fri, 24 Nov 2017 18:58:55 +0800

> user could very well send a 200 response here.

libwebsockets generally has the same approach to pass things to a 
user-provided callback to decide what to do.  But eg, we have different 
callback reasons coming according to the connection upgrade state; HTTP 
connections send different callback reasons for established / rx / 
writable / close than do connections in the ws state for example.

> the user can do what they want without such restrictions.

To implement the CONNECT processing for this, lws parses it internally 
and filters on the upgrades it understands, so lws will fail it out if 
it's not exactly upgrading to "websocket" and lws will send the 200 if 
it likes it, and adapt the connection state to ws-over-h2.

> To summarize:

Step zero: this implementation that doesn't actually understand and 
handle CONNECT upgrades wrongly sent the nondefault SETTING that says 
that it does understand them.

> request and respond with a representation of the resource, be careful!

It can do that... but the connection won't work because it's not 
upgraded to ws... it's not half-working either, it's not sending ws 
framing.  So the guy writing the user code will very quickly notice no 
ws packets are passing.

IIUI he can't accidentally fall into this because he has to send the 
non-default SETTING enabling it.  So we are just saying "implementations 
may be broken" I think...  (no doubt mine amongst them until it can be 
tested on a compliant client).

-Andy

---

From: Loïc Hoguin <[email-masked]>
Date: Fri, 24 Nov 2017 13:30:50 +0100

On 11/24/2017 11:58 AM, Andy Green wrote:
>>> So far there seems to be strong interest in this draft; please 
>>> forward any further thoughts (both for or against) on list in the 
>>> next week, when we'll make a decision.
>>
>> difference betwwen h1-websocket and h2-websocket that I'm uneasy 
>> about: in h1 the server could receive a Websocket upgrade request, 
>> ignore it and send a normal 200 response with a representation of the 
>> resource. In h2 it can only error out.
>>
>> For example my server currently receives a Websocket upgrade request 
>> and starts processing it like any normal request (h1 or h2): by 
>> passing it to user code and letting the user decide what to do: 
>> upgrade or not. The user could very well send a 200 response here.
> 

An h1 Websocket upgrade is first and foremost an HTTP request so it's 
treated as such in my server. Only after the 101 response has been sent 
does it stop being treated as a request and becomes a Websocket 
connection. There's server logic and callbacks specific to Websocket at 
that point.

My concerns are about the part of the logic where we are still dealing 
with HTTP (before accepting and performing the upgrade) where h1 and h2 
behaviors are subtly different.

>> handle the request as a normal HTTP request I have to fail the 
>> CONNECT, otherwise proceed with the upgrade. This is in contrast with 
>> h1 where the user can do what they want without such restrictions.
> 

My first implementation will be specific to Websocket and handle it 
automatically, therefore if it's not a CONNECT for Websocket or is 
missing required headers it can immediately fail.

However if it's a correct Websocket CONNECT I still need to route the 
request to the resource, call the user code and see if it accepts an 
upgrade to Websocket. Anything could happen in the user code (which uses 
the same interface for both h1 and h2) and I need to be ready for it.

> that it does understand them.

The implementation does understand CONNECT upgrades as stated in the 
document. What it does not do properly is handle edge cases that exist 
because of a difference in behavior between h1 and h2 Websocket 
upgrades. Having these differences clearly listed in the document can 
help avoid implementation issues.

To be clear I don't have an issue with the way the upgrade is performed. 
I just think adding an extra section would help implementers avoid 
falling into pitfalls.

-- 
Loïc Hoguin
https://ninenines.eu