Subject: [hybi] Comments about draft-13

From: Iñaki Baz Castillo <[email-masked]>
Date: Fri, 2 Sep 2011 14:01:14 +0200

Some doubts about draft 13:

1)

-------------------------------
  1.6.  Security Model

          6.  If the response includes a "Sec-WebSocket-Protocol" header field,	
 	       and this header field indicates the use of a subprotocol that was	
 	       not present in the client' handshake (the server has indicated a	
 	       subprotocol not requested by the client), the client MUST _Fail	
 	       the WebSocket Connection_.  (The parsing of this header field to	
 	       determine which extensions are requested is discussed in	
 	       Section 9.1.)
---------------------------------

Why is this text speaking about "extensions"? do I miss something?

2) Sec-WebSocket-Extensions BNF grammar still relies on RFC 2616
"implied *LWS". Please, don't reference it. Pure ABNF does not allow
it, it's just a hack in RFC 2616. Instead, change the current text:

---------------------------
9.1.  Negotiating Extensions

   A client requests extensions by including a "Sec-WebSocket-
   Extensions" header field, which follows the normal rules for HTTP
   header fields (see [RFC2616] section 4.2) and the value of the header
   field is defined by the following ABNF.  Note that unlike other
   section of the document this section is using ABNF syntax/rules from
   [RFC2616], including "implied *LWS rule".  If a value is received by
   either the client or the server during negotiation that does not
   conform to the ABNF below, the recipient of such malformed data MUST
   immediately _Fail the WebSocket Connection_.

         Sec-WebSocket-Extensions = extension-list
         extension-list = 1#extension
         extension = extension-token *( ";" extension-param )
         extension-token = registered-token
         registered-token = token
         extension-param = token [ "=" token ]
---------------------------

with this:

---------------------------
9.1.  Negotiating Extensions

   A client requests extensions by including a "Sec-WebSocket-
   Extensions" header field, which follows the normal rules for HTTP
   header fields (see [RFC2616] section 4.2) and the value of the header
   field is defined by the following ABNF.  If a value is received by
   either the client or the server during negotiation that does not
   conform to the ABNF below, the recipient of such malformed data MUST
   immediately _Fail the WebSocket Connection_.

         Sec-WebSocket-Extensions = extension-list
         extension-list = 1#extension
         extension = extension-token *( SEMI extension-param )
         extension-token = registered-token
         registered-token = token
         extension-param = token [ "=" token ]
         SEMI  = SWS ";" SWS;
         SWS  = LWS?;
---------------------------

Of course, the same should be changed in "4.3 Collected ABNF for new
header fields used in handshake" as it repeats the
Sec-WebSocket-Extensions ABNF !!

3) Section 4.2.2 does include nothing about a 4XX HTTP response code
for the case in which the WS clients offers N WS subprotocols and the
server supports no one of them. Current text states that the server
MUST reply 101 without Sec-WebSocket-Protocol, so the client would
then MUST Fail_The_Connection.

There has been a long thread recently suggesting that in that case
(and just in *that* case) the server whould *reject* the GET request
with a *specific* HTTP status code which would mean "I don't support
any of your suggested WS protocols, so I cannot accept the WS session
because I have no idea what we are supposed to speak".

This is a new protocol, so feel *free* to create a new "HTTP" response
code for this case, maybe:

  488 WebSocket SubProtocol Not Supported

