Subject: [hybi] Client offers invalid WS protocols, what must the server do? 101???

From: Iñaki Baz Castillo <[email-masked]>
Date: Mon, 29 Aug 2011 00:39:56 +0200

Hi, the draft (12) says:

       /subprotocol/
          Either a single value representing the subprotocol the server
          is ready to use or null.  The value chosen MUST be derived
          from the client's handshake, specifically by selecting one of
          the values from the "Sec-WebSocket-Protocol" field that the
          server is willing to use for this connection (if any).  If the
          client's handshake did not contain such a header field, or if
          the server does not agree to any of the client's requested
          subprotocols, the only acceptable value is null.  The absence
          of such a field is equivalent to the null value (meaning that
          if the server does not wish to agree to one of the suggested
          subprotocols, it MUST NOT send back a |Sec-WebSocket-Protocol|
          header field in its response).

So if the server just supports protocols "aaa" and "bbb" but the
client offers "ccc" and "ddd", the above text states that the server
must reply 101 without Sec-WebSocket-Protocol header.

So then, *what* are the client and the server supposed to speak now??
If the client has ***explicitly*** offered protocols "ccc" and "ddd"
and the server does not support them, the server should REJECT the WS
handshake, sure, rather than sending a 101. IMHO "501 Not Implemented"
could be a good HTTP response for this case.

The WebSocket handshake (HTTP GET + 101) is a negotiation between
client and server. If the negotiation fails, the WS GET request MUST
be rejected rather than accepted.

The current text seems to allow ugly JavaScript developers to set a
random protocol string (just for funny) in the Websocket JS API for
the function "connect(URL, protocols)". Please make it strict.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 30 Aug 2011 11:42:40 +0100

>could be a good HTTP response for this case.
Subprotocols are optional in the WebSocket protocols. So the client 
can't say that a particular extension is required. It can only close the 
connection after the handshake completes without it.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 30 Aug 2011 13:11:33 +0200

2011/8/30 Alexey Melnikov <[email-masked]>:
> Subprotocols are optional in the WebSocket protocols. So the client can't
> say that a particular extension is required. It can only close the

That does not answer to all my previous rationale. To summarize:

Why should the WS server accept (so 101) a WS handshake when the
client offers WS protocols NOT supported by the WS server? I don't
mean that the client does not provide Sec-WebSocket-Protocol header, I
mean that the client *provides * it, but offered protocols are NOT
supported by the server. Why should the server then accept such WS
session? what are they supposed to speak? IMHO it's really clear that
the server should not accept the WS handshake.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 30 Aug 2011 12:16:55 +0100

Iñaki Baz Castillo wrote:

>supported by the server.
Because by definition the list of extensions in the 
Sec-WebSocket-Protocol header field is optional for the server to 
support. If we want to have "you must support this extension, or we fail 
the handshake", then we need another mechanism to tell the server.

>Why should the server then accept such WS

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 30 Aug 2011 13:18:45 +0200

2011/8/30 Alexey Melnikov <[email-masked]>:
> Because by definition the list of extensions in the Sec-WebSocket-Protocol
> header field is optional for the server to support. If we want to have "you
> must support this extension, or we fail the handshake", then we need another
> mechanism to tell the server.

Ok, so after client offers "Sec-WebSocket-Protocol: aaa, bbb" and the
server provides NO such header in the 101 response.... what are client
and server supposed to speak now?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 30 Aug 2011 12:25:44 +0100

>and server supposed to speak now?
If the client really expected the extensions to be mandatory, it has to 
send Close.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 30 Aug 2011 13:29:00 +0200

2011/8/30 Alexey Melnikov <[email-masked]>:
> If the client really expected the extensions to be mandatory, it has to send
> Close.

A new close status code just to say "the WS protocol negotiation has
obviously failed so I close the connection"?

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: John Tamplin <[email-masked]>
Date: Tue, 30 Aug 2011 11:41:37 -0400

On Tue, Aug 30, 2011 at 7:29 AM, Iñaki Baz Castillo <[email-masked]> wrote:

