Subject: Re: Working Group Last Call: Bootstrapping WebSockets with HTTP/2

From: Loïc Hoguin <[email-masked]>
Date: Tue, 3 Apr 2018 16:17:34 +0200

On 03/28/2018 11:48 PM, Mark Nottingham wrote:
> Hi everyone,
> 
> Patrick (as editor) has incorporated the discussion from London and believes this is ready for WGLC; there are no open issues.
> 
> Please have a look at:
>    https://tools.ietf.org/html/draft-ietf-httpbis-h2-websockets-01
> 
> ... and bring up any issues on-list or on its issues list; likewise statements of support (or otherwise) for publication on-list would be appreciated.

Hello,

I am finalizing a server implementation. Just tried it against Chrome 
and things work as intended, with and without permessage-deflate.

I was a little surprised to see that the value for 
SETTINGS_ENABLE_CONNECT_PROTOCOL (0x8) is only defined in the IANA 
considerations.

I would +1 the need for some language on the END_STREAM flag, including 
how endpoints should behave when END_STREAM (or RST_STREAM) is sent on 
the stream without a close frame. I assume it's the same behavior as if 
an HTTP/1.1 Websocket connection was improperly closed but it would be 
nice to have confirmation.

Thanks for the great spec!

Cheers,

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

---

From: Alessandro Ghedini <[email-masked]>
Date: Tue, 3 Apr 2018 18:17:10 +0100

Hello,

Need a clarification regarding section 5. It says:

   Implementations using this extended CONNECT to bootstrap WebSockets
   do not do the processing of the [RFC6455] Sec-WebSocket-Key and Sec-
   WebSocket-Accept headers as that functionality has been superseded by
   the :protocol pseudo-header.

does that mean that a transparent proxy (say, a CDN, as opposed to a
traditional HTTP CONNECT proxy) that proxies WS connections and speaks HTTP/2
with the client but HTTP/1 with the origin server, is expected to generate
-Key and validate -Accept itself? Might be worth mentioning this in section 7
as well.

Cheers

---

From: Andy Green <[email-masked]>
Date: Wed, 04 Apr 2018 01:32:26 +0800

On April 4, 2018 1:17:10 AM GMT+08:00, Alessandro Ghedini <[email-masked]> wrote:
>> Patrick (as editor) has incorporated the discussion from London and
>believes this is ready for WGLC; there are no open issues.
>> 
>> Please have a look at:
>> ... and bring up any issues on-list or on its issues list; likewise
>statements of support (or otherwise) for publication on-list would be
>appreciated.
>
>Hello,
>

Yes it means that's solely a problem for the h1-speaking side to fake up.  The h2-speaking side doesn't have that ws upgrade handshake concept and no state from it is used on that side.

-Andy

---

From: Alessandro Ghedini <[email-masked]>
Date: Tue, 3 Apr 2018 19:10:05 +0100

On Thu, Mar 29, 2018 at 11:38:35AM -0400, Bence Béky wrote:
> Hi,
> 
> I would like to propose to add some language to the specification about
> END_STREAM flag on DATA frames.  The example in Section 5.1
> <https://tools.ietf.org/id/draft-ietf-httpbis-h2-websockets-01.html#rfc.section.5.1>
> indicates END_STREAM on the last DATA frames, but these is no other mention
> of this flag.  Chromium's implementation currently does not set the
> END_STREAM flag on any DATA frames sent, but instead resets the stream when
> it's destructed, which I do not believe is the most elegant approach.
> 
> Something along the lines of "Peers MUST set the END_STREAM flag (defined
> in RFC7540 Section 6.1) on any DATA frame sent that contains the entirety
> of or the last fragment of a WebSocket Close frame (defined in RFC6455
> Section 5.5.1).", appended to the end of Section 5, just above 5.1.

As worded, in the aforementioned HTTP/2<->HTTP/1.1 transparent proxy case, this
would require the proxy to inspect and parse the WS frames to detect when the
HTTP/1.1 origin (or client) sends a Close frame, instead of just blindly
proxying data as is currently the case for HTTP/1.1<->HTTP/1.1. So I'd relax
the MUST to a SHOULD, or explicitly exclude proxies from the requirement.
Otherwise looks good to me.

Cheers

---

From: Andy Green <[email-masked]>
Date: Wed, 04 Apr 2018 02:40:52 +0800

>the MUST to a SHOULD, or explicitly exclude proxies from the

Ws close frames are entirely optional, closing the h1 connection to logically end the ws link is also prone to happening at any time.  So I agree no point with the MUST, RST_STREAM will also have to be an equally legit option since it may be no CLOSE will come.  Then the intermediary can just have the simple policy of RST_STREAM when the h1 link goes away.

-Andy

---

From: Patrick McManus <[email-masked]>
Date: Tue, 03 Apr 2018 18:46:34 +0000 (UTC)