As I explained in other thread, this status code could help the human
user and the client application developer to realize that his software
is not up-to-date with the service requeriments ("your programm is too
old, upgrade please").

Regards.

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

---

From: Alexey Melnikov <[email-masked]>
Date: Sat, 03 Sep 2011 11:34:46 +0100

>Some doubts about draft 13:
Cut and paste error from elsewhere. I've deleted the text in ().

I let chairs/AD declare directions on your 2 other points

 [snip]

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 14:28:23 +0200

> is not up-to-date with the service requeriments ("your programm is too

Hi, any new consideration about this?
Thanks a lot.

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

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 13:37:20 -0400

Also, to re-iterate a comment I made earlier, "Sec-Websocket-Protocol" should just be "Websocket-Protocol", since it is not "Sec" -- scripts can set the value pretty much directly.

--Richard 

On Sep 6, 2011, at 8:28 AM, Iñaki Baz Castillo wrote:

> _______________________________________________
> hybi mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/hybi

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 19:38:58 +0200

> Also, to re-iterate a comment I made earlier, "Sec-Websocket-Protocol" should just be "Websocket-Protocol", since it is not "Sec" -- scripts can set the value pretty much directly.

+1

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

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 19:40:36 +0200

>> Also, to re-iterate a comment I made earlier, "Sec-Websocket-Protocol" should just be "Websocket-Protocol", since it is not "Sec" -- scripts can set the value pretty much directly.

Well, scripts can set the value pretty much directly but at least
JavaScript API for WebSocket requires such a value to be an string or
an array of strings. I expect that a JS code cannot set binary or
custom value in "Sec-Websocket-Protocol" header.

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

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 13:42:53 -0400

Hence the "pretty much" :)  

One could argue that scripts can also set the Content-Length header as well, by setting the length of a message.  But the current WS API offers a much more direct channel to Websocket-Protocol, allowing the script to put in arbitrary strings.

--Richard

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 19:54:26 +0200

2011/9/6 Richard L. Barnes <[email-masked]>:
> But the current WS API offers a much more direct channel to Websocket-Protocol, allowing the script to put in arbitrary strings.

But an "arbitraty string" could be a valid token so also a valid value
for Sec-WebSocket-Protocol :)

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

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 13:58:54 -0400

Correct.  So absent further restrictions in the API, a script could supply arbitrary UTF-8 data.  Thus, non "Sec".

--Richard

---

From: Philipp Serafin <[email-masked]>
Date: Tue, 06 Sep 2011 20:04:00 +0200

Sorry for dragging this discussion on, but I'd like to disagree here :)

I think there could be some value if UAs could block web sites from
using certain sub-protocols, if those protocols themselves might contain
security-relevant information. E.g., think about a hypothetical
"SPDY-over-WS".

Also, what happens if a javascript specifies both, a "Protocol" header
and a (different) sub-protocol using the API? Which would take precedence?

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 20:04:21 +0200

> Correct.  So absent further restrictions in the API, a script could supply arbitrary UTF-8 data.  Thus, non "Sec".

Sure? At least Chrome 15.X does not allow me to set a WS subprotocol
called "foo.€áéíóúñ.com". It does not send the HTTP GET request and
logs an error:

  Wrong protocol for WebSocket
'foo.\u20AC\u00E1\u00E9\u00ED\u00F3\u00FA\u00F1.com'

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

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 20:05:05 +0200

> and a (different) sub-protocol using the API? Which would take precedence?

What do you mean exactly?

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

---

From: Philipp Serafin <[email-masked]>
Date: Tue, 06 Sep 2011 20:14:05 +0200

... mhh, nevermind, I thought the javascript WS api had an equivalent to
XHR's setRequestHeader(), which would allow the script to change the
header after it called the constructor. But that doesn't seem the case.
So, my bad :)

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 20:24:12 +0200

> header after it called the constructor. But that doesn't seem the case.

The WS API seems insuficient IMHO as it does not provide a Boolean
field to check out wheter an established connecion is secure (wss) or
not. Yes, URI parsing can be manually done but...

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

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 06 Sep 2011 22:27:01 +0100

>Also, to re-iterate a comment I made earlier, "Sec-Websocket-Protocol" should just be "Websocket-Protocol", since it is not "Sec" -- scripts can set the value pretty much directly.
Let's please not change the header field name now, this will break 
implementations of all earlier versions, some of which are already deployed.

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Tue, 6 Sep 2011 23:49:02 +0200

> implementations of all earlier versions, some of which are already deployed.

I've checked that, at least a in a web browser, JavaScript does not
allow an invalid WS protocol string (something different than a
'token' as defined in the BNF). So IMHO it's correct such header to
begin with "Sec-".

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

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 17:57:32 -0400

> Let's please not change the header field name now, this will break implementations of all earlier versions, some of which are already deployed.
> 

I wouldn't have a problem with this had W3C not assigned a semantic to the field name:
"
[Do not allow a script to set a header] if /header/ is a case-insensitive match for one of the following headers [...] or if the start of /header/ is a case-insensitive match for Proxy- or Sec- (including when header is just Proxy- or Sec-).
"
<http://www.w3.org/TR/XMLHttpRequest/>