> send

We don't need a separate close code for every possible reason -- there will
be too many, and we will certainly miss many ones that would actually be
used.  Instead, we need more generic error codes describing categories of
failures.

-- 
John A. Tamplin
Software Engineer (GWT), Google

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 30 Aug 2011 16:42:48 +0100

John Tamplin wrote:

> On Tue, Aug 30, 2011 at 7:29 AM, Iñaki Baz Castillo <[email-masked] 
> <mailto:[email-masked]>> wrote:
>
>     2011/8/30 Alexey Melnikov <[email-masked]
>     <mailto:[email-masked]>>:
> We don't need a separate close code for every possible reason -- there 
> will be too many, and we will certainly miss many ones that would 
> actually be used.  Instead, we need more generic error codes 
> describing categories of failures.

I think we need both. More specific error codes are better, if 
introduced early.

---

From: Philipp Serafin <[email-masked]>
Date: Wed, 31 Aug 2011 18:18:34 +0200

I agree with Inaki that an error code for unsupported subprotocols would
be useful. But I think it would be cleaner if the server would send it
right as part of the handshake instead of the client.

So far it looks to me as if WS connections that make use of sub
protocols serve completely different use cases than those that don't.

On the one hand, we have proprietary, "internal" endpoints that will
solely be implementation details of a web application. The actual
protocol used on top of WS will be tailor-made to that specific
web-application and may change any time without notice. In fact, the
application might even switch to a completely different technology than
WS any time. Both WS client and server will be controlled by the same
developers.
As defining a formal subprotocol in such a case doesn't make much sense,
the protocol header will likely not be used.

On the other hand, we may have standardized, "external", WS-based APIs,
the same way e.g. SOAP and OAUTH can be layered on top of HTTP today.
Here, clients and servers from different parties will have to speak with
each other, some of which might not even run in a browser or might
otherwise be hard to update. Here, standardized subprotocols and the
negotiation mechanism will be of much use.

However, I don't see much overlap in those two use-cases right now. I
don't see many cases where a server that doesn't support a certain
standardized protocols could reasonably fall back to a proprietary
default protocol. This also makes the subprotocol header less useful
IMO, since it implies that the client doesn't actually lists all
protocols it supports in the header - it might or might not also support
an unnamed, proprietary protocol.

Why can't we take the presence of a subprotocol header in the client
request as a hint that the client wants to speak a "standard" protocol?
Then it would be reasoneable for the server to reject the connection if
none of those standard protocols are supported.
However, if the client sends no protocol header, then the server can
still accept the connection and speak an unnamed, proprietary protocol.

Am 30.08.2011 17:42, schrieb Alexey Melnikov:
>> We don't need a separate close code for every possible reason --
>> there will be too many, and we will certainly miss many ones that
>> would actually be used.  Instead, we need more generic error codes
> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 31 Aug 2011 18:32:29 +0200

> still accept the connection and speak an unnamed, proprietary protocol.

That's exactly what I meant, but I did it worse :)

Thanks a lot.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Bruce Atherton <[email-masked]>
Date: Wed, 31 Aug 2011 11:13:24 -0700

> the protocol header will likely not be used.

I think your analysis is mixing a few concerns. To me, there are two 
questions to answer when considering this issue: Is the subprotocol 
custom or standard? Is it running on an application-specific endpoint or 
a standard browser/server?

When both the subprotocol and the endpoints are custom, there are still 
benefits to using the subprotocol field. It allows versioning, for 
example. It also allows you to limit the subprotocols used at the 
endpoints so you can support things like pricing based on subprotocols 
deployed to a particular customer.

When the subprotocol is custom and the endpoints are standard, then a 
subprotocol layers on top of the default subprotocol. This may be useful 
if, for example, you want to deploy a vendor's widget that uses 
Websockets to your page. It allows your server to implement the specific 
protocol for talking to the widget. And consider if you had multiple 
widgets each from a different vendor on the same page. I would think 
that browsers will deal with an attempt to open multiple connections to 
the same URL with different subprotocols by MUXing them. I could be 
wrong about that, but it would provide a nice mechanism for dealing with 
the multiple vendor problem.

