Subject: Re: [hybi] WebSocket over HTTP/2.0 protocol negotiation

From: Yutaka Hirano <[email-masked]>
Date: Tue, 4 Feb 2014 16:16:43 +0900

Hi Tobias,

In other words: I think a server should actively announce support for any
> SPDY/WS, and only then
> should SPDY/WS be tried first when a JS opens a WebSocket connection to an
> origin that has an
> existing SPDY connection and which already announced it's support and
> willingness to speak
> any SPDY/WS.

I see. I propose a new negotiation method here and I think it addresses
your concern.

*Negotiation Decision Process:*
1: If the client has an existing HTTP/2.0 session and it knows that the
server supports WebSocket over HTTP/2.0, create a WebSocket stream on the
session. Both of WebSocket (ws) and secure WebSocket (wss) could share the
same HTTP/2.0 session.
2: If the client is going to establish a secure WebSocket connection,
create a WebSocket connection over TLS.
3: If the client is going to establish a non-secure WebSocket connection,
try the WebSocket protocol negotiation.

*Negotiation Cases:*

*Create WebSocket Stream on Existing HTTP/2.0 Session*
The client SHOULD create a new HTTP/2.0 stream in the existing HTTP/2.0
session.

*Create WebSocket Connection over TLS*
HTTP/2.0 uses TLS Application Level Protocol Negotiation (ALPN) for the
protocol negotiation. The client sends the application protocols it wants
to use, "HTTP/1.1" for the native WebSocket over TLS, "HTTP/2.0[ws]" for
non secure WebSocket over HTTP/2.0, "HTTP/2.0[wss]" for secure WebSocket
over HTTP/2.0.
If the server selects "HTTP/1.1", the client SHOULD start the native
WebSocket opening handshake on TLS.
If the server selects "HTTP/2.0[ws]", the client SHOULD create an HTTP/2.0
session and start the WebSocket opening handshake on it with "ws" scheme.
If the server selects "HTTP/2.0[wss]", the client SHOULD create an HTTP/2.0
session and start the WebSocket opening handshake on it with "wss" scheme.

*The WebSocket Protocol Negotiation*
(same as the document)

*Supporting scheme negotiation using SETTINGS frame*
By default, a client can send HEADERS frames on schemes that server
supports based on the protocol server selected in ALPN. A server SHOULD
send a SETTINGS frame as soon as possible whether it supports other schemes
or not.
Here is a proposed ID and value which should be defined in the HTTP/2.0
specification. If the endpoint received a HEADERS on unsupporting schemes,
the endpoint MUST reset the stream.

Defined IDs: (same as the document)

No additional RTTs are introduced when the server supports the native
WebSocket and HTTP/2.0 but does not support WebSocket over HTTP/2.0.
We should introduce the following in the HTTP/2.0 specification.
 - Supporting scheme advertisement using SETTINGS frame
 - HTTP/2.0[xx] in the ALPN stands for the HTTP/2.0 protocol with scheme xx.

Thanks,

On Thu, Jan 30, 2014 at 9:24 PM, Tobias Oberstein <
[email-masked]> wrote:

