Skip to content
Permalink
Browse files

[giow] (1) Make WebSockets support subprotocol negotiation.

git-svn-id: http://svn.whatwg.org/webapps@5173 340c8d12-0b0e-0410-8428-c7bf67bfef74
  • Loading branch information...
Hixie committed Jul 21, 2010
1 parent 2b219e6 commit eb678d8ed1829ec976b19657273f5f1fabb5ecc1
Showing with 202 additions and 120 deletions.
  1. +97 −59 complete.html
  2. +1 −0 index
  3. +104 −61 source

<h4 id=the-websocket-interface><span class=secno>10.3.2 </span>The <code><a href=#websocket>WebSocket</a></code> interface</h4>

<pre class=idl>[<a href=#dom-websocket title=dom-WebSocket>Constructor</a>(in DOMString url, in optional DOMString protocol)]
<pre class=idl>[<a href=#dom-websocket title=dom-WebSocket>Constructor</a>(in DOMString url, in optional DOMString protocols)]
[<a href=#dom-websocket title=dom-WebSocket>Constructor</a>(in DOMString url, in optional DOMString[] protocols)]
interface <dfn id=websocket>WebSocket</dfn> {
readonly attribute DOMString <a href=#dom-websocket-url title=dom-WebSocket-url>url</a>;

attribute <a href=#function>Function</a> <a href=#handler-websocket-onmessage title=handler-WebSocket-onmessage>onmessage</a>;
attribute <a href=#function>Function</a> <a href=#handler-websocket-onerror title=handler-WebSocket-onerror>onerror</a>;
attribute <a href=#function>Function</a> <a href=#handler-websocket-onclose title=handler-WebSocket-onclose>onclose</a>;
readonly attribute DOMString <a href=#dom-websocket-protocol title=dom-WebSocket-protocol>protocol</a>;
boolean <a href=#dom-websocket-send title=dom-WebSocket-send>send</a>(in DOMString data);
void <a href=#dom-websocket-close title=dom-WebSocket-close>close</a>();
};
<a href=#websocket>WebSocket</a> implements <a href=#eventtarget>EventTarget</a>;</pre>

<p>The <dfn id=dom-websocket title=dom-WebSocket><code>WebSocket(<var title="">url</var>, <var title="">protocol</var>)</code></dfn>
<p>The <dfn id=dom-websocket title=dom-WebSocket><code>WebSocket(<var title="">url</var>, <var title="">protocols</var>)</code></dfn>
constructor takes one or two arguments. The first argument, <var title="">url</var>, specifies the <a href=#url>URL</a> to which to
connect. The second, <var title="">protocol</var>, if present,
specifies a sub-protocol that the server must support for the
connection to be successful. The sub-protocol name must be a
non-empty ASCII string with no control characters in it (i.e. only
characters in the range U+0020 to U+007E).</p>
connect. The second, <var title="">protocols</var>, if present, is
either a string or an array of strings. If it is a string, it is
equivalent to an array consisting of just that string; if it is
omitted, it is equivalent to the empty array. Each string in the
array is a subprotocol name. The connection will only be established
if the server reports that it has selected one of these
subprotocols. The subprotocol names must all be non-empty ASCII
strings with no control characters and not spaces in them (i.e. only
characters in the range U+0021 to U+007E).</p>

<p>When the <code>WebSocket()</code> constructor is invoked, the UA
must run these steps:</p>

</li>

<li><p>If <var title="">protocol</var> is present but is either the
empty string or contains characters with Unicode code points less
than U+0020 or greater than U+007E (i.e. any characters that are
not printable ASCII characters), then throw a
<li>

<p>If <var title="">protocols</var> is absent, let <var title="">protocols</var> be an empty array.</p>

<p>Otherwise, if <var title="">protocols</var> is present and a
string, let <var title="">protocols</var> instead be an array
consisting of just that string.</p>

</li>

<li><p>If any of the values in <var title="">protocols</var> occur
more than once or contain characters with Unicode code points less
than U+0021 or greater than U+007E (i.e. the space character or any
characters that are not printable ASCII characters), then throw a
<code><a href=#syntax_err>SYNTAX_ERR</a></code> exception and abort these steps.</li>

<li><p>Let <var title="">origin</var> be the <a href=#ascii-serialization-of-an-origin title="ASCII

<p><a href=#establish-a-websocket-connection>Establish a WebSocket connection</a> to a host <var title="">host</var>, on port <var title="">port</var> (if one was
specified), from <var title="">origin</var>, with the flag <var title="">secure</var>, with <var title="">resource name</var> as
the resource name, and with <var title="">protocol</var> as the
protocol (if it is present).</p>
the resource name, and with <var title="">protocols</var> as the
(possibly empty) list of protocols.</p>

<p class=note>If the "<a href=#establish-a-websocket-connection>establish a WebSocket
connection</a>" algorithm fails, it triggers the "<a href=#fail-the-websocket-connection>fail
</dl><p>When the object is created its <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> must be set to
<code title=dom-WebSocket-CONNECTING><a href=#dom-websocket-connecting>CONNECTING</a></code> (0).</p>

<p>The <dfn id=dom-websocket-protocol title=dom-WebSocket-protocol><code>protocol</code></dfn> attribute
must initially return the empty string. After the <a href=#websocket-connection-is-established>WebSocket
connection is established</a>, its value might change, as defined
below.</p>

<p class=note>The <code title=dom-WebSocket-protocol><a href=#dom-websocket-protocol>protocol</a></code> attribute returns the
subprotocol selected by the server, if any. It can be used in
conjunction with the array form of the constructor's second argument
to perform subprotocol negotiation.</p>

<p>The <dfn id=dom-websocket-send title=dom-WebSocket-send><code>send(<var title="">data</var>)</code></dfn> method transmits data using the
connection. If the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute is
<code title=dom-WebSocket-CONNECTING><a href=#dom-websocket-connecting>CONNECTING</a></code>, it must

<p>When the <i><a href=#websocket-connection-is-established>WebSocket connection is established</a></i>, the user
agent must <a href=#queue-a-task>queue a task</a> to first change the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's value
to <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1), and then
<a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-open>open</code> at the <code><a href=#websocket>WebSocket</a></code>
to <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1); then change the
<code title=dom-WebSocket-protocol><a href=#dom-websocket-protocol>protocol</a></code> attribute's
value to the <a href=#selected-websocket-subprotocol>selected WebSocket subprotocol</a>, if there
is one; and then <a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-open>open</code> at the <code><a href=#websocket>WebSocket</a></code>
object.</p>