That behavior has set the expectation that Sec- header fields cannot be set by scripts, which is not really true of Sec-Websocket-Protocol.  As the WS API is specified now, a script can provide an arbitrary UTF-8 string.  So either this spec should constrain the syntax of the field (e.g., a sequence of ASCII tokens, which is what actually seems to be desired) or remove the "Sec-".

--Richard

---

From: Alexey Melnikov <[email-masked]>
Date: Tue, 06 Sep 2011 23:21:49 +0100

>That behavior has set the expectation that Sec- header fields cannot be set by scripts, which is not really true of Sec-Websocket-Protocol.  As the WS API is specified now, a script can provide an a…
The header field syntax is already specified in -13, see Section 4.3. 
Also see Iñaki's response.

---

From: "Richard L. Barnes" <[email-masked]>
Date: Tue, 6 Sep 2011 18:33:51 -0400

On Sep 6, 2011, at 6:21 PM, Alexey Melnikov wrote:

> The header field syntax is already specified in -13, see Section 4.3. Also see Iñaki's response.
> 

Ok, thanks.  I had missed that.  I think that's adequately restricted to merit "Sec-".  Never mind.

--Richard

---

From: Greg Wilkins <[email-masked]>
Date: Wed, 7 Sep 2011 11:20:48 +1000

On 7 September 2011 07:27, Alexey Melnikov <[email-masked]> wrote:
> Richard L. Barnes wrote:
>
>> Also, to re-iterate a comment I made earlier, "Sec-Websocket-Protocol"
>> should just be "Websocket-Protocol", since it is not "Sec" -- scripts can
>> set the value pretty much directly.
>>

I'm not really keen on changing the header either, but  not sure how
much of a transgression of the W3C rules it is to send a script
control value in a Sec- header.   Perhaps we should refer the question
to the W3C - if they don't view it as a big issue, then we can keep
it.

If we keep it and it is a big issue, then we will be forced to change
later and that will be more painful.

Note that if we are forced to change, then I think we should also
change all the server sent headers and remove Sec- from them, because
they obviously do not match the w3c criteria.

cheers

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Wed, 07 Sep 2011 03:45:42 +0200

* Richard L. Barnes wrote:
>[Do not allow a script to set a header] if /header/ is a case-insensitive
>match for one of the following headers [...] or if the start of /header/
>is a case-insensitive match for Proxy- or Sec- (including when header is
>just Proxy- or Sec-).
>"

This is an incorrect reading of the XMLHttpRequest proposal. The idea is
that those header values must be controlled by the entity that puts the
bits on the wire, not the caller of XMLHttpRequest methods. It could say
just aswell that when the XMLHttpRequest caller sets the Content-Length
header, the implementation must override or remove the value when making
the request, as would be appropriate for the request. "A script" can of
course control the value of the header by sending so and so many bytes
(provided the length is indicated by the browser using the header). And
that is just XMLHttpRequest anyway, not the Websocket API.

Turning this around, you are saying that XMLHttpRequest callers should
be able to set the Websocket header on ordinary HTTP requests despite
them having no meaning there. Back in the day I argued to explain this
in the terms above, and the proposal does say "Note: The above headers
are controlled by the user agent to let it control those aspects of
transport. This guarantees data integrity to some extent. Header names
starting with Sec- are not allowed to be set to allow new headers to be
minted that are guaranteed not to come from XMLHttpRequest." at least.

"A script" is different from "not from XMLHttpRequest", so I am unclear
on where the confusion comes from. That it is XMLHttpRequest that makes
such conventions is a problem; I expect that the httpbis Working Group
<http://lists.w3.org/Archives/Public/ietf-http-wg/2011JanMar/0160.html>
where I raised it will resolve this in one form or another eventually.
-- 
Björn Höhrmann · mailto:[email-masked] · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

---

From: Alexey Melnikov <[email-masked]>
Date: Thu, 08 Sep 2011 00:25:14 +0100

Hi Iñaki,

>Hi, any new consideration about this?
After thinking more about this: I would prefer to leave the current 
behaviour as is:

C: I would like to use either subprotocol "foo" or "bar"
S: 101 (WebSocket handshake), but speak neither