> Hi Yutaka,
>
>
>
> the point I was trying to raise is this:
>
>
>
> For a JavaScript in a browser that opens a "ws://…" connection, there
> should never be an additional roundtrip
>
> incurred by first probing for any SPDY/WS and then falling back to native
> WS, but the native WS should be
>
> tried first.
>
>
>
> In other words: the current, immediate connection establishment for native
> WS should not be put
>
> at an disadvantage just because of introducing any SPDY/WS.
>
>
>
> A server should be able to provide both SPDY and native WebSocket on the
> _same_ origin without
>
> being required to implement SPDY/WS also, and without incurring an
> additional roundtrip for
>
> probing SPDY/WS while establishing a WS connection.
>
>
>
> In other words: I think a server should actively announce support for any
> SPDY/WS, and only then
>
> should SPDY/WS be tried first when a JS opens a WebSocket connection to an
> origin that has an
>
> existing SPDY connection and which already announced it's support and
> willingness to speak
>
> any SPDY/WS.
>
>
>
> Probably I misunderstood the draft.
>
>
>
> Are browsers supposed to work like above when they implement any SPDY/WS?
>
>
>
> /Tobias
>
>
>
>
>
> *Von:* hybi [mailto:[email-masked]] *Im Auftrag von *Yutaka Hirano
> *Gesendet:* Donnerstag, 30. Januar 2014 07:45
> *An:* [email-masked]
> *Betreff:* [hybi] WebSocket over HTTP/2.0 protocol negotiation
>
>
>
> Hi,
>
>
>
> As I announced, I've updated the draft and requested for comments.
>
> Tobias gave a comment on protocol negotiation (thanks!) and I think it is
> good to discuss here, not at the draft comment fields.
>
>
>
> The draft says:
>
>    1. If the client has a HTTP/2.0 session established by previous
>    requests and it doesn’t know that the session does NOT support WebSocket
>    layering over HTTP/2.0, create a WebSocket stream on the session. Both of
>    WebSocket (ws) and secure WebSocket (wss) could share the same HTTP/2.0
>    session.
>    2. If the client is going to establish a secure WebSocket connection,
>    create a WebSocket connection over TLS.
>    3. If the client is going to establish a non-secure WebSocket
>    connection, try the WebSocket protocol negotiation.
>
> Tobias doesn't like the first step. He says:
>
> I think native WS should be tried first. Native WS has less overhead than
> any WS-over-SPDY layering, and hence should be preferred.
>
>
>
> I have some comments about it.
>
>  - WebSocket over HTTP/2.0 is multiplexed, so it is not so obvious which
> is preferable. I think it depends on the popularity of the services:
>
>    - WebSocket over HTTP/2.0
>
>    - Native WebSocket and HTTP/2.0
>
>    - Native WebSocket and WebSocket over HTTP/2.0
>
>    Note that servers which doesn't support HTTP/2.0 don't matter, because
> they don't meet the precondition of the first step.
>
>  -  There are two scheme negotiation hints described below.
>
>     If we choose Hint X, before receiving a SETTINGS frame from the
> server, the client doesn't know which service is preferable. It is rare,
> but trying connecting to the wrong service can occur.
>
>     If we choose Hint Y, whether the server supports WebSocket over
> HTTP/2.0 or not is detected by the client prior to HTTP/2.0 session
> establishment and hence the client always understands the server's
> preference.
>
>     So, the actual negotiation decision process depends on the hint we
> choose.
>
>
>
> I'm sorry that the draft is not clear at this point, but it will be when
> the hint is chosen.
>
>
>
> Thanks,
>
>
>

---

From: Tobias Oberstein <[email-masked]>
Date: Tue, 4 Feb 2014 02:32:04 -0800

Hi Yutaka,

"No additional RTTs are introduced when the server supports the native WebSocket and HTTP/2.0 but does not support WebSocket over HTTP/2.0."

Awesome! The negotiation scheme you outline below seems to provide this.

Just some small detail questions:

1)
What if the server does not support TLS ALPN extension?

IOW: client sends ALPN with "HTTP/1.1, HTTP2.0[ws], HTTP2.0[wss]", and server answers
with no TLS ALPN extension part (or no next protocol selected).

Will the client then default to trying RFC6455 opening handshake (HTTP1.1/Upgrade)?

2)
"If the client has an existing HTTP/2.0 session and it knows that the server supports WebSocket over HTTP/2.0 …"

How does the client become aware of the server's support for WS-over-HTTP2?

Is that via the HTTP/2.0 SETTINGS frame you mention below?

3)
If the client _already_ knows the server supports HTTP/WS, what ALPN will it send
if no HTTP2 session is currently in place?

Will it nevertheless send "HTTP/1.1, HTTP2.0[ws], HTTP2.0[wss]" (same order)?

Or will it send "HTTP2.0[ws], HTTP2.0[wss]" only?

Or will it send "HTTP2.0[ws], HTTP2.0[wss], HTTP/1.1" (reordered)?

4) ALPN name for native RFC6455: wouldn't "HTTP/1.1[wss]" better correspond to
the actual protocol the client offers / desires to speak?

The client offers to speak RFC6455, just upgrading from HTTP/1.1, and the server
might want to select a dedicated implementation for that.

In general, a server that supports TLS ALPN might just want to lookup a preferred
implementation given a list of ALPN names offered by a client.

Example:
Take a server that implements HTTP/1.1 and HTTP/2.0 for serving static Web content,
and RFC6455 for application messaging (all services on same ports), and that wants
to realize the following behavior for TLS:

no ALPN & ALPNs "HTTP/1.1":
  => Server choses HTTP/1.1 implementation, no later upgrade to RFC6455 is allowed

ALPNs "HTTP/2.0":
  => Server choses HTTP/2.0 implementation (without announcing HTTP/WS support)