When the subprotocol is standard and one of the endpoints is custom, 
there is still a benefit to specifying a subprotocol as it enhances the 
chances of interoperability with other implementations.

When both the subprotocol and the endpoints are standard, right now it 
is the same as when the subprotocol is custom. But in the future, 
browsers and servers may provide architectures for extending the 
subprotocols they support. Imagine tunneling SIP and RTP over Websockets 
so that everyone visiting a particular web page was given the option of 
joining a conference call. That may be a useful enough feature that 
eventually browsers actually include support for the SIP and RTP 
subprotocols natively.

Regarding the server sending the error code, that would eliminate the 
ability for a client to fall back to the raw binary/text subprotocol if 
the server doesn't support any of the specific subprotocols. I don't 
think that is a good idea.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 31 Aug 2011 20:29:30 +0200

2011/8/31 Bruce Atherton <[email-masked]>:
> Imagine tunneling SIP and RTP over Websockets

No please. SIP over WebSocket and RTP over UDP as WebRTC claims :)

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Philipp Serafin <[email-masked]>
Date: Wed, 31 Aug 2011 20:31:26 +0200

> questions to answer when considering this issue: Is the subprotocol custom
> or standard? Is it running on an application-specific endpoint or a standard
> browser/server?
>

I'm sorry for being imprecise. When talking about developer-controlled
clients in the web application case, I meant the client-side part of web
apps that still run inside the browser. So the developers have control of
the server and the javascript component that runs inside the browser, but
NOT of the actual WS client implementation.

> ability for a client to fall back to the raw binary/text subprotocol if the
> server doesn't support any of the specific subprotocols. I don't think that
> is a good idea.
>
>
But how would such a fallback look like? Unless your talking about a CS year
one chat server, "text" is no proper protocol on itself, like "XML" and
"JSON" are not enough to know the type of a document - you need to layer
some additional structure on top of that.

If a client sends a protocol header, I don't see why it can't indicate ALL
protocols it supports for this connection. If the server supports none of
those protocols, and if neither client nor server are part of a single web
application (so there is no implicit custom protocol they could both
understand), I don't see how a sucessful connection could be established.

As I understood it, subprotocol names don't need to be registered but can be
chosen ad-hoc. So it shouldn't be hard to choose a protocol name even if you
just want to use it for the public web api of your site.

I agree with your other use cases though.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 31 Aug 2011 21:21:57 +0200

> understand), I don't see how a sucessful connection could be established.

Of course. Say the opposite means allowing ugly/annoying pseudo negotiations.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: John Tamplin <[email-masked]>
Date: Wed, 31 Aug 2011 15:26:42 -0400

> Of course. Say the opposite means allowing ugly/annoying pseudo

Personally, I see little value at this point for subprotocols.  They
basically represent an agreement between the application end points for a
protocol to run on top of WS.  Since the app developer owns both endpoints,
they can already use whatever protocol they like.  It is a convenient place
to send selection between multiple protocols out-of-band, but no more.

Maybe in the future there are standard subprotocols, and you could have some
off-the-shelf product to offload those subprotocols, but initially there
seems to be little value so I don' t think we need to go overboard imagining
things that would be useful with only limited experience with WS itself.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 31 Aug 2011 22:05:34 +0200

2011/8/31 John Tamplin <[email-masked]>:
> protocol to run on top of WS.

> Since the app developer owns both endpoints,

What? and what about HTTP API's? don't you expect that there will also
exist WS API's so I can develope, for example, a Linux KDE desktop
application/widget that connects to Gmail via WebSocket (Google WS
API) to check my mail in realtime??? You work in Google, you should
know it, am I wrong?

A protocol MUST NOT be designed taking that wrong assumption into
account. This is a protocol, not a JavaScript "feature" to make the
text blinking or ringing in Chrome.

> off-the-shelf product to offload those subprotocols,