at this point the client can decide to close the connection, or decide 
that it can cope with lack of the subprotocols.

You propose:
C: I would like to use either subprotocol "foo" or "bar"
S: 488 speak neither

At this point if the client can cope with lack of support for both "foo" 
and "bar", it has to redo the handshake without mentioning them.
Otherwise it can close the connection.

I don't think there is a significant difference between 2 cases: the 
number of round trips is the same and the same behaviour can be achieved 
easily in either case.

I would also like to keep handling of subprotocols the same as handling 
of extensions, i.e. client can always list them as optional for the 
server to handle.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 8 Sep 2011 10:37:44 +1000

The only thing I think is missing is the ability to speak multiple protocols.

The server should be able to say "foo" and "bar" as well as "foo" or "bar"

I don't see any reason that protocols have to be exclusive.  For
example I might want to use an oauth protocol with a chat protocol.

cheers

On 8 September 2011 09:25, Alexey Melnikov <[email-masked]> wrote:
> at this point the client can decide to close the connection, or decide that
> it can cope with lack of the subprotocols.
>
> You propose:
> At this point if the client can cope with lack of support for both "foo" and
> "bar", it has to redo the handshake without mentioning them.
> I don't think there is a significant difference between 2 cases: the number
> of round trips is the same and the same behaviour can be achieved easily in
> either case.
>
> I would also like to keep handling of subprotocols the same as handling of
> extensions, i.e. client can always list them as optional for the server to
> handle.
>

---

From: John Tamplin <[email-masked]>
Date: Wed, 7 Sep 2011 20:41:43 -0400

> example I might want to use an oauth protocol with a chat protocol.

I don't think that makes any sense -- a subprotocol defines the
interpretation of the data that rides in the WS messages.  How can it be
both oauth data and chat data?  It might be an additional layer that can
carry both, but that is the subprotocol that should be negotiated.

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

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 8 Sep 2011 11:29:30 +1000

John

if we interpret multiple protocols in the same way that we interpret
multiple extensions, then it does make sense.   Ie there is an
ordering of protocols, so if you had "oauth","chat"  then the oauth
protocol would be given the messages first and it could consume them
and generate replies before potentially passing messages to the chat
protocol.

Of course not all protocols will be additive in this way, but i think
it is still a needless restriction to have only 1.

But then it's not a big issue and unless everybody says +1 now, it's
not worth holding up the spec for.

cheers

---

From: John Tamplin <[email-masked]>
Date: Wed, 7 Sep 2011 21:38:58 -0400

> and generate replies before potentially passing messages to the chat

That doesn't make sense unless you have another layer of the protocol to
decide whether this particular message is an oauth message or something
else.  If it is just a bunch of bytes that should be delivered to an
upper-level protocol, you can't tell whether it is destined for this one or
some other one.  If you have some mechanism to identify the upper protocol,
then defining what that information is is the actually subprotocol, and then
you have protocols on top of them.

> it is still a needless restriction to have only 1.

IP doesn't have multiple upper-level protocols, for exactly the same reason
-- if you want to run multiple protocols on top of that, you have some
additional identifier in a higher layer.

> not worth holding up the spec for.

Well, you can count me as a big -1.

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 8 Sep 2011 11:52:28 +1000

> you have protocols on top of them.

Exactly!

If the application layer accepts a connection with "foo" and "bar"
then obviously it is saying that it has a way to tell the difference
between "foo" and "bar" messages, because it is the application layer
that does the protocol handling.

If the application can't handle multiple protocols, or a particular
mix of protocols, then it just doesn't accept the connection, or
accepts with only 1 protocol.

I see no reason the WS layer needs to get involved - including
policing that there are [0,1] protocols accepted.

but whatever, I'm not that fussed either way.

regards

---

From: John Tamplin <[email-masked]>
Date: Wed, 7 Sep 2011 22:12:14 -0400

> accepts with only 1 protocol.

Then it is your application that is the subprotocol and provides a way to
distinguish them.  A server component that understands the "foo" protocol
should be able to speak it without knowing it needs to add some
disambiguation about which subprotocol a particular message belongs to.

It seems to me that your example should be "my-layered-protocol", which has
some identifier for the next-layer protocol, then the payload of that next
layer protocol.