ALPNs "HTTP/1.1[wss],HTTP/2.0[wss]":
  => server choses RFC6455 implementation requiring immediate upgrade (that is, no
"plain" HTTP/GET requests before HTTP/Upgrade to WS are allowed)

IOW: the server wants to adjust it's behavior with ALPNs "HTTP/1.1" versus "HTTP/1.1[wss]":

ALPN "HTTP/1.1": client will _never_ HTTP1.1/Upgrade (to RFC6455 or anything other)
ALPN "HTTP/1.1[wss]": client will _immediately_ HTTP1.1/Upgrade to RFC6455

Cheers,
/Tobias

Von: [email-masked] [mailto:[email-masked]] Im Auftrag von Yutaka Hirano
Gesendet: Dienstag, 4. Februar 2014 08:17
An: Tobias Oberstein
Cc: [email-masked]; [email-masked]
Betreff: Re: [hybi] WebSocket over HTTP/2.0 protocol negotiation

Hi Tobias,

In other words: I think a server should actively announce support for any SPDY/WS, and only then
should SPDY/WS be tried first when a JS opens a WebSocket connection to an origin that has an
existing SPDY connection and which already announced it's support and willingness to speak
any SPDY/WS.
I see. I propose a new negotiation method here and I think it addresses your concern.

Negotiation Decision Process:
1: If the client has an existing HTTP/2.0 session and it knows that the server supports WebSocket over HTTP/2.0, create a WebSocket stream on the session. Both of WebSocket (ws) and secure WebSocket (wss) could share the same HTTP/2.0 session.
2: If the client is going to establish a secure WebSocket connection, create a WebSocket connection over TLS.
3: If the client is going to establish a non-secure WebSocket connection, try the WebSocket protocol negotiation.

Negotiation Cases:

Create WebSocket Stream on Existing HTTP/2.0 Session
The client SHOULD create a new HTTP/2.0 stream in the existing HTTP/2.0 session.
Create WebSocket Connection over TLS
HTTP/2.0 uses TLS Application Level Protocol Negotiation (ALPN) for the protocol negotiation. The client sends the application protocols it wants to use, "HTTP/1.1" for the native WebSocket over TLS, "HTTP/2.0[ws]" for non secure WebSocket over HTTP/2.0, "HTTP/2.0[wss]" for secure WebSocket over HTTP/2.0.
If the server selects "HTTP/1.1", the client SHOULD start the native WebSocket opening handshake on TLS.
If the server selects "HTTP/2.0[ws]", the client SHOULD create an HTTP/2.0 session and start the WebSocket opening handshake on it with "ws" scheme.
If the server selects "HTTP/2.0[wss]", the client SHOULD create an HTTP/2.0 session and start the WebSocket opening handshake on it with "wss" scheme.

The WebSocket Protocol Negotiation
(same as the document)

Supporting scheme negotiation using SETTINGS frame
By default, a client can send HEADERS frames on schemes that server supports based on the protocol server selected in ALPN. A server SHOULD send a SETTINGS frame as soon as possible whether it supports other schemes or not.
Here is a proposed ID and value which should be defined in the HTTP/2.0 specification. If the endpoint received a HEADERS on unsupporting schemes, the endpoint MUST reset the stream.

No additional RTTs are introduced when the server supports the native WebSocket and HTTP/2.0 but does not support WebSocket over HTTP/2.0.
We should introduce the following in the HTTP/2.0 specification.
 - Supporting scheme advertisement using SETTINGS frame
 - HTTP/2.0[xx] in the ALPN stands for the HTTP/2.0 protocol with scheme xx.

Thanks,

On Thu, Jan 30, 2014 at 9:24 PM, Tobias Oberstein <[email-masked]<mailto:[email-masked]>> wrote:
Hi Yutaka,

For a JavaScript in a browser that opens a "ws://…" connection, there should never be an additional roundtrip
incurred by first probing for any SPDY/WS and then falling back to native WS, but the native WS should be
tried first.

In other words: the current, immediate connection establishment for native WS should not be put
at an disadvantage just because of introducing any SPDY/WS.

A server should be able to provide both SPDY and native WebSocket on the _same_ origin without
being required to implement SPDY/WS also, and without incurring an additional roundtrip for
probing SPDY/WS while establishing a WS connection.

In other words: I think a server should actively announce support for any SPDY/WS, and only then
should SPDY/WS be tried first when a JS opens a WebSocket connection to an origin that has an
existing SPDY connection and which already announced it's support and willingness to speak
any SPDY/WS.

/Tobias