I don't think we need to add new normative language here - just some
explanatory text that would be helpful.

The model is that the h2 stream is treated like the h1 connection. RST and
END_STREAM have direct h1 connection correlaries (i.e. TCP RST and TCP FIN)
and the handling should be the same (modulo scope of stream vs connection).
I can add an explainer sentence without adding requirements or restating
(perhaps incorrectly?) what 6455 has to say.

On Tue, Apr 3, 2018 at 2:40 PM, Andy Green <[email-masked]> wrote:

> Ws close frames are entirely optional, closing the h1 connection to
> logically end the ws link is also prone to happening at any time.  So I
> agree no point with the MUST, RST_STREAM will also have to be an equally
> legit option since it may be no CLOSE will come.  Then the intermediary can
> just have the simple policy of RST_STREAM when the h1 link goes away.
>
> -Andy
>

---

From: Loïc Hoguin <[email-masked]>
Date: Wed, 4 Apr 2018 14:43:35 +0200

> ... and bring up any issues on-list or on its issues list; likewise statements of support (or otherwise) for publication on-list would be appreciated.

Assuming a resource is only configured for Websocket use, how would you 
reject incoming HTTP/2 requests that don't use the extended CONNECT? Or 
requests that use the extended CONNECT but with an incorrect :protocol 
value? I have been using 426 with HTTP/1.1 but it only seems adequate 
for the HTTP/1.1 Upgrade mechanism.

How would you reject extended CONNECT requests in the case where the 
server is properly configured to accept them, the client's request is 
correct but the resource configured for the given :path refuses to use 
Websocket? In HTTP/1.1 requests the Upgrade header could be ignored and 
a normal HTTP response sent back. Would you recommend using the status 
code 405 for HTTP/2?

Cheers,

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

---

From: Patrick McManus <[email-masked]>
Date: Wed, 04 Apr 2018 13:11:34 +0000 (UTC)

On Wed, Apr 4, 2018 at 8:43 AM, Loïc Hoguin <[email-masked]> wrote:

> reject incoming HTTP/2 requests that don't use the extended CONNECT?

I think you're asking specifically about a CONNECT request on a resource
that expects h2ws but doesn't include the new pseudoheader? I would
probably return a 400.

> Or requests that use the extended CONNECT but with an incorrect :protocol
> value? I have been using 426 with HTTP/1.1 but it only seems adequate for
> the HTTP/1.1 Upgrade mechanism.
>

yeah, I think a generic response code is your best bet here too. I'm
curious, do you think the 426 added anything of value (beyond human
readable info which can go in the message body) to the original error path?
i.e. could a client automatically do anything with that?

> Websocket? In HTTP/1.1 requests the Upgrade header could be ignored and a
> normal HTTP response sent back. Would you recommend using the status code
> 405 for HTTP/2?

if the resource doesn't support the CONNECT method, then 405 is a good
choice imo

---

From: Loïc Hoguin <[email-masked]>
Date: Wed, 4 Apr 2018 16:26:09 +0200

On 04/04/2018 03:11 PM, Patrick McManus wrote:
> 
> 
> On Wed, Apr 4, 2018 at 8:43 AM, Loïc Hoguin <[email-masked] 
> <mailto:[email-masked]>> wrote:
> 
> 
>     Assuming a resource is only configured for Websocket use, how would
>     you reject incoming HTTP/2 requests that don't use the extended CONNECT?
> 
> 

Sorry. I meant a GET or other non-CONNECT. I guess a 405 would be the 
way to go for this particular case.

For CONNECT requests lacking a :protocol pseudoheader but containing a 
:scheme or :path I reject them as malformed very early on as per 
https://tools.ietf.org/html/rfc7540#section-8.3

>     Or requests that use the extended CONNECT but with an incorrect
>     :protocol value? I have been using 426 with HTTP/1.1 but it only
>     seems adequate for the HTTP/1.1 Upgrade mechanism.
> 
> 
> readable info which can go in the message body) to the original error 
> path? i.e. could a client automatically do anything with that?

In Websocket's case I have not seen it be useful in practice beyond 
human readable info.

In theory if the 426 response contained Upgrade: websocket and a 
sec-websocket-protocol header it could be potentially useful to 
automatically detect functionality (like a REST API also having a 
Websocket endpoint for STOMP or MQTT) but I haven't heard of anyone 
doing this in practice. This could be described in the response body anyway.

400 it is.

>     server is properly configured to accept them, the client's request
>     is correct but the resource configured for the given :path refuses
>     to use Websocket? In HTTP/1.1 requests the Upgrade header could be
>     ignored and a normal HTTP response sent back. Would you recommend
>     using the status code 405 for HTTP/2?
> 
> 

Thanks!

Cheers,

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