Me (and others AFAIK) are just proposing that, in *case* the client
provides a WS protocol in the HTTP GET, and the server *does not*
support such protocol, then the server MUST reject the WS handshake
(which means a 4XX error code rather than "101 I don't know what we
are supposed to speak now but I accept the WS session").

Is it to hard? does it break so much?

Of course, what you propose is just valid for allowing a stupid JS
developer coding a JS application that connects to the WS server by
providing "Sec-WebSocket-Protocol:
i-dont-know-programming.but-i-am-cool.com".

> but initially there

The protocol is being written right now, not within 4 years when all
the people and browsers extensively use WebSocket and it's not
possible to change nothing. This is not an experiment, it's an
Internet protocol.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Philipp Serafin <[email-masked]>
Date: Wed, 31 Aug 2011 22:08:56 +0200

> are supposed to speak now but I accept the WS session").
Exactly.

---

From: John Tamplin <[email-masked]>
Date: Wed, 31 Aug 2011 16:18:45 -0400

> API) to check my mail in realtime??? You work in Google, you should

Since you brought it up, lets take such an example.  You can connect using
the GData APIs to get your calendar information, etc. over HTTP today.  You
can do that despite the fact that HTTP doesn't support a subprotocol
defining what that API looks like.  It works because you read the docs and
wrote code to speak the "subprotocol" over that connection, despite the fact
that it wasn't announced.

Likewise, you could do exactly the same in WS whether or not a hypothetical
GData service over WebSocket used a subprotocol.

> text blinking or ringing in Chrome.

The protocol is defined, and a subprotocol cannot change the framing or
representation of messages in the base protocol.  To me, that limits the
value of subprotocol as out-of-band identification of what the next layer up
plans to do with that channel, similar to a MIME type for HTTP.  I don't see
where your suggestion this is a Javascript feature enters into it.

> i-dont-know-programming.but-i-am-cool.com".

Your attitude is not conducive to constructive conversation.

---

From: Philipp Serafin <[email-masked]>
Date: Wed, 31 Aug 2011 22:05:42 +0200

I may be wrong, but this looks like a feature that would be really cheap
to specify and implement now (even if we don't know if it'll actually be
of much use) but very hard later when we'd have to take lots and lots of
back-compat issues into consideration.

I'd just hate to see subprotocols go the way of the HTTP Accept header,
which is practically unuseable in the browser world today, even though
it would solve some real-world problems. (As shown by the &type=... URL
params in many APIs)

Am 31.08.2011 21:26, schrieb John Tamplin:
> On Wed, Aug 31, 2011 at 3:21 PM, Iñaki Baz Castillo <[email-masked]
>     2011/8/31 Philipp Serafin <[email-masked]
>     <mailto:[email-masked]>>:
> basically represent an agreement between the application end points
> for a protocol to run on top of WS.  Since the app developer owns both
> endpoints, they can already use whatever protocol they like.  It is a
> convenient place to send selection between multiple protocols
> out-of-band, but no more.
>
> Maybe in the future there are standard subprotocols, and you could
> have some off-the-shelf product to offload those subprotocols, but
> initially there seems to be little value so I don' t think we need to
> go overboard imagining things that would be useful with only limited
> experience with WS itself. 
>
> -- 
> John A. Tamplin

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Wed, 31 Aug 2011 23:03:51 +0200

> GData service over WebSocket used a subprotocol.

Yes, sure I can ignore WS subprotocols, just not use them at all in my
WS application (server and client). The point is: if the protocol
introduces a mechanism (an *optional* mechanism) for negotiating a WS
subprotocol, and the client wants to use it, why couldn't the server
reject the WS session if the server does not support such protocol?
why is that so terrible? You can just ignore it in your apps.

Now let me expose an example (assuming my suggestion for a HTTP 4XX
response code):