<p>When <i><a href=#a-websocket-message-has-been-received>a WebSocket message has been received</a></i> with text <var title="">data</var>, the user agent must create an event that uses
and <code title=http-cookie>Cookie</code>, which can used for
sending cookies to the server (e.g. as an authentication
mechanism). The <code title=http-sec-websocket-protocol><a href=#sec-websocket-protocol>Sec-WebSocket-Protocol</a></code>
field takes an arbitrary string:</p>
field takes a space-separated list of strings:</p>

<pre>Sec-WebSocket-Protocol: chat</pre>
<pre>Sec-WebSocket-Protocol: org.example.chat wsxmpp ACME.COM-IM-2</pre>

<p>This field indicates the subprotocol (the application-level
protocol layered over the WebSocket protocol) that the client
intends to use. The server echoes this field in its handshake to
indicate that it supports that subprotocol.</p>
<p>This field indicates the subprotocols (the application-level
protocol layered over the WebSocket protocol) that the client can
use. The server reports which subprotocol it is going to use in its
handshake response.</p>

<p>The other fields in the handshake are all security-related. The
<code title=http-host>Host</code> field is used to protect against
<p>Option fields can also be included. In this version of the
protocol, the main option field is <code title=http-sec-websocket-protocol><a href=#sec-websocket-protocol>Sec-WebSocket-Protocol</a></code>,
which indicates the subprotocol that the server speaks. Web browsers
verify that the server included the same value as was specified in
the <code><a href=#websocket>WebSocket</a></code> constructor, so a server that speaks
multiple subprotocols has to make sure it selects one based on the
client's handshake and specifies the right one in its handshake.</p>
verify that the server specified one of the values that was
specified in the <code><a href=#websocket>WebSocket</a></code> constructor, so a server
that speaks multiple subprotocols has to make sure it selects one
based on the client's handshake and specifies the right one in its
handshake.</p>

<pre>Sec-WebSocket-Protocol: chat</pre>
<pre>Sec-WebSocket-Protocol: org.example.chat</pre>

<p>The server can also set cookie-related option fields to
<em>set</em> cookies, as in HTTP.</p>

<p>Conceptually, WebSocket is really just a layer on top of TCP
that adds a Web "origin"-based security model for browsers; adds an
addressing and protocol naming mechanism to support multiple
addressing and subprotocol naming mechanism to support multiple
services on one port and multiple host names on one IP address;
layers a framing mechanism on top of TCP to get back to the IP
packet mechanism that TCP is built on, but without length
<p>The client can request that the server use a specific subprotocol
by including the <code title=http-sec-websocket-protocol><a href=#sec-websocket-protocol>Sec-Websocket-Protocol</a></code>
field in its handshake. If it is specified, the server needs to
include the same field and value in its response for the connection
to be established.</p>
include an equivalent field in its response for the connection to be
established.</p>

<p>These subprotocol names do not need to be registered, but if a
subprotocol is intended to be implemented by multiple independent
Corporation were to create a Chat subprotocol to be implemented by
many servers around the Web, they could name it
"chat.example.com". If the Example Organisation called their
competing subprotocol "example.org's&nbsp;chat&nbsp;protocol", then
the two subprotocols could be implemented by servers simultaneously,
with the server dynamically selecting which subprotocol to use based
on the value sent by the client.</p>
competing subprotocol "the-example.org-chat-protocol", then the two
subprotocols could be implemented by servers simultaneously, with
the server dynamically selecting which subprotocol to use based on
the value sent by the client.</p>