Von: hybi [mailto:[email-masked]<mailto:[email-masked]>] Im Auftrag von Yutaka Hirano
Gesendet: Donnerstag, 30. Januar 2014 07:45
An: [email-masked]<mailto:[email-masked]>
Betreff: [hybi] WebSocket over HTTP/2.0 protocol negotiation

Hi,

As I announced, I've updated the draft and requested for comments.
Tobias gave a comment on protocol negotiation (thanks!) and I think it is good to discuss here, not at the draft comment fields.

The draft says:

 1.  If the client has a HTTP/2.0 session established by previous requests and it doesn’t know that the session does NOT support WebSocket layering over HTTP/2.0, create a WebSocket stream on the session. Both of WebSocket (ws) and secure WebSocket (wss) could share the same HTTP/2.0 session.
 2.  If the client is going to establish a secure WebSocket connection, create a WebSocket connection over TLS.
 3.  If the client is going to establish a non-secure WebSocket connection, try the WebSocket protocol negotiation.
Tobias doesn't like the first step. He says:
I think native WS should be tried first. Native WS has less overhead than any WS-over-SPDY layering, and hence should be preferred.

I have some comments about it.
 - WebSocket over HTTP/2.0 is multiplexed, so it is not so obvious which is preferable. I think it depends on the popularity of the services:
   - WebSocket over HTTP/2.0
   - Native WebSocket and HTTP/2.0
   - Native WebSocket and WebSocket over HTTP/2.0
   Note that servers which doesn't support HTTP/2.0 don't matter, because they don't meet the precondition of the first step.
 -  There are two scheme negotiation hints described below.
    If we choose Hint X, before receiving a SETTINGS frame from the server, the client doesn't know which service is preferable. It is rare, but trying connecting to the wrong service can occur.
    If we choose Hint Y, whether the server supports WebSocket over HTTP/2.0 or not is detected by the client prior to HTTP/2.0 session establishment and hence the client always understands the server's preference.
    So, the actual negotiation decision process depends on the hint we choose.

I'm sorry that the draft is not clear at this point, but it will be when the hint is chosen.

Thanks,

---

From: Yutaka Hirano <[email-masked]>
Date: Wed, 5 Feb 2014 17:26:56 +0900

Adam pointed out that HTTP/2.0[ws] isn't useful since a client doesn't use
ALPN when it wants to use non-secure WebSocket.
He is right, I will fix the description.

1)
> Will the client then default to trying RFC6455 opening handshake
If there is no TLS ALPN extension part, yes.
If "no_application_protocol" alert is returned, I think the client should
give up.

> 2)
> "If the client has an existing HTTP/2.0 session and it knows that the
> server supports WebSocket over HTTP/2.0 …"
>
Yes. In addition to that, when there is an existing WebSocket over HTTP/2.0
connection to the server, even if without a SETTINGS frame the client knows
that the server supports the protocol.

> Or will it send "HTTP2.0[ws], HTTP2.0[wss], HTTP/1.1" (reordered)?
Same order looks good.

> implementation given a list of ALPN names offered by a client.
It sounds reasonable, but

ALPN "HTTP/1.1": client will _never_ HTTP1.1/Upgrade (to RFC6455 or
> anything other)
I think this is beyond our interest, isn't it?

> ALPN "HTTP/1.1[wss]": client will _immediately_ HTTP1.1/Upgrade to RFC6455
I think this is sufficient.

Thanks,

On Tue, Feb 4, 2014 at 7:32 PM, Tobias Oberstein <
[email-masked]> wrote:

> Hi Yutaka,
>
>
>
> "No additional RTTs are introduced when the server supports the native
> WebSocket and HTTP/2.0 but does not support WebSocket over HTTP/2.0."
>
>
>
> "If the client has an existing HTTP/2.0 session and it knows that the
> server supports WebSocket over HTTP/2.0 …"
>
>
>
> *Von:* [email-masked] [mailto:[email-masked]] *Im Auftrag von *Yutaka
> Hirano
> *Gesendet:* Dienstag, 4. Februar 2014 08:17
> *An:* Tobias Oberstein
> *Cc:* [email-masked]; [email-masked]
> *Betreff:* Re: [hybi] WebSocket over HTTP/2.0 protocol negotiation
>
>
>
> Hi Tobias,
>
>
>
> If the server selects "HTTP/2.0[wss]", the client SHOULD create an
> HTTP/2.0 session and start the WebSocket opening handshake on it with "wss"
> scheme.
>
>
>