[html5] r4820 - [giow] (0) Add a closing handshake.
whatwg at whatwg.org
whatwg at whatwg.org
Wed Mar 3 19:17:03 PST 2010
Author: ianh
Date: 2010-03-03 19:17:02 -0800 (Wed, 03 Mar 2010)
New Revision: 4820
Modified:
complete.html
source
Log:
[giow] (0) Add a closing handshake.
Modified: complete.html
===================================================================
--- complete.html 2010-03-03 23:55:02 UTC (rev 4819)
+++ complete.html 2010-03-04 03:17:02 UTC (rev 4820)
@@ -157,7 +157,7 @@
<header class=head id=head><p><a class=logo href=http://www.whatwg.org/ rel=home><img alt=WHATWG src=/images/logo></a></p>
<hgroup><h1>Web Applications 1.0</h1>
- <h2 class="no-num no-toc">Draft Standard — 3 March 2010</h2>
+ <h2 class="no-num no-toc">Draft Standard — 4 March 2010</h2>
</hgroup><p>You can take part in this work. <a href=http://www.whatwg.org/mailing-list>Join the working group's discussion list.</a></p>
<p><strong>Web designers!</strong> We have a <a href=http://blog.whatwg.org/faq/>FAQ</a>, a <a href=http://forums.whatwg.org/>forum</a>, and a <a href=http://www.whatwg.org/mailing-list#help>help mailing list</a> for you!</p>
<!--<p class="impl"><strong>Implementors!</strong> We have a <a href="http://www.whatwg.org/mailing-list#implementors">mailing list</a> for you too!</p>-->
@@ -963,31 +963,34 @@
<ol>
<li><a href=#background-0><span class=secno>10.3.4.1.1 </span>Background</a></li>
<li><a href=#protocol-overview><span class=secno>10.3.4.1.2 </span>Protocol overview</a></li>
- <li><a href=#handshake><span class=secno>10.3.4.1.3 </span>Handshake</a></li>
- <li><a href=#design-philosophy><span class=secno>10.3.4.1.4 </span>Design philosophy</a></li>
- <li><a href=#security-model><span class=secno>10.3.4.1.5 </span>Security model</a></li>
- <li><a href=#relationship-to-tcp-and-http><span class=secno>10.3.4.1.6 </span>Relationship to TCP and HTTP</a></li>
- <li><a href=#establishing-a-connection><span class=secno>10.3.4.1.7 </span>Establishing a connection</a></li>
- <li><a href=#subprotocols-using-the-websocket-protocol><span class=secno>10.3.4.1.8 </span>Subprotocols using the WebSocket protocol</a></li>
- <li><a href=#terminology-1><span class=secno>10.3.4.1.9 </span>Terminology</a></ol></li>
+ <li><a href=#opening-handshake><span class=secno>10.3.4.1.3 </span>Opening Handshake</a></li>
+ <li><a href=#closing-handshake><span class=secno>10.3.4.1.4 </span>Closing Handshake</a></li>
+ <li><a href=#design-philosophy><span class=secno>10.3.4.1.5 </span>Design philosophy</a></li>
+ <li><a href=#security-model><span class=secno>10.3.4.1.6 </span>Security model</a></li>
+ <li><a href=#relationship-to-tcp-and-http><span class=secno>10.3.4.1.7 </span>Relationship to TCP and HTTP</a></li>
+ <li><a href=#establishing-a-connection><span class=secno>10.3.4.1.8 </span>Establishing a connection</a></li>
+ <li><a href=#subprotocols-using-the-websocket-protocol><span class=secno>10.3.4.1.9 </span>Subprotocols using the WebSocket protocol</a></li>
+ <li><a href=#terminology-1><span class=secno>10.3.4.1.10 </span>Terminology</a></ol></li>
<li><a href=#websocket-urls><span class=secno>10.3.4.2 </span>WebSocket URLs</a>
<ol>
<li><a href=#parsing-websocket-urls><span class=secno>10.3.4.2.1 </span>Parsing WebSocket URLs</a></li>
<li><a href=#constructing-websocket-urls><span class=secno>10.3.4.2.2 </span>Constructing WebSocket URLs</a></ol></li>
<li><a href=#client-side-requirements><span class=secno>10.3.4.3 </span>Client-side requirements</a>
<ol>
- <li><a href=#handshake-0><span class=secno>10.3.4.3.1 </span>Handshake</a></li>
+ <li><a href=#opening-handshake-0><span class=secno>10.3.4.3.1 </span>Opening Handshake</a></li>
<li><a href=#data-framing><span class=secno>10.3.4.3.2 </span>Data framing</a></li>
- <li><a href=#failing-the-connection><span class=secno>10.3.4.3.3 </span>Failing the connection</a></li>
- <li><a href=#handling-errors-in-utf-8><span class=secno>10.3.4.3.4 </span>Handling errors in UTF-8</a></ol></li>
+ <li><a href=#handling-errors-in-utf-8-from-the-server><span class=secno>10.3.4.3.3 </span>Handling errors in UTF-8 from the server</a></ol></li>
<li><a href=#server-side-requirements><span class=secno>10.3.4.4 </span>Server-side requirements</a>
<ol>
- <li><a href="#reading-the-client's-handshake"><span class=secno>10.3.4.4.1 </span>Reading the client's handshake</a></li>
- <li><a href="#sending-the-server's-handshake"><span class=secno>10.3.4.4.2 </span>Sending the server's handshake</a></li>
+ <li><a href="#reading-the-client's-opening-handshake"><span class=secno>10.3.4.4.1 </span>Reading the client's opening handshake</a></li>
+ <li><a href="#sending-the-server's-opening-handshake"><span class=secno>10.3.4.4.2 </span>Sending the server's opening handshake</a></li>
<li><a href=#ws-sd-framing><span class=secno>10.3.4.4.3 </span>Data framing</a></li>
- <li><a href=#aborting-the-connection><span class=secno>10.3.4.4.4 </span>Aborting the connection</a></li>
- <li><a href=#handling-errors-in-utf-8-0><span class=secno>10.3.4.4.5 </span>Handling errors in UTF-8</a></ol></li>
- <li><a href=#closing-the-connection><span class=secno>10.3.4.5 </span>Closing the connection</a></li>
+ <li><a href=#handling-errors-in-utf-8-from-the-client><span class=secno>10.3.4.4.4 </span>Handling errors in UTF-8 from the client</a></ol></li>
+ <li><a href=#closing-the-connection><span class=secno>10.3.4.5 </span>Closing the connection</a>
+ <ol>
+ <li><a href=#client-initiated-closure><span class=secno>10.3.4.5.1 </span>Client-initiated closure</a></li>
+ <li><a href=#server-initiated-closure><span class=secno>10.3.4.5.2 </span>Server-initiated closure</a></li>
+ <li><a href=#closure><span class=secno>10.3.4.5.3 </span>Closure</a></ol></li>
<li><a href=#security-considerations><span class=secno>10.3.4.6 </span>Security considerations</a></li>
<li><a href=#iana-considerations-0><span class=secno>10.3.4.7 </span>IANA considerations</a>
<ol>
@@ -66934,14 +66937,15 @@
// ready state
const unsigned short <a href=#dom-websocket-connecting title=dom-WebSocket-CONNECTING>CONNECTING</a> = 0;
const unsigned short <a href=#dom-websocket-open title=dom-WebSocket-OPEN>OPEN</a> = 1;
- const unsigned short <a href=#dom-websocket-closed title=dom-WebSocket-CLOSED>CLOSED</a> = 2;
+ const unsigned short <a href=#dom-websocket-closing title=dom-WebSocket-CLOSING>CLOSING</a> = 2;
+ const unsigned short <a href=#dom-websocket-closed title=dom-WebSocket-CLOSED>CLOSED</a> = 3;
readonly attribute unsigned short <a href=#dom-websocket-readystate title=dom-WebSocket-readyState>readyState</a>;
readonly attribute unsigned long <a href=#dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount>bufferedAmount</a>;
// networking
attribute <a href=#function>Function</a> <a href=#handler-websocket-onopen title=handler-WebSocket-onopen>onopen</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-onmessageerror title=handler-WebSocket-onmessageerror>onmessageerror</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>;
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>();
@@ -67025,8 +67029,12 @@
<dd>The <a href=#websocket-connection-is-established>WebSocket connection is established</a> and communication is possible.</dd>
- <dt><dfn id=dom-websocket-closed title=dom-WebSocket-CLOSED><code>CLOSED</code></dfn> (numeric value 2)</dt>
+ <dt><dfn id=dom-websocket-closing title=dom-WebSocket-CLOSING><code>CLOSING</code></dfn> (numeric value 2)</dt>
+ <dd>The connection is going through the closing handshake.</dd>
+
+ <dt><dfn id=dom-websocket-closed title=dom-WebSocket-CLOSED><code>CLOSED</code></dfn> (numeric value 3)</dt>
+
<dd>The connection has been closed or could not be opened.</dd>
</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
@@ -67037,27 +67045,87 @@
<code title=dom-WebSocket-CONNECTING><a href=#dom-websocket-connecting>CONNECTING</a></code>, it must
raise an <code><a href=#invalid_state_err>INVALID_STATE_ERR</a></code> exception. If the <var title="">data</var> argument has any unpaired surrogates, then it
must raise <code><a href=#syntax_err>SYNTAX_ERR</a></code>. If the connection is
- established, and the string has no unpaired surrogates, then the
- user agent must <a href=#send-data-using-the-websocket>send <var title="">data</var> using the
+ established, and the string has no unpaired surrogates, and <a href=#the-websocket-closing-handshake-has-started title="the WebSocket closing handshake has started">the WebSocket
+ closing handshake has not yet started</a>, then the user agent
+ must <a href=#send-data-using-the-websocket>send <var title="">data</var> using the
WebSocket</a>. If the data cannot be sent, e.g. because it would
need to be buffered but the buffer is full, the user agent must
<a href=#close-the-websocket-connection>close the WebSocket connection</a>. The method must then
return true if the connection is still established (and the data was
- queued or sent successfully), or false if the connection is closed
- (e.g. because the user agent just had a buffer overflow and failed
- to send the data).</p>
+ queued or sent successfully), or false if the connection is closing
+ or closed (e.g. because the user agent just had a buffer overflow
+ and failed to send the data, or because <a href=#the-websocket-closing-handshake-has-started>the WebSocket closing
+ handshake has started</a>).</p>
<p>The <dfn id=dom-websocket-close title=dom-WebSocket-close><code>close()</code></dfn>
- method must <a href=#close-the-websocket-connection>close the WebSocket connection</a> or
- connection attempt, if any, and change the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's value
- to <code title=dom-WebSocket-CLOSED><a href=#dom-websocket-closed>CLOSED</a></code> (2). If the
- connection is already closed, it must do nothing.</p>
+ method must run the first matching steps from the following list:</p>
- <p class=note>Closing the connection immediately causes a task to
- be queued to fire a <code title=event-close>close</code> event, as
- <a href=#closeWebSocket>described below</a>.</p>
+ <dl class=switch><dt>If the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
+ attribute is in the <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2) or <code title=dom-WebSocket-CLOSED><a href=#dom-websocket-closed>CLOSED</a></code> (3) state</dt>
- <hr><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn>
+ <dd>
+
+ <p>Do nothing.</p>
+
+ <p class=note>The connection is already closing or is already
+ closed. If it has not already, a <code title=event-close>close</code> event will eventually fire <a href=#closeWebSocket>as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>If the WebSocket connection is not yet <a href=#websocket-connection-is-established title="WebSocket
+ connection is established">established</a></dt>
+
+ <dd>
+
+ <p><a href=#fail-the-websocket-connection>Fail the WebSocket connection</a> and set the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's
+ value to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code>
+ (2).</p>
+
+ <p class=note>The "<a href=#fail-the-websocket-connection>fail the WebSocket connection</a>"
+ algorithm invokes the "<a href=#close-the-websocket-connection>close the WebSocket
+ connection</a>" algorithm, which then establishes that the
+ "<a href=#websocket-connection-is-closed>WebSocket connection is closed</a>", which fires the
+ <code title=event-close>close</code> event <a href=#closeWebSocket>as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>If the WebSocket closing handshake has not yet been <a href=#the-websocket-closing-handshake-has-started title="the WebSocket closing handshake has
+ started">started</a></dt>
+
+ <dd>
+
+ <p><a href=#start-the-websocket-closing-handshake>Start the WebSocket closing handshake</a> and set the
+ <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
+ attribute's value to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2).</p>
+
+ <p class=note>The "<a href=#start-the-websocket-closing-handshake>start the WebSocket closing
+ handshake</a>" algorithm eventually invokes the "<a href=#close-the-websocket-connection>close
+ the WebSocket connection</a>" algorithm, which then establishes
+ that the "<a href=#websocket-connection-is-closed>WebSocket connection is closed</a>", which
+ fires the <code title=event-close>close</code> event <a href=#closeWebSocket>as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>Otherwise</dt>
+
+ <dd>
+
+ <p>Set the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's
+ value to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code>
+ (2).</p>
+
+ <p class=note><a href=#the-websocket-closing-handshake-has-started>The WebSocket closing handshake has
+ started</a>, and will eventually invokethe "<a href=#close-the-websocket-connection>close the
+ WebSocket connection</a>" algorithm, which will establish that
+ the "<a href=#websocket-connection-is-closed>WebSocket connection is closed</a>", and thus the
+ <code title=event-close>close</code> event will fire, <a href=#closeWebSocket>as described below</a>.</p>
+
+ </dd>
+
+ </dl><hr><p>The <dfn id=dom-websocket-bufferedamount title=dom-WebSocket-bufferedAmount><code>bufferedAmount</code></dfn>
attribute must return the number of bytes that have been queued but
not yet sent. This does not include framing overhead incurred by the
protocol. If the connection is closed, this attribute's value will
@@ -67095,7 +67163,7 @@
<table><thead><tr><th><a href=#event-handlers title="event handlers">Event handler</a> <th><a href=#event-handler-event-type>Event handler event type</a>
<tbody><tr><td><dfn id=handler-websocket-onopen title=handler-WebSocket-onopen><code>onopen</code></dfn> <td> <code title=event-open>open</code>
<tr><td><dfn id=handler-websocket-onmessage title=handler-WebSocket-onmessage><code>onmessage</code></dfn> <td> <code title=event-message><a href=#event-message>message</a></code>
- <tr><td><dfn id=handler-websocket-onmessageerror title=handler-WebSocket-onmessageerror><code>onmessageerror</code></dfn> <td> <code title=event-messageerror>messageerror</code>
+ <tr><td><dfn id=handler-websocket-onerror title=handler-WebSocket-onerror><code>onerror</code></dfn> <td> <code title=event-error>error</code>
<tr><td><dfn id=handler-websocket-onclose title=handler-WebSocket-onclose><code>onclose</code></dfn> <td> <code title=event-close>close</code>
</table><h4 id=feedback-from-the-protocol><span class=secno>10.3.3 </span>Feedback from the protocol</h4>
@@ -67110,28 +67178,35 @@
cancelable, has no default action, and whose <code title=dom-MessageEvent-data><a href=#dom-messageevent-data>data</a></code> attribute is set to <var title="">data</var>, and <a href=#queue-a-task>queue a task</a> to check to see
if the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
attribute's value is <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code>
- (1), and if so, dispatch the event at the <code><a href=#websocket>WebSocket</a></code>
- object.</p>
+ (1) or <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2), and
+ if so, dispatch the event at the <code><a href=#websocket>WebSocket</a></code> object.</p>
<p>When <i><a href=#a-websocket-error-has-been-detected>a WebSocket error has been detected</a></i>, the user agent
- must <a href=#queue-a-task>queue a task</a> to set to <var title="">data</var>,
- and <a href=#queue-a-task>queue a task</a> to check to see if the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's value
- is <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1), and if so,
- <a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-messageerror>messageerror</code> at the <code><a href=#websocket>WebSocket</a></code>
+ must <a href=#queue-a-task>queue a task</a> to check to see if the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's value
+ is <code title=dom-WebSocket-OPEN><a href=#dom-websocket-open>OPEN</a></code> (1) or <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2), and if so,
+ <a href=#fire-a-simple-event>fire a simple event</a> named <code title=event-error>error</code> at the <code><a href=#websocket>WebSocket</a></code>
object.</p>
- <p id=closeWebSocket>When the <i><a href=#websocket-connection-is-closed>WebSocket connection is
- closed</a></i>, the user agent must create an event that uses the
- <code><a href=#closeevent>CloseEvent</a></code> interface, with the event name <code title=event-close>close</code>, which does not bubble, is not
- cancelable, has no default action, and whose <code title=dom-CloseEvent-wasClean><a href=#dom-closeevent-wasclean>wasClean</a></code> attribute is set to
- false, and <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-CLOSED><a href=#dom-websocket-closed>CLOSED</a></code> (2), and then
- dispatch the event at the <code><a href=#websocket>WebSocket</a></code> object. (If the
+ <p>When <i><a href=#the-websocket-closing-handshake-has-started>the WebSocket closing handshake has started</a></i>, the user
+ agent must <a href=#queue-a-task>queue a task</a> to change the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code> attribute's value
+ to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2). (If the
<code title=dom-WebSocket-close><a href=#dom-websocket-close>close()</a></code> method was called,
the <code title=dom-WebSocket-readyState><a href=#dom-websocket-readystate>readyState</a></code>
- attribute's value will already be set to <code title=dom-WebSocket-CLOSED><a href=#dom-websocket-closed>CLOSED</a></code> (2) when this task
+ attribute's value will already be set to <code title=dom-WebSocket-CLOSING><a href=#dom-websocket-closing>CLOSING</a></code> (2) when this task
runs.)</p>
+ <p id=closeWebSocket>When the <i><a href=#websocket-connection-is-closed>WebSocket connection is
+ closed</a></i>, possibly <i title="">cleanly</i>, the user agent must
+ create an event that uses the <code><a href=#closeevent>CloseEvent</a></code> interface,
+ with the event name <code title=event-close>close</code>, which
+ does not bubble, is not cancelable, has no default action, and whose
+ <code title=dom-CloseEvent-wasClean><a href=#dom-closeevent-wasclean>wasClean</a></code> attribute is
+ set to true if the connection closed <i title="">cleanly</i> and
+ false otherwise; and <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-CLOSED><a href=#dom-websocket-closed>CLOSED</a></code> (3), and
+ then dispatch the event at the <code><a href=#websocket>WebSocket</a></code> object.</p>
+
<p>The <a href=#task-source>task source</a> for all <a href=#concept-task title=concept-task>tasks</a> <a href=#queue-a-task title="queue a
task">queued</a> in this section is the <dfn id=websocket-task-source>WebSocket task
source</dfn>.</p>
@@ -67301,17 +67376,20 @@
specifications to implement buffering and piecing together of
messages manually.</p>
- <!-- XXX Close Handshake -->
+ <p>To close the connection cleanly, a frame consisting of just a
+ 0xFF byte followed by a 0x00 byte is sent from one peer to ask that
+ the other peer close the connection.</p>
<p>The protocol is designed to support other frame types in
- future. Instead of the 0x00 byte, other bytes might in future be
- defined. Frames denoted by bytes that do not have the high bit set
- (0x00 to 0x7F) are treated as described above (a stream of bytes
- terminated by 0xFF). Frames denoted by bytes that have the high bit
- set (0x80 to 0xFF) have a leading length indicator, which is encoded
- as a series of 7-bit bytes stored in octets with the 8th bit being
- set for all but the last byte. The remainder of the frame is then as
- much data as was specified.</p>
+ future. Instead of the 0x00 and 0xFF bytes, other bytes might in
+ future be defined. Frames denoted by bytes that do not have the high
+ bit set (0x00 to 0x7F) are treated as a stream of bytes terminated
+ by 0xFF. Frames denoted by bytes that have the high bit set (0x80 to
+ 0xFF) have a leading length indicator, which is encoded as a series
+ of 7-bit bytes stored in octets with the 8th bit being set for all
+ but the last byte. The remainder of the frame is then as much data
+ as was specified. (The closing handshake contains no data and
+ therefore has a length byte of 0x00.)</p>
<p>This wire format for the data transfer part is described by the
following non-normative ABNF, which is given in two alternative
@@ -67322,16 +67400,16 @@
</p>
- <!-- XXX Close Handshake -->
<pre>; the wire protocol as allowed by this specification
frames = *frame
-frame = text-frame
-text-frame = (%x00) *( UTF8-char ) %xFF
+frame = text-frame / closing-frame
+text-frame = %x00 *( UTF8-char ) %xFF
+closing-frame = %xFF %x00
; the wire protocol including error-handling and forward-compatible parsing rules
frames = *frame
frame = text-frame / binary-frame
-text-frame = (%x00-7F) *( UTF8-char / %x80-FE ) %xFF
+text-frame = (%x00-7F) *(%x00-FE) %xFF
binary-frame = (%x80-FF) length < as many bytes as given by the length >
length = *(%x80-FF) (%x00-7F)</pre>
@@ -67340,34 +67418,36 @@
<p class=note>The above ABNF is intended for a binary octet
environment.</p>
- <!-- XXX Close Handshake -->
<p class=warning>At this time, the WebSocket protocol cannot be
used to send binary data. Using any of the frame types other than
- 0x00 is invalid.</p>
+ 0x00 and 0xFF is invalid.</p>
- <hr><p>The following diagrams summarise the protocol:</p>
+ <hr><p>The following diagram summarises the protocol:</p>
<pre>Handshake
|
V
-Frame type byte <-------------------------------------.
- | | |
- | `-- (0x00 to 0x7F) --> Data... --> 0xFF -->-+
- | |
- `-- (0x80 to 0xFF) --> Length --> Data... ------->-'</pre>
+Frame type byte <--------------------------------------.
+ | | |
+ | `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
+ | |
+ `--> (0x80 to 0xFE) --> Length --> Data... ------->-'
+</pre>
- <h6 id=handshake><span class=secno>10.3.4.1.3 </span>Handshake</h6>
+ <h6 id=opening-handshake><span class=secno>10.3.4.1.3 </span>Opening Handshake</h6>
+
<p><i>This section is non-normative.</i></p>
- <p>The handshake is intended to be compatible with HTTP-based
- server-side software, so that a single port can be used by both HTTP
- clients talking to that server and WebSocket clients talking to that
- server. To this end, the WebSocket client's handshake appears to
- HTTP servers to be a regular GET request with an Upgrade offer:</p>
+ <p>The opening handshake is intended to be compatible with
+ HTTP-based server-side software, so that a single port can be used
+ by both HTTP clients talking to that server and WebSocket clients
+ talking to that server. To this end, the WebSocket client's
+ handshake appears to HTTP servers to be a regular GET request with
+ an Upgrade offer:</p>
<pre>GET /resource HTTP/1.1
Upgrade: WebSocket
@@ -67508,9 +67588,35 @@
man-in-the-middle cache or proxy.</p>
+ <h6 id=closing-handshake><span class=secno>10.3.4.1.4 </span>Closing Handshake</h6>
- <h6 id=design-philosophy><span class=secno>10.3.4.1.4 </span>Design philosophy</h6>
+ <p><i>This section is non-normative.</i></p>
+ <p>The closing handshake is far simpler than the opening handshake.</p>
+
+ <p>Either peer can send a 0xFF frame with length 0x00 to begin the
+ closing handshake. Upon receiving a 0xFF frame, the other peer
+ sends an identical 0xFF frame in acknowledgement, if it hasn't
+ already sent one. Upon receiving <em>that</em> 0xFF frame, the first
+ peer then closes the connection, safe in the knowledge that no
+ further data is forthcoming.</p>
+
+ <p>After sending a 0xFF frame, a peer does not send any further
+ data; after receiving a 0xFF frame, a peer discards any further
+ data received.</p>
+
+ <p>It is safe for both peers to initiate this handshake
+ simultaneously.</p>
+
+ <p>The closing handshake is intended to replace the TCP closing
+ handshake (FIN/ACK), on the basis that the TCP closing handshake is
+ not always reliable end-to-end, especially in the presence of
+ man-in-the-middle proxies and other intermediaries.</p>
+
+
+
+ <h6 id=design-philosophy><span class=secno>10.3.4.1.5 </span>Design philosophy</h6>
+
<p><i>This section is non-normative.</i></p>
<p>The WebSocket protocol is designed on the principle that there
@@ -67524,13 +67630,11 @@
<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
- services on one port and multiple host names on one IP address; and
+ 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
- limits.
+ limits; and reimplements the closing handshake in-band.
- <!-- XXX Close Handshake -->
-
Other than that, it adds nothing. Basically it is intended
to be as close to just exposing raw TCP to script as possible
given the constraints of the Web. It's also designed in such a way
@@ -67542,7 +67646,7 @@
sending binary data.</p>
- <h6 id=security-model><span class=secno>10.3.4.1.5 </span>Security model</h6>
+ <h6 id=security-model><span class=secno>10.3.4.1.6 </span>Security model</h6>
<p><i>This section is non-normative.</i></p>
@@ -67574,7 +67678,7 @@
<code>XMLHttpRequest</code>.</p>
- <h6 id=relationship-to-tcp-and-http><span class=secno>10.3.4.1.6 </span>Relationship to TCP and HTTP</h6>
+ <h6 id=relationship-to-tcp-and-http><span class=secno>10.3.4.1.7 </span>Relationship to TCP and HTTP</h6>
<p><i>This section is non-normative.</i></p>
@@ -67587,7 +67691,7 @@
over TLS.</p>
- <h6 id=establishing-a-connection><span class=secno>10.3.4.1.7 </span>Establishing a connection</h6>
+ <h6 id=establishing-a-connection><span class=secno>10.3.4.1.8 </span>Establishing a connection</h6>
<p><i>This section is non-normative.</i></p>
@@ -67617,7 +67721,7 @@
- <h6 id=subprotocols-using-the-websocket-protocol><span class=secno>10.3.4.1.8 </span>Subprotocols using the WebSocket protocol</h6>
+ <h6 id=subprotocols-using-the-websocket-protocol><span class=secno>10.3.4.1.9 </span>Subprotocols using the WebSocket protocol</h6>
<p><i>This section is non-normative.</i></p>
@@ -67650,7 +67754,7 @@
- <h6 id=terminology-1><span class=secno>10.3.4.1.9 </span>Terminology</h6>
+ <h6 id=terminology-1><span class=secno>10.3.4.1.10 </span>Terminology</h6>
<p>When an implementation is required to <i>send</i> data as part of
@@ -67756,7 +67860,7 @@
establish to a server.</p>
- <h6 id=handshake-0><span class=secno>10.3.4.3.1 </span>Handshake</h6>
+ <h6 id=opening-handshake-0><span class=secno>10.3.4.3.1 </span>Opening Handshake</h6>
<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
@@ -68590,7 +68694,7 @@
<li id=ws-cd-length><p><i>Length</i>: Read a byte, let <var title="">b</var> be that byte.</li>
- <li><p>Let <var title="">b<sub title="">v</sub></var> be
+ <li><p>Let <var title="">b<sub title="">v</sub></var> be an
integer corresponding to the low 7 bits of <var title="">b</var>
(the value you would get by <i>and</i>ing <var title="">b</var>
with 0x7F).</li>
@@ -68606,8 +68710,34 @@
<li><p>Discard the read bytes.</li>
- <li><p>Let <var title="">error</var> be true.</li>
+ <li>
+ <p>If the <var title="">frame type</var> is 0xFF and the <var title="">length</var> was 0, then run the following
+ substeps:</p>
+
+ <ol><li>If <a href=#the-websocket-closing-handshake-has-started title="the WebSocket closing handshake has
+ started">the WebSocket closing handshake has not yet
+ started</a>, then <a href=#start-the-websocket-closing-handshake>start the WebSocket closing
+ handshake</a>.</li>
+
+ <li>Wait until either <a href=#the-websocket-closing-handshake-has-started>the WebSocket closing handshake
+ has started</a> or the <a href=#websocket-connection-is-closed>WebSocket connection is
+ closed</a>.</li>
+
+ <li>If the <a href=#websocket-connection-is-closed title="WebSocket connection is
+ closed">WebSocket connection is not already closed</a>,
+ then <a href=#close-the-websocket-connection>close the WebSocket connection</a>: <dfn id=the-websocket-closing-handshake-has-finished>The
+ WebSocket closing handshake has finished</dfn>. (If the
+ connection closes before this happens, then the closing
+ handshake doesn't finish.)</li>
+
+ <li>Abort these steps. Any data on the connection after the
+ 0xFF frame is discarded.</li>
+
+ </ol><p>Otherwise, let <var title="">error</var> be true.</p>
+
+ </li>
+
</ol></dd>
<dt>If the high-order bit of the <var title="">frame type</var>
@@ -68638,9 +68768,9 @@
<li>
<p>If <var title="">error</var> is true, then <dfn id=a-websocket-error-has-been-detected>a WebSocket
- error has been detected</dfn>.</li>
+ error has been detected</dfn>.</p>
-
+ </li>
<li><p>Return to the first step to read the next byte.</li>
@@ -68650,7 +68780,8 @@
resource starvation, then it must <a href=#fail-the-websocket-connection>fail the WebSocket
connection</a>.</p>
- <hr><p>Once a <a href=#websocket-connection-is-established>WebSocket connection is established</a>, the
+ <hr><p>Once a <a href=#websocket-connection-is-established>WebSocket connection is established</a>, but
+ before <a href=#the-websocket-closing-handshake-has-started>the WebSocket closing handshake has started</a>, the
user agent must use the following steps to <dfn id=send-data-using-the-websocket>send <var title="">data</var> using the WebSocket</dfn>:</p>
<ol><li><p>Send a 0x00 byte to the server.</li>
@@ -68660,7 +68791,36 @@
<li><p>Send a 0xFF byte to the server.</li>
- </ol><p>If at any point there is a fatal problem with sending data to the
+ </ol><p>Once <a href=#the-websocket-closing-handshake-has-started>the WebSocket closing handshake has started</a>,
+ the user agent must not send any further data on the connection.</p>
+
+ <hr><p>Once a <a href=#websocket-connection-is-established>WebSocket connection is established</a>, the user
+ agent must use the following steps to <dfn id=start-the-websocket-closing-handshake>start the WebSocket
+ closing handshake</dfn>. These steps must be run asynchronously
+ relative to whatever algorithm invoked this one.</p>
+
+ <ol><li><p>If <a href=#the-websocket-closing-handshake-has-started>the WebSocket closing handshake has started</a>,
+ then abort these steps.</li>
+
+ <li><p>Send a 0xFF byte to the server.</li>
+
+ <li><p>Send a 0x00 byte to the server.</li>
+
+ <li><p><dfn id=the-websocket-closing-handshake-has-started>The WebSocket closing handshake has started</dfn>.</li>
+
+ <li><p>Wait a user-agent-determined length of time, or until the
+ <a href=#websocket-connection-is-closed>WebSocket connection is closed</a>.</p>
+
+ <li>If the <a href=#websocket-connection-is-closed title="WebSocket connection is closed">WebSocket
+ connection is not already closed</a>, then <a href=#close-the-websocket-connection>close the
+ WebSocket connection</a>. (If this happens, then the closing
+ handshake doesn't finish.)</li>
+
+ </ol><p class=note>The closing handshake <a href=#the-websocket-closing-handshake-has-finished title="the WebSocket
+ closing handshake has finished">finishes</a> once the server
+ returns the 0xFF packet, as described above.</p>
+
+ <hr><p>If at any point there is a fatal problem with sending data to the
server, the user agent must <a href=#fail-the-websocket-connection>fail the WebSocket
connection</a>.</p>
@@ -68670,22 +68830,8 @@
data. -->
- <h6 id=failing-the-connection><span class=secno>10.3.4.3.3 </span>Failing the connection</h6>
+ <h6 id=handling-errors-in-utf-8-from-the-server><span class=secno>10.3.4.3.3 </span>Handling errors in UTF-8 from the server</h6>
- <p>To <dfn id=fail-the-websocket-connection>fail the WebSocket connection</dfn>, the user agent must
- <a href=#close-the-websocket-connection>close the WebSocket connection</a>, and may report the
- problem to the user (which would be especially useful for
- developers). However, user agents must not convey the failure
- information to the script that attempted the connection in a way
- distinguishable from the WebSocket being closed normally.</p>
-
- <p>Except as indicated above or as specified by the application
- layer (e.g. a script using the WebSocket API), user agents should
- not close the connection.</p>
-
-
- <h6 id=handling-errors-in-utf-8><span class=secno>10.3.4.3.4 </span>Handling errors in UTF-8</h6>
-
<p>When a client is to interpret a byte stream as UTF-8 but finds
that the byte stream is not in fact a valid UTF-8 stream, then any
bytes or sequences of bytes that are not valid UTF-8 sequences must
@@ -68698,12 +68844,12 @@
<p><i>This section only applies to servers.</i></p>
- <h6 id="reading-the-client's-handshake"><span class=secno>10.3.4.4.1 </span>Reading the client's handshake</h6>
+ <h6 id="reading-the-client's-opening-handshake"><span class=secno>10.3.4.4.1 </span>Reading the client's opening handshake</h6>
<p>When a client starts a WebSocket connection, it sends its part of
- the handshake. The server must parse at least part of this handshake
- in order to obtain the necessary information to generate the server
- part of the handshake.</p>
+ the opening handshake. The server must parse at least part of this
+ handshake in order to obtain the necessary information to generate
+ the server part of the handshake.</p>
<p>The client handshake consists of the following parts. If the
server, while reading the handshake, finds that the client did not
@@ -68896,7 +69042,7 @@
doesn't support.</p>
- <h6 id="sending-the-server's-handshake"><span class=secno>10.3.4.4.2 </span>Sending the server's handshake</h6>
+ <h6 id="sending-the-server's-opening-handshake"><span class=secno>10.3.4.4.2 </span>Sending the server's opening handshake</h6>
<p>When a client establishes a WebSocket connection to a server, the
server must run the following steps.</p>
@@ -69212,7 +69358,7 @@
<li id=ws-sd-length><p><i>Length</i>: Read a byte, let <var title="">b</var> be that byte.</li>
- <li><p>Let <var title="">b<sub title="">v</sub></var> be
+ <li><p>Let <var title="">b<sub title="">v</sub></var> be an
integer corresponding to the low 7 bits of <var title="">b</var>
(the value you would get by <i>and</i>ing <var title="">b</var>
with 0x7F).</li>
@@ -69228,6 +69374,10 @@
<li><p>Discard the read bytes.</li>
+ <li><p>If <var title="">type</var> is 0xFF and <var title="">length</var> is 0, then set the <var title="">client
+ terminated</var> flag and abort these steps. All further data
+ sent by the client should be discarded.</li>
+
</ol></li>
<li><p>Return to the step labeled <a href=#ws-sd-frame><i>frame</i></a>.</li>
@@ -69244,15 +69394,26 @@
<li><p>Send a 0xFF byte to the client to indicate the end of the
message.</li>
- </ol><h6 id=aborting-the-connection><span class=secno>10.3.4.4.4 </span>Aborting the connection</h6>
+ </ol><hr><p>At any time, the server may decide to terminate the WebSocket
+ connection by running through the following steps:</p>
- <p>To <dfn id=abort-the-websocket-connection>abort the WebSocket connection</dfn> during the
- handshake, the server must <a href=#close-the-websocket-connection>close the WebSocket
- connection</a>.</p>
+ <ol><li><p>Send a 0xFF byte and a 0x00 byte to the client to indicate
+ the start of the closing handshake.</li>
+ <li><p>Wait until the <var title="">client terminated</var> flag
+ has been set, or until a server-defined timeout expires.</li>
- <h6 id=handling-errors-in-utf-8-0><span class=secno>10.3.4.4.5 </span>Handling errors in UTF-8</h6>
+ <li><p><a href=#close-the-websocket-connection>Close the WebSocket connection</a>.</li>
+ </ol><p>Once these steps have started, the server must not send any
+ further data to the server. The 0xFF 0x00 bytes indicate the end of
+ the server's data, and further bytes will be discarded by the
+ client.</p>
+
+
+
+ <h6 id=handling-errors-in-utf-8-from-the-client><span class=secno>10.3.4.4.4 </span>Handling errors in UTF-8 from the client</h6>
+
<p>When a server is to interpret a byte stream as UTF-8 but finds
that the byte stream is not in fact a valid UTF-8 stream, behaviour
is undefined. A server could close the connection, convert invalid
@@ -69265,16 +69426,62 @@
<h5 id=closing-the-connection><span class=secno>10.3.4.5 </span>Closing the connection</h5>
- <p>To <dfn id=close-the-websocket-connection>close the WebSocket connection</dfn>, either the user
- agent or the server closes the TCP connection. There is no
- closing handshake. When a user agent notices that the server has
- closed its connection, it must immediately close its side of the
- connection also. Whether the user agent or the server closes the
- connection first, it is said that the <dfn id=websocket-connection-is-closed>WebSocket connection is
- closed</dfn>.</p>
+ <h6 id=client-initiated-closure><span class=secno>10.3.4.5.1 </span>Client-initiated closure</h6>
- <!-- XXX Close Handshake but NOT for FAILing or ABORTing -->
+ <p>Certain algorithms require the user agent to <dfn id=fail-the-websocket-connection>fail the
+ WebSocket connection</dfn>. To do so, the user agent must
+ <a href=#close-the-websocket-connection>close the WebSocket connection</a>, and may report the
+ problem to the user (which would be especially useful for
+ developers).</p>
+ <p>Except as indicated above or as specified by the application
+ layer (e.g. a script using the WebSocket API), user agents should
+ not close the connection.</p>
+
+ <p>User agents must not convey any failure information to scripts in
+ a way that would allow a script to distinguish the following
+ situations:</p>
+
+ <ul><li>A server whose host name could not be resolved.</li>
+
+ <li>A server to which packets could not successfully be
+ routed.</li>
+
+ <li>A server that refused the connection on the specified
+ port.</li>
+
+ <li>A server that did not complete the opening handshake
+ (e.g. because it was not a WebSocket server).</li>
+
+ <li>A WebSocket server that sent a correct opening handshake, but
+ that specified options that caused the client to drop the
+ connection (e.g. the server specified an origin that differed from
+ the script's).</li>
+
+ <li>A WebSocket server that abruptly closed the connection after
+ successfully completing the opening handshake.</li>
+
+ </ul><h6 id=server-initiated-closure><span class=secno>10.3.4.5.2 </span>Server-initiated closure</h6>
+
+ <p>Certain algorithms require or recommend that the server
+ <dfn id=abort-the-websocket-connection>abort the WebSocket connection</dfn> during the opening
+ handshake. To do so, the server must simply <a href=#close-the-websocket-connection>close the
+ WebSocket connection</a>.</p>
+
+
+ <h6 id=closure><span class=secno>10.3.4.5.3 </span>Closure</h6>
+
+ <p>To <dfn id=close-the-websocket-connection>close the WebSocket connection</dfn>, the user agent or
+ server must close the TCP connection, using whatever mechanism
+ possible (e.g. either the TCP RST or FIN mechanisms). When a user
+ agent notices that the server has closed its connection, it must
+ immediately close its side of the connection also. Whether the user
+ agent or the server closes the connection first, it is said that the
+ <dfn id=websocket-connection-is-closed>WebSocket connection is closed</dfn>. If the connection was
+ closed after the client <a href=#the-websocket-closing-handshake-has-finished title="the WebSocket closing handshake
+ has finished">finished the WebSocket closing handshake</a>, then
+ the WebSocket connection is said to have been closed <i title="">cleanly</i>.</p>
+
<p>Servers may <a href=#close-the-websocket-connection>close the WebSocket connection</a> whenever
desired. User agents should not <a href=#close-the-websocket-connection>close the WebSocket
connection</a> arbitrarily.</p>
Modified: source
===================================================================
--- source 2010-03-03 23:55:02 UTC (rev 4819)
+++ source 2010-03-04 03:17:02 UTC (rev 4820)
@@ -75232,14 +75232,15 @@
// ready state
const unsigned short <span title="dom-WebSocket-CONNECTING">CONNECTING</span> = 0;
const unsigned short <span title="dom-WebSocket-OPEN">OPEN</span> = 1;
- const unsigned short <span title="dom-WebSocket-CLOSED">CLOSED</span> = 2;
+ const unsigned short <span title="dom-WebSocket-CLOSING">CLOSING</span> = 2;
+ const unsigned short <span title="dom-WebSocket-CLOSED">CLOSED</span> = 3;
readonly attribute unsigned short <span title="dom-WebSocket-readyState">readyState</span>;
readonly attribute unsigned long <span title="dom-WebSocket-bufferedAmount">bufferedAmount</span>;
// networking
attribute <span>Function</span> <span title="handler-WebSocket-onopen">onopen</span>;
attribute <span>Function</span> <span title="handler-WebSocket-onmessage">onmessage</span>;
- attribute <span>Function</span> <span title="handler-WebSocket-onmessageerror">onmessageerror</span>;
+ attribute <span>Function</span> <span title="handler-WebSocket-onerror">onerror</span>;
attribute <span>Function</span> <span title="handler-WebSocket-onclose">onclose</span>;
boolean <span title="dom-WebSocket-send">send</span>(in DOMString data);
void <span title="dom-WebSocket-close">close</span>();
@@ -75343,8 +75344,12 @@
<dd>The <span>WebSocket connection is established</span> and communication is possible.</dd>
- <dt><dfn title="dom-WebSocket-CLOSED"><code>CLOSED</code></dfn> (numeric value 2)</dt>
+ <dt><dfn title="dom-WebSocket-CLOSING"><code>CLOSING</code></dfn> (numeric value 2)</dt>
+ <dd>The connection is going through the closing handshake.</dd>
+
+ <dt><dfn title="dom-WebSocket-CLOSED"><code>CLOSED</code></dfn> (numeric value 3)</dt>
+
<dd>The connection has been closed or could not be opened.</dd>
</dl>
@@ -75361,27 +75366,102 @@
raise an <code>INVALID_STATE_ERR</code> exception. If the <var
title="">data</var> argument has any unpaired surrogates, then it
must raise <code>SYNTAX_ERR</code>. If the connection is
- established, and the string has no unpaired surrogates, then the
- user agent must <span>send <var title="">data</var> using the
+ established, and the string has no unpaired surrogates, and <span
+ title="the WebSocket closing handshake has started">the WebSocket
+ closing handshake has not yet started</span>, then the user agent
+ must <span>send <var title="">data</var> using the
WebSocket</span>. If the data cannot be sent, e.g. because it would
need to be buffered but the buffer is full, the user agent must
<span>close the WebSocket connection</span>. The method must then
return true if the connection is still established (and the data was
- queued or sent successfully), or false if the connection is closed
- (e.g. because the user agent just had a buffer overflow and failed
- to send the data).</p>
+ queued or sent successfully), or false if the connection is closing
+ or closed (e.g. because the user agent just had a buffer overflow
+ and failed to send the data, or because <span>the WebSocket closing
+ handshake has started</span>).</p>
<p>The <dfn title="dom-WebSocket-close"><code>close()</code></dfn>
- method must <span>close the WebSocket connection</span> or
- connection attempt, if any, and change the <code
- title="dom-WebSocket-readyState">readyState</code> attribute's value
- to <code title="dom-WebSocket-CLOSED">CLOSED</code> (2). If the
- connection is already closed, it must do nothing.</p>
+ method must run the first matching steps from the following list:</p>
- <p class="note">Closing the connection immediately causes a task to
- be queued to fire a <code title="event-close">close</code> event, as
- <a href="#closeWebSocket">described below</a>.</p>
+ <dl class="switch">
+ <dt>If the <code title="dom-WebSocket-readyState">readyState</code>
+ attribute is in the <code
+ title="dom-WebSocket-CLOSING">CLOSING</code> (2) or <code
+ title="dom-WebSocket-CLOSED">CLOSED</code> (3) state</dt>
+
+ <dd>
+
+ <p>Do nothing.</p>
+
+ <p class="note">The connection is already closing or is already
+ closed. If it has not already, a <code
+ title="event-close">close</code> event will eventually fire <a
+ href="#closeWebSocket">as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>If the WebSocket connection is not yet <span title="WebSocket
+ connection is established">established</span></dt>
+
+ <dd>
+
+ <p><span>Fail the WebSocket connection</span> and set the <code
+ title="dom-WebSocket-readyState">readyState</code> attribute's
+ value to <code title="dom-WebSocket-CLOSING">CLOSING</code>
+ (2).</p>
+
+ <p class="note">The "<span>fail the WebSocket connection</span>"
+ algorithm invokes the "<span>close the WebSocket
+ connection</span>" algorithm, which then establishes that the
+ "<span>WebSocket connection is closed</span>", which fires the
+ <code title="event-close">close</code> event <a
+ href="#closeWebSocket">as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>If the WebSocket closing handshake has not yet been <span
+ title="the WebSocket closing handshake has
+ started">started</span></dt>
+
+ <dd>
+
+ <p><span>Start the WebSocket closing handshake</span> and set the
+ <code title="dom-WebSocket-readyState">readyState</code>
+ attribute's value to <code
+ title="dom-WebSocket-CLOSING">CLOSING</code> (2).</p>
+
+ <p class="note">The "<span>start the WebSocket closing
+ handshake</span>" algorithm eventually invokes the "<span>close
+ the WebSocket connection</span>" algorithm, which then establishes
+ that the "<span>WebSocket connection is closed</span>", which
+ fires the <code title="event-close">close</code> event <a
+ href="#closeWebSocket">as described below</a>.</p>
+
+ </dd>
+
+
+ <dt>Otherwise</dt>
+
+ <dd>
+
+ <p>Set the <code
+ title="dom-WebSocket-readyState">readyState</code> attribute's
+ value to <code title="dom-WebSocket-CLOSING">CLOSING</code>
+ (2).</p>
+
+ <p class="note"><span>The WebSocket closing handshake has
+ started</span>, and will eventually invokethe "<span>close the
+ WebSocket connection</span>" algorithm, which will establish that
+ the "<span>WebSocket connection is closed</span>", and thus the
+ <code title="event-close">close</code> event will fire, <a
+ href="#closeWebSocket">as described below</a>.</p>
+
+ </dd>
+
+ </dl>
+
<hr>
<p>The <dfn
@@ -75431,7 +75511,7 @@
<tbody>
<tr><td><dfn title="handler-WebSocket-onopen"><code>onopen</code></dfn> <td> <code title="event-open">open</code>
<tr><td><dfn title="handler-WebSocket-onmessage"><code>onmessage</code></dfn> <td> <code title="event-message">message</code>
- <tr><td><dfn title="handler-WebSocket-onmessageerror"><code>onmessageerror</code></dfn> <td> <code title="event-messageerror">messageerror</code>
+ <tr><td><dfn title="handler-WebSocket-onerror"><code>onerror</code></dfn> <td> <code title="event-error">error</code>
<tr><td><dfn title="handler-WebSocket-onclose"><code>onclose</code></dfn> <td> <code title="event-close">close</code>
</table>
@@ -75456,34 +75536,40 @@
title="">data</var>, and <span>queue a task</span> to check to see
if the <code title="dom-WebSocket-readyState">readyState</code>
attribute's value is <code title="dom-WebSocket-OPEN">OPEN</code>
- (1), and if so, dispatch the event at the <code>WebSocket</code>
- object.</p>
+ (1) or <code title="dom-WebSocket-CLOSING">CLOSING</code> (2), and
+ if so, dispatch the event at the <code>WebSocket</code> object.</p>
<p>When <i>a WebSocket error has been detected</i>, the user agent
- must <span>queue a task</span> to set to <var title="">data</var>,
- and <span>queue a task</span> to check to see if the <code
+ must <span>queue a task</span> to check to see if the <code
title="dom-WebSocket-readyState">readyState</code> attribute's value
- is <code title="dom-WebSocket-OPEN">OPEN</code> (1), and if so,
+ is <code title="dom-WebSocket-OPEN">OPEN</code> (1) or <code
+ title="dom-WebSocket-CLOSING">CLOSING</code> (2), and if so,
<span>fire a simple event</span> named <code
- title="event-messageerror">messageerror</code> at the <code>WebSocket</code>
+ title="event-error">error</code> at the <code>WebSocket</code>
object.</p>
- <p id="closeWebSocket">When the <i>WebSocket connection is
- closed</i>, the user agent must create an event that uses the
- <code>CloseEvent</code> interface, with the event name <code
- title="event-close">close</code>, which does not bubble, is not
- cancelable, has no default action, and whose <code
- title="dom-CloseEvent-wasClean">wasClean</code> attribute is set to
- false, and <span>queue a task</span> to first change the <code
+ <p>When <i>the WebSocket closing handshake has started</i>, the user
+ agent must <span>queue a task</span> to change the <code
title="dom-WebSocket-readyState">readyState</code> attribute's value
- to <code title="dom-WebSocket-CLOSED">CLOSED</code> (2), and then
- dispatch the event at the <code>WebSocket</code> object. (If the
+ to <code title="dom-WebSocket-CLOSING">CLOSING</code> (2). (If the
<code title="dom-WebSocket-close">close()</code> method was called,
the <code title="dom-WebSocket-readyState">readyState</code>
attribute's value will already be set to <code
- title="dom-WebSocket-CLOSED">CLOSED</code> (2) when this task
+ title="dom-WebSocket-CLOSING">CLOSING</code> (2) when this task
runs.)</p>
+ <p id="closeWebSocket">When the <i>WebSocket connection is
+ closed</i>, possibly <i title="">cleanly</i>, the user agent must
+ create an event that uses the <code>CloseEvent</code> interface,
+ with the event name <code title="event-close">close</code>, which
+ does not bubble, is not cancelable, has no default action, and whose
+ <code title="dom-CloseEvent-wasClean">wasClean</code> attribute is
+ set to true if the connection closed <i title="">cleanly</i> and
+ false otherwise; and <span>queue a task</span> to first change the
+ <code title="dom-WebSocket-readyState">readyState</code> attribute's
+ value to <code title="dom-WebSocket-CLOSED">CLOSED</code> (3), and
+ then dispatch the event at the <code>WebSocket</code> object.</p>
+
<p>The <span>task source</span> for all <span
title="concept-task">tasks</span> <span title="queue a
task">queued</span> in this section is the <dfn>WebSocket task
@@ -75669,17 +75755,20 @@
specifications to implement buffering and piecing together of
messages manually.</p>
- <!-- XXX Close Handshake -->
+ <p>To close the connection cleanly, a frame consisting of just a
+ 0xFF byte followed by a 0x00 byte is sent from one peer to ask that
+ the other peer close the connection.</p>
<p>The protocol is designed to support other frame types in
- future. Instead of the 0x00 byte, other bytes might in future be
- defined. Frames denoted by bytes that do not have the high bit set
- (0x00 to 0x7F) are treated as described above (a stream of bytes
- terminated by 0xFF). Frames denoted by bytes that have the high bit
- set (0x80 to 0xFF) have a leading length indicator, which is encoded
- as a series of 7-bit bytes stored in octets with the 8th bit being
- set for all but the last byte. The remainder of the frame is then as
- much data as was specified.</p>
+ future. Instead of the 0x00 and 0xFF bytes, other bytes might in
+ future be defined. Frames denoted by bytes that do not have the high
+ bit set (0x00 to 0x7F) are treated as a stream of bytes terminated
+ by 0xFF. Frames denoted by bytes that have the high bit set (0x80 to
+ 0xFF) have a leading length indicator, which is encoded as a series
+ of 7-bit bytes stored in octets with the 8th bit being set for all
+ but the last byte. The remainder of the frame is then as much data
+ as was specified. (The closing handshake contains no data and
+ therefore has a length byte of 0x00.)</p>
<p>This wire format for the data transfer part is described by the
following non-normative ABNF, which is given in two alternative
@@ -75693,16 +75782,16 @@
<!--START websocket-protocol-->
</p>
- <!-- XXX Close Handshake -->
<pre>; the wire protocol as allowed by this specification
frames = *frame
-frame = text-frame
-text-frame = (%x00) *( UTF8-char ) %xFF
+frame = text-frame / closing-frame
+text-frame = %x00 *( UTF8-char ) %xFF
+closing-frame = %xFF %x00
; the wire protocol including error-handling and forward-compatible parsing rules
frames = *frame
frame = text-frame / binary-frame
-text-frame = (%x00-7F) *( UTF8-char / %x80-FE ) %xFF
+text-frame = (%x00-7F) *(%x00-FE) %xFF
binary-frame = (%x80-FF) length < as many bytes as given by the length >
length = *(%x80-FF) (%x00-7F)</pre>
@@ -75712,36 +75801,38 @@
<p class="note">The above ABNF is intended for a binary octet
environment.</p>
- <!-- XXX Close Handshake -->
<p class="warning">At this time, the WebSocket protocol cannot be
used to send binary data. Using any of the frame types other than
- 0x00 is invalid.</p>
+ 0x00 and 0xFF is invalid.</p>
<hr>
- <p>The following diagrams summarise the protocol:</p>
+ <p>The following diagram summarises the protocol:</p>
<pre>Handshake
|
V
-Frame type byte <-------------------------------------.
- | | |
- | `-- (0x00 to 0x7F) --> Data... --> 0xFF -->-+
- | |
- `-- (0x80 to 0xFF) --> Length --> Data... ------->-'</pre>
+Frame type byte <--------------------------------------.
+ | | |
+ | `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
+ | |
+ `--> (0x80 to 0xFE) --> Length --> Data... ------->-'
+</pre>
- <h6>Handshake</h6>
+ <h6>Opening Handshake</h6>
+
<p><i>This section is non-normative.</i></p>
- <p>The handshake is intended to be compatible with HTTP-based
- server-side software, so that a single port can be used by both HTTP
- clients talking to that server and WebSocket clients talking to that
- server. To this end, the WebSocket client's handshake appears to
- HTTP servers to be a regular GET request with an Upgrade offer:</p>
+ <p>The opening handshake is intended to be compatible with
+ HTTP-based server-side software, so that a single port can be used
+ by both HTTP clients talking to that server and WebSocket clients
+ talking to that server. To this end, the WebSocket client's
+ handshake appears to HTTP servers to be a regular GET request with
+ an Upgrade offer:</p>
<pre>GET /resource HTTP/1.1
Upgrade: WebSocket
@@ -75891,7 +75982,33 @@
man-in-the-middle cache or proxy.</p>
+ <h6>Closing Handshake</h6>
+ <p><i>This section is non-normative.</i></p>
+
+ <p>The closing handshake is far simpler than the opening handshake.</p>
+
+ <p>Either peer can send a 0xFF frame with length 0x00 to begin the
+ closing handshake. Upon receiving a 0xFF frame, the other peer
+ sends an identical 0xFF frame in acknowledgement, if it hasn't
+ already sent one. Upon receiving <em>that</em> 0xFF frame, the first
+ peer then closes the connection, safe in the knowledge that no
+ further data is forthcoming.</p>
+
+ <p>After sending a 0xFF frame, a peer does not send any further
+ data; after receiving a 0xFF frame, a peer discards any further
+ data received.</p>
+
+ <p>It is safe for both peers to initiate this handshake
+ simultaneously.</p>
+
+ <p>The closing handshake is intended to replace the TCP closing
+ handshake (FIN/ACK), on the basis that the TCP closing handshake is
+ not always reliable end-to-end, especially in the presence of
+ man-in-the-middle proxies and other intermediaries.</p>
+
+
+
<h6>Design philosophy</h6>
<p><i>This section is non-normative.</i></p>
@@ -75907,13 +76024,11 @@
<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
- services on one port and multiple host names on one IP address; and
+ 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
- limits.
+ limits; and reimplements the closing handshake in-band.
- <!-- XXX Close Handshake -->
-
Other than that, it adds nothing. Basically it is intended
to be as close to just exposing raw TCP to script as possible
given the constraints of the Web. It's also designed in such a way
@@ -76195,7 +76310,7 @@
establish to a server.</p>
- <h6>Handshake</h6>
+ <h6>Opening Handshake</h6>
<p>When the user agent is to <dfn>establish a WebSocket
connection</dfn> to a host <var title="">host</var>, on a port <var
@@ -77138,7 +77253,7 @@
<li id="ws-cd-length"><p><i>Length</i>: Read a byte, let <var
title="">b</var> be that byte.</p></li>
- <li><p>Let <var title="">b<sub title="">v</sub></var> be
+ <li><p>Let <var title="">b<sub title="">v</sub></var> be an
integer corresponding to the low 7 bits of <var title="">b</var>
(the value you would get by <i>and</i>ing <var title="">b</var>
with 0x7F).</p></li>
@@ -77156,8 +77271,39 @@
<li><p>Discard the read bytes.</p></li>
- <li><p>Let <var title="">error</var> be true.</p></li>
+ <li>
+ <p>If the <var title="">frame type</var> is 0xFF and the <var
+ title="">length</var> was 0, then run the following
+ substeps:</p>
+
+ <ol>
+
+ <li>If <span title="the WebSocket closing handshake has
+ started">the WebSocket closing handshake has not yet
+ started</span>, then <span>start the WebSocket closing
+ handshake</span>.</li>
+
+ <li>Wait until either <span>the WebSocket closing handshake
+ has started</span> or the <span>WebSocket connection is
+ closed</span>.</li>
+
+ <li>If the <span title="WebSocket connection is
+ closed">WebSocket connection is not already closed</span>,
+ then <span>close the WebSocket connection</span>: <dfn>The
+ WebSocket closing handshake has finished</dfn>. (If the
+ connection closes before this happens, then the closing
+ handshake doesn't finish.)</li>
+
+ <li>Abort these steps. Any data on the connection after the
+ 0xFF frame is discarded.</li>
+
+ </ol>
+
+ <p>Otherwise, let <var title="">error</var> be true.</p>
+
+ </li>
+
</ol>
</dd>
@@ -77201,7 +77347,7 @@
<li>
<p>If <var title="">error</var> is true, then <dfn>a WebSocket
- error has been detected</dfn>.</p></li>
+ error has been detected</dfn>.</p>
</li>
@@ -77217,7 +77363,8 @@
<hr>
- <p>Once a <span>WebSocket connection is established</span>, the
+ <p>Once a <span>WebSocket connection is established</span>, but
+ before <span>the WebSocket closing handshake has started</span>, the
user agent must use the following steps to <dfn>send <var
title="">data</var> using the WebSocket</dfn>:</p>
@@ -77232,6 +77379,43 @@
</ol>
+ <p>Once <span>the WebSocket closing handshake has started</span>,
+ the user agent must not send any further data on the connection.</p>
+
+ <hr>
+
+ <p>Once a <span>WebSocket connection is established</span>, the user
+ agent must use the following steps to <dfn>start the WebSocket
+ closing handshake</dfn>. These steps must be run asynchronously
+ relative to whatever algorithm invoked this one.</p>
+
+ <ol>
+
+ <li><p>If <span>the WebSocket closing handshake has started</span>,
+ then abort these steps.</p></li>
+
+ <li><p>Send a 0xFF byte to the server.</p></li>
+
+ <li><p>Send a 0x00 byte to the server.</p></li>
+
+ <li><p><dfn>The WebSocket closing handshake has started</dfn>.</p></li>
+
+ <li><p>Wait a user-agent-determined length of time, or until the
+ <span>WebSocket connection is closed</span>.</p>
+
+ <li>If the <span title="WebSocket connection is closed">WebSocket
+ connection is not already closed</span>, then <span>close the
+ WebSocket connection</span>. (If this happens, then the closing
+ handshake doesn't finish.)</li>
+
+ </ol>
+
+ <p class="note">The closing handshake <span title="the WebSocket
+ closing handshake has finished">finishes</span> once the server
+ returns the 0xFF packet, as described above.</p>
+
+ <hr>
+
<p>If at any point there is a fatal problem with sending data to the
server, the user agent must <span>fail the WebSocket
connection</span>.</p>
@@ -77242,22 +77426,8 @@
data. -->
- <h6>Failing the connection</h6>
+ <h6>Handling errors in UTF-8 from the server</h6>
- <p>To <dfn>fail the WebSocket connection</dfn>, the user agent must
- <span>close the WebSocket connection</span>, and may report the
- problem to the user (which would be especially useful for
- developers). However, user agents must not convey the failure
- information to the script that attempted the connection in a way
- distinguishable from the WebSocket being closed normally.</p>
-
- <p>Except as indicated above or as specified by the application
- layer (e.g. a script using the WebSocket API), user agents should
- not close the connection.</p>
-
-
- <h6>Handling errors in UTF-8</h6>
-
<p>When a client is to interpret a byte stream as UTF-8 but finds
that the byte stream is not in fact a valid UTF-8 stream, then any
bytes or sequences of bytes that are not valid UTF-8 sequences must
@@ -77270,12 +77440,12 @@
<p><i>This section only applies to servers.</i></p>
- <h6>Reading the client's handshake</h6>
+ <h6>Reading the client's opening handshake</h6>
<p>When a client starts a WebSocket connection, it sends its part of
- the handshake. The server must parse at least part of this handshake
- in order to obtain the necessary information to generate the server
- part of the handshake.</p>
+ the opening handshake. The server must parse at least part of this
+ handshake in order to obtain the necessary information to generate
+ the server part of the handshake.</p>
<p>The client handshake consists of the following parts. If the
server, while reading the handshake, finds that the client did not
@@ -77477,7 +77647,7 @@
doesn't support.</p>
- <h6>Sending the server's handshake</h6>
+ <h6>Sending the server's opening handshake</h6>
<p>When a client establishes a WebSocket connection to a server, the
server must run the following steps.</p>
@@ -77834,7 +78004,7 @@
<li id="ws-sd-length"><p><i>Length</i>: Read a byte, let <var
title="">b</var> be that byte.</p></li>
- <li><p>Let <var title="">b<sub title="">v</sub></var> be
+ <li><p>Let <var title="">b<sub title="">v</sub></var> be an
integer corresponding to the low 7 bits of <var title="">b</var>
(the value you would get by <i>and</i>ing <var title="">b</var>
with 0x7F).</p></li>
@@ -77852,6 +78022,11 @@
<li><p>Discard the read bytes.</p></li>
+ <li><p>If <var title="">type</var> is 0xFF and <var
+ title="">length</var> is 0, then set the <var title="">client
+ terminated</var> flag and abort these steps. All further data
+ sent by the client should be discarded.</p></li>
+
</ol>
</li>
@@ -77879,16 +78054,32 @@
</ol>
+ <hr>
- <h6>Aborting the connection</h6>
+ <p>At any time, the server may decide to terminate the WebSocket
+ connection by running through the following steps:</p>
- <p>To <dfn>abort the WebSocket connection</dfn> during the
- handshake, the server must <span>close the WebSocket
- connection</span>.</p>
+ <ol>
+ <li><p>Send a 0xFF byte and a 0x00 byte to the client to indicate
+ the start of the closing handshake.</p></li>
- <h6>Handling errors in UTF-8</h6>
+ <li><p>Wait until the <var title="">client terminated</var> flag
+ has been set, or until a server-defined timeout expires.</p></li>
+ <li><p><span>Close the WebSocket connection</span>.</p></li>
+
+ </ol>
+
+ <p>Once these steps have started, the server must not send any
+ further data to the server. The 0xFF 0x00 bytes indicate the end of
+ the server's data, and further bytes will be discarded by the
+ client.</p>
+
+
+
+ <h6>Handling errors in UTF-8 from the client</h6>
+
<p>When a server is to interpret a byte stream as UTF-8 but finds
that the byte stream is not in fact a valid UTF-8 stream, behaviour
is undefined. A server could close the connection, convert invalid
@@ -77901,16 +78092,68 @@
<h5>Closing the connection</h5>
- <p>To <dfn>close the WebSocket connection</dfn>, either the user
- agent or the server closes the TCP connection. There is no
- closing handshake. When a user agent notices that the server has
- closed its connection, it must immediately close its side of the
- connection also. Whether the user agent or the server closes the
- connection first, it is said that the <dfn>WebSocket connection is
- closed</dfn>.</p>
+ <h6>Client-initiated closure</h6>
- <!-- XXX Close Handshake but NOT for FAILing or ABORTing -->
+ <p>Certain algorithms require the user agent to <dfn>fail the
+ WebSocket connection</dfn>. To do so, the user agent must
+ <span>close the WebSocket connection</span>, and may report the
+ problem to the user (which would be especially useful for
+ developers).</p>
+ <p>Except as indicated above or as specified by the application
+ layer (e.g. a script using the WebSocket API), user agents should
+ not close the connection.</p>
+
+ <p>User agents must not convey any failure information to scripts in
+ a way that would allow a script to distinguish the following
+ situations:</p>
+
+ <ul>
+
+ <li>A server whose host name could not be resolved.</li>
+
+ <li>A server to which packets could not successfully be
+ routed.</li>
+
+ <li>A server that refused the connection on the specified
+ port.</li>
+
+ <li>A server that did not complete the opening handshake
+ (e.g. because it was not a WebSocket server).</li>
+
+ <li>A WebSocket server that sent a correct opening handshake, but
+ that specified options that caused the client to drop the
+ connection (e.g. the server specified an origin that differed from
+ the script's).</li>
+
+ <li>A WebSocket server that abruptly closed the connection after
+ successfully completing the opening handshake.</li>
+
+ </ul>
+
+
+ <h6>Server-initiated closure</h6>
+
+ <p>Certain algorithms require or recommend that the server
+ <dfn>abort the WebSocket connection</dfn> during the opening
+ handshake. To do so, the server must simply <span>close the
+ WebSocket connection</span>.</p>
+
+
+ <h6>Closure</h6>
+
+ <p>To <dfn>close the WebSocket connection</dfn>, the user agent or
+ server must close the TCP connection, using whatever mechanism
+ possible (e.g. either the TCP RST or FIN mechanisms). When a user
+ agent notices that the server has closed its connection, it must
+ immediately close its side of the connection also. Whether the user
+ agent or the server closes the connection first, it is said that the
+ <dfn>WebSocket connection is closed</dfn>. If the connection was
+ closed after the client <span title="the WebSocket closing handshake
+ has finished">finished the WebSocket closing handshake</span>, then
+ the WebSocket connection is said to have been closed <i
+ title="">cleanly</i>.</p>
+
<p>Servers may <span>close the WebSocket connection</span> whenever
desired. User agents should not <span>close the WebSocket
connection</span> arbitrarily.</p>
More information about the Commit-Watchers
mailing list