- Let's suppose Google provides a WS API to connect to ws://gmail.com.
Initially it provides the WS "v01.gmail.com" subprotocol.
- Lot of desktop/mobile applications (not just web browsers) implement
it to check the mail.
- After two years Google introduces improvements in the service which
becomes "v02.gmail.com" WS subprotocol. Google still supports boh
protocols in the same WS URL.
- Some clients are upgraded, some others not.
- After 3 years Google decides to drop the support for "v01.gmail.com".
- Non upgraded clients, which still offer "sec-WebSocket-Protocol:
v01.gmail.com" would be rejected by some HTTP 4XX code which is good,
because if such 4XX becomes an standard the application could prompt a
warning to the user "cannot connect to the service due to WebSocket
subprotocol incompatibility".

What is the alternative if Sec-WebSocket-Protocol is not used at all?
Clients would fail "at some point" because the exchanged messages are
not compatible. The client WS application has no way to describe the
problem to the user (neither to their authors).

Of course, you can decide to use another URL path for version 02 and
you are done, of course. But, why do you want to avoid that me or
others relying on the ellegant protocol mechanism I've described in my
example?
In other words: why is so bad for you my suggestion? you can just
ignore it as it's an optional mechanism, why is then a problem?

> plans to do with that channel, similar to a MIME type for HTTP.

Ok, don't use it if you don't consider it useful, but the protocol
already includes it (as an optional mechanism). I'm just suggesting
that, for those who consider it useful, it should be better defined (a
specific HTTP 4XX code in case the server does not support WS
subprotocol(s) offered by the client).

> Your attitude is not conducive to constructive conversation.

It was just a joke, sorry. I just meant that the *only* "problem" with
my suggestion could occur is case a JavaScript developer decides to
offer an unexisting WS subprotocol in his JavaScript code. There is
absolutely no reason to expect that.

Regards.

-- 
Iñaki Baz Castillo
<[email-masked]>

---

From: Brian <[email-masked]>
Date: Wed, 31 Aug 2011 14:59:05 -0700

Yes.  This requirement should be in the spec.  Frankly, I implemented my
WebSocket libraries this way as it's the only thing that makes any sense.  I
just assumed that's how it was supposed to be.  It didn't really occur to me
that the protocol was underspecified here.  There is absolutely no
reasonable use case for the server to fall back to an unspecified default
protocol and accept the connection if it doesn't know any of the requested
subprotocols from the client, just like there's no acceptable use case for
the server to accept the connection with a subprotocol not contained in the
list of subprotocols requested by the client.  If the client requests a list
of subprotocols, that is to be taken as the canonical list of the only
subprotocols it knows how to speak.  Anything else will fail.  It should
respond with a 4xx HTTP error code.

The *only* time a server should accept the connection with a default
unspecified subprotocol is when the client doesn't request any subprotocols
at all.  That's really the end of the story.

This minor enhancement to the spec would be trivial and shouldn't hold
anything else up.

Brian

On Wed, Aug 31, 2011 at 1:08 PM, Philipp Serafin <[email-masked]> wrote:

> Me (and others AFAIK) are just proposing that, in **case** the client
> provides a WS protocol in the HTTP GET, and the server **does not**

---

From: Joel Martin <[email-masked]>
Date: Wed, 31 Aug 2011 18:58:53 -0500

On Wed, Aug 31, 2011 at 4:59 PM, Brian <[email-masked]> wrote:

> that the protocol was underspecified here.

+1. This was also my assumption in implementing websockify. One of the
protocols is mandatory if specified and the server may only respond
successfully if it supports one of them.

Also, should the server really be able to specify a protocol if the client
didn't specify any? It seems that if the client doesn't specify a protocol
then that ought to mean "no protocol" rather than "any protocol".

Regards,

Joel Martin (kanaka)

---

From: Brian <[email-masked]>
Date: Wed, 31 Aug 2011 17:06:56 -0700

As far as I'm concerned, the server shouldn't be able to specify a
subprotocol if the client didn't request one.  If the client didn't request
a given subprotocol, it doesn't know how to speak it.  That's a failure
case, plain and simple.

The only "I don't care" exception that is acceptable is when the client
requests no subprotocol, and the server specifies no subprotocol in
response.

Cheers,
Brian