<p>Subprotocols can be versioned in backwards-incompatible ways by
changing the subprotocol name, eg. going from "bookings.example.net"
<p>When the user agent is to <dfn id=establish-a-websocket-connection>establish a WebSocket
connection</dfn> to a host <var title="">host</var>, on a port <var title="">port</var>, from an origin whose <a href=#ascii-serialization-of-an-origin title="ASCII
serialization of an origin">ASCII serialization</a> is <var title="">origin</var>, with a flag <var title="">secure</var>, with
a string giving a <var title="">resource name</var>, and optionally
with a string giving a <var title="">protocol</var>, it must run the
following steps. The <var title="">host</var> must be ASCII-only
(i.e. it must have been punycode-encoded already if necessary). The
<var title="">origin</var> must not contain characters in the range
a string giving a <var title="">resource name</var>, and with a
(possibly empty) list of strings giving the <var title="">protocols</var>, it must run the following steps. The <var title="">host</var> must be ASCII-only (i.e. it must have been
punycode-encoded already if necessary). The <var title="">origin</var> must not contain characters in the range
U+0041 to U+005A (i.e. LATIN CAPITAL LETTER A to LATIN CAPITAL
LETTER Z). The <var title="">resource name</var> and <var title="">protocol</var> strings must be non-empty strings of ASCII
characters in the range U+0020 to U+007E. The <var title="">resource
name</var> string must start with a U+002F SOLIDUS character (/) and
must not contain a U+0020 SPACE character. <a href=#refsORIGIN>[ORIGIN]</a></p>
LETTER Z). The <var title="">resource name</var> string must be a
non-empty string of ASCII characters in the range U+0021 to U+007E
that starts with a U+002F SOLIDUS character (/). The various strings
in <var title="">protocols</var> must all be non-empty strings with
characters in the range U+0021 to U+007E, and must all be unique. <a href=#refsORIGIN>[ORIGIN]</a></p>

<ol><li>


<li>

<p>If there is no <var title="">protocol</var>, then skip this step.</p>
<p>If the <var title="">protocols</var> list is empty, then skip
this step.</p>

<p>Otherwise, add the string consisting of the concatenation of
the string "Sec-WebSocket-Protocol:", a U+0020 SPACE character,
and the <var title="">protocol</var> value, to <var title="">fields</var>.</p>
and the strings in <var title="">protocols</var>, maintaining
their relative order and each separated from the next by a single
U+0020 SPACE character, to <var title="">fields</var>.</p>

</li>


<dt>If the entry's name is "<code title=http-sec-websocket-protocol><a href=#sec-websocket-protocol>sec-websocket-protocol</a></code>"</dt>

<dd><p>If there was a <var title="">protocol</var> specified, and
the value is not exactly equal to <var title="">protocol</var>,
then <a href=#fail-the-websocket-connection>fail the WebSocket connection</a> and abort these
steps. (If no <var title="">protocol</var> was specified, the
field is ignored.)</dd>
<dd>

<p>If the <var title="">protocols</var> list was not empty, and
the value is not exactly equal to one of the strings in the <var title="">protocols</var> list, then <a href=#fail-the-websocket-connection>fail the WebSocket
connection</a> and abort these steps.</p>

<p>Otherwise, let the <dfn id=selected-websocket-subprotocol>selected WebSocket subprotocol</dfn>
be the entry's value.</p>

</dd>


<dt>If the entry's name is "<code title=http-setcookie>set-cookie</code>" or "<code title=http-setcookie2>set-cookie2</code>" or another

<dd>

<p>The value gives the name of a subprotocol that the client is
intending to select. It would be interesting if the server
supports multiple protocols or protocol versions.</p>
<p>The value gives the names of subprotocols that the client is
willing to use, as a space-separated list in the order that the
client prefers the protocols. It would be interesting if the
server supports multiple protocols or protocol versions.</p>

<p>Can be safely ignored, though the server may <a href=#abort-the-websocket-connection>abort the WebSocket
connection</a> if the field is absent but the conventions for
communicating with the server are such that the field is
expected; and the server should <a href=#abort-the-websocket-connection>abort the WebSocket connection</a>
if the field has a value that does not match one of the
subprotocols that the server supports, to avoid integrity errors
once the connection is established.</p>
<p>Can be safely ignored, though the server may <a href=#abort-the-websocket-connection>abort the
WebSocket connection</a> if the field is absent but the
conventions for communicating with the server are such that the
field is expected; and the server should <a href=#abort-the-websocket-connection>abort the WebSocket
connection</a> if the field does not contain a value that does
matches one of the subprotocols that the server supports, to avoid
integrity errors once the connection is established.</p>

</dd>

James M Snell,
James Perrett,
James Robinson,
Jamie Lokier,
Jan-Klaas Kollhof,
Jason Kersey,
Jason Lustig,
1 index
James M Snell,
James Perrett,
James Robinson,
Jamie Lokier,
Jan-Klaas Kollhof,
Jason Kersey,
Jason Lustig,
Oops, something went wrong.

0 comments on commit eb678d8

Please sign in to comment.
You can’t perform that action at this time.