As a practical example, let's say that the client ask for the "foo" and
"bar" subprotocols.  The server can speak either of them.  How does it
decide between answering "foo", "bar", or "foo, bar"?  Does it have to keep
a table of which subprotocols are mutually distinguishable so they can be
accepted together?  Do you rely on heuristics, or do all subprotocols have
to have a "magic value" at the beginning of each message so they can be
distinguished?

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 8 Sep 2011 12:26:48 +1000

John,

acceptance is entirely a matter for the application, and it can decide
to accept "foo", "bar", "foo" and "bar" or neither entirely by
whatever mechanism it wants (I suspect many would just be fixed).

But anyway -  let's not waste more time just agree to disagree about
the feasibility of this and leave it as is - ie with the requirement
that the WS server has to enforce that the application accepts only 0
or 1 protocols.

---

From: Bjoern Hoehrmann <[email-masked]>
Date: Thu, 08 Sep 2011 04:47:09 +0200

>policing that there are [0,1] protocols accepted.

There is always exactly one sub-protocol, the only difference is that
you can identify the sub-protocol if you want to. If you intermix foo
and bar then the definition of how they are mixed is the sub-protocol
and "foo" and "bar" handling occurs on a layer below it. Sub-protocols
are things you can write a reliable Wireshark dissector for. You can
write one for "foo", but you cannot write one for "foo and bar mixed
in some unidentified application-specific manner".
-- 
Björn Höhrmann · mailto:[email-masked] · http://bjoern.hoehrmann.de
Am Badedeich 7 · Telefon: +49(0)160/4415681 · http://www.bjoernsworld.de
25899 Dagebüll · PGP Pub. KeyID: 0xA4357E78 · http://www.websitedev.de/

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Thu, 8 Sep 2011 11:13:45 +0200

> Otherwise it can close the connection.

No, the client cannot close the connection because the server replied
488 so there is no established WS connection.

> of round trips is the same and the same behaviour can be achieved easily in

This is a negotiation. If Client wants to speak "foo" or "bar" but the
server does not support any of them, the server should reply 488 (such
response could/MUST include a Sec-WebSocket-Protocol with the
subprotocols the server supports).

I see no reason for the server to reply 101 in the case it does not
support any subprotocol offered by the client.

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

---

From: Iñaki Baz Castillo <[email-masked]>
Date: Thu, 8 Sep 2011 11:16:05 +0200

2011/9/8 Greg Wilkins <[email-masked]>:
> example I might want to use an oauth protocol with a chat protocol

So could then the client send WS messages of type "foo" and "bar"???
how is the server supposed to detect which subprotocol each message
belongs to? This exotic feature would require an extra layer
identifying the subprotocol for each message.

Bad IMHO. By definition there is a *single* WS subprotocol on top of a
WebSocket connection.

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

---

From: Greg Wilkins <[email-masked]>
Date: Thu, 8 Sep 2011 19:31:35 +1000

> identifying the subprotocol for each message.

This is not the case. They are ordered, so there is no need for an
extra layer (just as we don't have an extra layer for extensions, but
allow multiple ones to be active).

> Bad IMHO. By definition there is a *single* WS subprotocol on top of a

Fine - as I said, unless there is quick universal support for this,
it's not worth delaying.

I think the confusion is due to the fact that subprotocols are really
underspecified and I'm sure that we all have different mental pictures
of what they could be.   Unfortunately I don't think we have time to
work out a single subprotocol vision and then work out if multiple
subprotocols is useful or not.

So let's leave it as is.

regards

---

From: "Joonas Lehtolahti" <[email-masked]>
Date: Thu, 08 Sep 2011 11:58:40 +0200

> subprotocols is useful or not.

What about using subprotocol such as "foo+bar"? Technically it is  
different from "foo" and "bar", a single third subprotocol, but it is  
application layer interpretation anyway and can be accepted as meaning of  
combining the two separate subprotocols in a specific way that both the  
client and server knows.

---

From: Peter Saint-Andre <[email-masked]>
Date: Thu, 08 Sep 2011 06:09:50 -0600

<hat type='individual'/>

> subprotocols is useful or not.

I tend to agree that such a vision will be worked out through
implementation and deployment of WebSocket over the next few years. We
can't know everything in advance.

Peter

-- 
Peter Saint-Andre
https://stpeter.im/