[html5] r5241 - [giowt] (1) Change the framing for WebSockets to always be 64 bit fixed length f [...]
whatwg at whatwg.org
whatwg at whatwg.org
Thu Aug 5 17:38:11 PDT 2010
Author: ianh
Date: 2010-08-05 17:38:10 -0700 (Thu, 05 Aug 2010)
New Revision: 5241
Modified:
complete.html
source
Log:
[giowt] (1) Change the framing for WebSockets to always be 64 bit fixed length frames rather than variable width and/or sentinel-based.
Modified: complete.html
===================================================================
--- complete.html 2010-08-04 23:07:55 UTC (rev 5240)
+++ complete.html 2010-08-06 00:38:10 UTC (rev 5241)
@@ -209,7 +209,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 — 4 August 2010</h2>
+ <h2 class="no-num no-toc">Draft Standard — 6 August 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>-->
@@ -72835,54 +72835,43 @@
independently from the other, send data at will.</p>
<p>Data is sent in the form of UTF-8 text. Each frame of data starts
- with a 0x00 byte and ends with a 0xFF byte, with the UTF-8 text in
- between.</p>
+ with a 0xFF byte identifying the frame type, followed by the number
+ of bytes in the data expressed as a big-endian 64 bit integer,
+ followed by the UTF-8 data.</p>
+ <p class=note>The length is the number of UTF-8 <em>bytes</em>,
+ and not the number of characters. For example, the string
+ "H̶e̸͜҉ll̡o̵̶͘"
+ has 13 Unicode code points, but is 21 bytes long.</p><!-- Zalgo -->
+
<p>The WebSocket protocol uses this framing so that specifications
that use the WebSocket protocol can expose such connections using
an event-based mechanism instead of requiring users of those
specifications to implement buffering and piecing together of
messages manually.</p>
- <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>To close the connection cleanly, a frame consisting of just nine
+ 0x00 bytes in a row is sent from one peer to ask that the other peer
+ close the connection. That corresponds to a frame type of 0x00
+ followed by a length of zero, indicating an empty frame.</p>
- <p>The protocol is designed to support other frame types in
- 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>In addition to the 0x00 and 0xFF frame types, other types might
+ in future be defined, to support binary data, fragmentation,
+ compression, multiplexing, or other features.</p>
- <p>This wire format for the data transfer part is described by the
- following non-normative ABNF, which is given in two alternative
- forms: the first describing the wire format as allowed by this
- specification, and the second describing how an arbitrary bytestream
- would be parsed.
+ <p>The wire format for the data transfer part is described by the
+ <code title="">frames</code> production of the following
+ non-normative ABNF.
<a href=#refsABNF>[ABNF]</a>
</p>
- <pre>; the wire protocol as allowed by this specification
-frames = *frame
-frame = text-frame / closing-frame
-text-frame = %x00 *( UTF8-char ) %xFF
-closing-frame = %xFF %x00
+ <pre>frames = *frame
+frame = frame-type frame-length data
+frame-type = OCTET
+frame-length = 8OCTET
+data = *OCTET ; count must match the given length</pre>
-; the wire protocol including error-handling and forward-compatible parsing rules
-frames = *frame
-frame = text-frame / binary-frame
-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>
-
- <p>The UTF8-char rule is defined in the UTF-8 specification. <a href=#refsRFC3629>[RFC3629]</a></p>
-
<p class=note>The above ABNF is intended for a binary octet
environment.</p>
@@ -72891,21 +72880,8 @@
0x00 and 0xFF is invalid. All other frame types are reserved for
future use by future versions of this protocol.</p>
- <hr><p>The following diagram summarises the protocol:</p>
- <pre>Handshake
- |
- V
-Frame type byte <--------------------------------------.
- | | |
- | `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
- | |
- `--> (0x80 to 0xFE) --> Length --> Data... ------->-'
-</pre>
-
-
-
<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>
@@ -73170,8 +73146,9 @@
HTTP servers as an Upgrade request.</p>
<p>Based on the expert recommendation of the IANA<!-- [IANA #257455]
- -->, the WebSocket protocol by default uses port 80 for regular WebSocket connections and port 443 for WebSocket connections tunneled
- over TLS.</p>
+ -->, the WebSocket protocol by default uses port 80 for regular
+ WebSocket connections and port 443 for WebSocket connections
+ tunneled over TLS.</p>
@@ -73236,8 +73213,11 @@
but carefully designing the actual subprotocol to support this kind
of extensibility.</p>
+ <p>Subprotocol names are sequences of one or more characters in the
+ range U+0021 to U+007F.</p>
+
<h5 id=terminology-1><span class=secno>10.3.4.2 </span>Terminology</h5>
@@ -73247,6 +73227,7 @@
packets.</p>
+
<h5 id=websocket-urls><span class=secno>10.3.4.3 </span>WebSocket URLs</h5>
<h6 id=parsing-websocket-urls><span class=secno>10.3.4.3.1 </span>Parsing WebSocket URLs</h6>
@@ -73736,9 +73717,9 @@
<li>
- <p>Let <var title="">key3</var> be a string consisting of eight
- random bytes (or equivalently, a random 64 bit integer encoded in
- big-endian order).</p>
+ <p>Let <var title="">key<sub>3</sub></var> be a string consisting
+ of eight random bytes (or equivalently, a random 64 bit integer
+ encoded in big-endian order).</p>
<p class=example>For example, 0x47 0x30 0x22 0x2D 0x5A 0x3F 0x47
0x58.</p>
@@ -73747,7 +73728,7 @@
<li>
- <p>Send <var title="">key3</var> to the server.</p>
+ <p>Send <var title="">key<sub>3</sub></var> to the server.</p>
</li>
@@ -74026,6 +74007,10 @@
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>If the the value contains any characters outside the range
+ U+0021 to U+007F, 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>
@@ -74274,125 +74259,101 @@
<li>
- <p>Let <var title="">error</var> be false.</p>
+ <p>Try to read eight more bytes from the server. Let <var title="">frame length</var> be the result of interpreting those
+ eight bytes as a big-endian 64 bit integer.</p>
</li>
<li>
- <p>Handle the <var title="">frame type</var> byte as follows:</p>
+ <p>Try to read <var title="">frame length</var> bytes from the
+ server. Let <var title="">raw data</var> be those bytes.</p>
- <dl><dt>If the high-order bit of the <var title="">frame type</var>
- byte is set (i.e. if <var title="">frame type</var> <i title="">and</i>ed with 0x80 returns 0x80)</dt>
+ </li>
- <dd>
+ <li>
- <p>Run these steps:</p>
+ <p>Let <var title="">error</var> be false.</p>
- <ol><li><p>Let <var title="">length</var> be zero.</li>
+ </li>
- <li id=ws-cd-length><p><i>Length</i>: Read a byte, let <var title="">b</var> be that byte.</li>
+ <li>
- <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>
+ <p>If <var title="">frame length</var> is greater than the length
+ of data the user agent is able to deal with at this time, set <var title="">error</var> to true.</p>
- <li><p>Multiply <var title="">length</var> by 128, add <var title="">b<sub title="">v</sub></var> to that result, and store
- the final result in <var title="">length</var>.</li>
+ <p>User agents should ensure they are always able to deal with
+ lengths up to at least 65536 bytes.</p>
- <li><p>If the high-order bit of <var title="">b</var> is set
- (i.e. if <var title="">b</var> <i title="">and</i>ed with 0x80
- returns 0x80), then return to the step above labeled <a href=#ws-cd-length><i>length</i></a>.</li>
+ <p class=note>The minimum expected supported length will likely
+ be increased in future revisions of this protocol.</p>
- <li>
+ </li>
- <p>Read <var title="">length</var> bytes.</p>
+ <li>
- <p class=warning>It is possible for a server to (innocently
- or maliciously) send frames with lengths greater than
- 2<sup>31</sup> or 2<sup>32</sup> bytes, overflowing a signed
- or unsigned 32-bit integer. User agents may therefore impose
- implementation-specific limits on the lengths of invalid
- frames that they will skip; even supporting frames 2GB in
- length is considered, at the time of writing, as going well
- above and beyond the call of duty.</p>
+ <p>If <var title="">error</var> is still false, handle the <var title="">frame type</var> byte as follows:</p>
- </li>
+ <dl><dt>If the <var title="">frame type</var> byte is 0x00</dt>
- <li><p>Discard the read bytes.</li>
+ <dd>
- <li>
+ <p>If <var title="">frame length</var> is not zero, then set
+ <var title="">error</var> to true. Otherwise, run these
+ steps:</p>
- <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>
- <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>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>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
+ 0x00 frame is discarded.</li>
- <li>Abort these steps. Any data on the connection after the
- 0xFF frame is discarded.</li>
-
- </ol></li>
-
- <li>
-
- <p>Otherwise, if the <var title="">frame type</var> is not
- 0xFF or if the <var title="">length</var> was not 0, let <var title="">error</var> be true.</p>
-
- </li>
-
</ol></dd>
- <dt>If the high-order bit of the <var title="">frame type</var>
- byte is <em>not</em> set (i.e. if <var title="">frame type</var>
- <i title="">and</i>ed with 0x80 returns 0x00)</dt>
+ <dt>If the <var title="">frame type</var> byte is 0xFF</dt>
<dd>
- <p>Run these steps:</p>
+ <p><dfn id=a-websocket-message-has-been-received>A WebSocket message has been received</dfn> with
+ obtained by interpreting <var title="">raw data</var> as a UTF-8
+ string.</p>
- <ol><li><p>Let <var title="">raw data</var> be an empty byte array.</li>
+ </dd>
- <li id=ws-cd-data><p><i>Data</i>: Read a byte, let <var title="">b</var> be that byte.</p>
+ <dt>Otherwise (the <var title="">frame type</var> byte is in the range 0x01 to 0xFE)</dt>
- <li><p>If <var title="">b</var> is not 0xFF, then append <var title="">b</var> to <var title="">raw data</var> and return to
- the previous step (labeled <a href=#ws-cd-data><i>data</i></a>).</li>
+ <dd>
- <li><p>Interpret <var title="">raw data</var> as a UTF-8
- string, and store that string in <var title="">data</var>.</p>
+ <p>Set <var title="">error</var> to true.</p>
- <li><p>If <var title="">frame type</var> is 0x00, then <dfn id=a-websocket-message-has-been-received>a
- WebSocket message has been received</dfn> with text <var title="">data</var>. Otherwise, discard the data and let <var title="">error</var> be true.</li>
+ </dd>
- </ol></dd>
-
</dl></li>
<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>.</p>
+ error has been detected</dfn>. Discard <var title="">raw
+ data</var>.</p>
</li>
<li><p>Return to the first step to read the next byte.</li>
- </ol><p>If the user agent is faced with content that is too large to be
- handled appropriately, runs out of resources for buffering incoming
+ </ol><p>If the user agent runs out of resources for buffering incoming
data, or hits an artificial resource limit intended to avoid
resource starvation, then it must <a href=#fail-the-websocket-connection>fail the WebSocket
connection</a>.</p>
@@ -74401,13 +74362,16 @@
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>
+ <ol><li><p>Encode the text in <var title="">data</var> using UTF-8 to
+ obtain the byte stream <var title="">bytes</var>.</li>
- <li><p>Encode <var title="">data</var> using UTF-8 and send the
- resulting byte stream to the server.</li>
-
<li><p>Send a 0xFF byte to the server.</li>
+ <li><p>Send the number of bytes in <var title="">bytes</var>, as
+ a 64 bit big-endian integer, to the server.</li>
+
+ <li><p>Send <var title="">raw data</var> to the server.</li>
+
</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>
@@ -74419,10 +74383,8 @@
<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 nine 0x00 bytes 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
@@ -74435,19 +74397,14 @@
</ol><p class=note>If the user agent initiates it, 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 frame, as
+ finished">finishes</a> once the server returns the 0x00 frame, 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>
- <!-- v2: People often request the ability to send binary blobs over
- this API; we should also look into allowing name/value pairs,
- arrays, and numbers using send() instead of just strings and binary
- data. -->
-
<h6 id=handling-errors-in-utf-8-from-the-server><span class=secno>10.3.4.4.3 </span>Handling errors in UTF-8 from the server</h6>
<p>When a client is to interpret a byte stream as UTF-8 but finds
@@ -74973,115 +74930,99 @@
<h6 id=ws-sd-framing><span class=secno>10.3.4.5.3 </span>Data framing</h6>
<p>The server must run through the following steps to process the
- bytes sent by the client. If at any point during these steps a read
+ bytes sent by the client. If at any point during these steps a read
is attempted but fails because the <a href=#websocket-connection-is-closed>WebSocket connection is
closed</a>, then abort.</p>
- <ol><li id=ws-sd-frame><p><i title="">Frame</i>: Read a byte from the
- client. Let <var title="">type</var> be that byte.</li>
+ <ol><li>
- <li>
+ <p>Try to read a byte from the client. Let <var title="">frame
+ type</var> be that byte.</p>
- <p>If the most significant bit of <var title="">type</var> is not
- set, then run the following steps:</p>
+ </li>
- <ol><li><p>If <var title="">type</var> is not a 0x00 byte, then the
- server may abort these steps and either immediately disconnect
- from the client or set the <var title="">client terminated</var>
- flag.</li>
+ <li>
- <li><p>Let <var title="">raw data</var> be an empty byte
- array.</li>
+ <p>Try to read eight more bytes from the client. Let <var title="">frame length</var> be the result of interpreting those
+ eight bytes as a big-endian 64 bit integer.</p>
- <li id=ws-sd-data><p><i>Data</i>: Read a byte, let <var title="">b</var> be that byte.</li>
+ </li>
- <li><p>If <var title="">b</var> is not 0xFF, then append <var title="">b</var> to <var title="">raw data</var> and return to
- the previous step (labeled <a href=#ws-sd-data><i>data</i></a>).</li>
+ <li>
- <li><p>If <var title="">type</var> was 0x00, interpret <var title="">raw data</var> as a UTF-8 string, and apply whatever
- server-specific processing is to occur for the resulting string
- (the message from the client).</p>
+ <p>Try to read <var title="">frame length</var> bytes from the
+ client. Let <var title="">raw data</var> be those bytes.</p>
- </ol><p>Otherwise, the most significant bit of <var title="">type</var>
- is set. Run the following steps.</p>
+ </li>
- <ol><li><p>If <var title="">type</var> is not a 0xFF byte, then the
- server may abort these steps and either immediately disconnect
- from the client or set the <var title="">client terminated</var>
- flag.</li>
+ <li>
- <li><p>Let <var title="">length</var> be zero.</li>
+ <p>If <var title="">frame length</var> is greater than the length
+ of data the server is able to deal with at this time, the server
+ may abort these steps and either immediately disconnect from the
+ client or set the <var title="">client terminated</var>
+ flag. Alternatively, the server may just discard this frame and
+ jump back to the first step.</p>
- <li id=ws-sd-length><p><i>Length</i>: Read a byte, let <var title="">b</var> be that byte.</li>
+ </li>
- <li>
+ <li>
- <p>If <var title="">b</var> is not a 0x00 byte, then run these
- substeps:</p>
+ <p>Handle the <var title="">frame type</var> byte as follows:</p>
- <ol><li><p>The server may abort these steps and either immediately
- disconnect from the client or set the <var title="">client
- terminated</var> flag.</li>
+ <dl><dt>If the <var title="">frame type</var> byte is 0x00 and the <var title="">frame length</var> is 0</dt>
- <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>
+ <dd>
- <li><p>Multiply <var title="">length</var> by 128, add <var title="">b<sub title="">v</sub></var> to that result, and store
- the final result in <var title="">length</var>.</li>
+ <p>Set the <var title="">client terminated</var> flag and abort
+ these steps. All further data sent by the client should be
+ discarded.</p>
- <li><p>If the high-order bit of <var title="">b</var> is set
- (i.e. if <var title="">b</var> <i title="">and</i>ed with 0x80
- returns 0x80), then return to the step above labeled <a href=#ws-sd-length><i>length</i></a>.</li>
+ </dd>
- <li>
+ <dt>If the <var title="">frame type</var> byte is 0xFF</dt>
- <p>Read <var title="">length</var> bytes.</p>
+ <dd>
- <p class=warning>It is possible for a malicious client to send
- frames with lengths greater than 2<sup>31</sup> or
- 2<sup>32</sup> bytes, overflowing a signed or unsigned 32-bit
- integer. Servers may therefore impose implementation-specific
- limits on the lengths of invalid frames that they will skip, if
- they support skipping such frames at all. If a server cannot
- correctly skip past a long frame, then the server must abort
- these steps (discarding all future data), and should either
- immediately disconnect from the client or set the <var title="">client terminated</var> flag.</p>
+ <p>Interpret <var title="">raw data</var> as a UTF-8 string, and
+ apply whatever server-specific processing is to occur for the
+ resulting string (the message from the client).</p>
- </li>
+ </dd>
- <li><p>Discard the read bytes.</li>
+ <dt>Otherwise</dt>
- </ol></li>
+ <dd>
- <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>
+ <p>The server may abort these steps and either immediately
+ disconnect from the client or set the <var title="">client
+ terminated</var> flag.</p>
- </ol></li>
+ </dd>
- <li><p>Return to the step labeled <a href=#ws-sd-frame><i>frame</i></a>.</li>
+ </dl></li>
+ <li><p>Return to the first step to read the next byte.</li>
+
</ol><hr><p>The server must run through the following steps to send strings
to the client:</p>
- <ol><li><p>Send a 0x00 byte to the client to indicate the start of a
- string.</li>
+ <ol><li><p>Encode the text using UTF-8 to obtain the byte stream <var title="">raw data</var>.</li>
- <li><p>Encode <var title="">data</var> using UTF-8 and send the
- resulting byte stream to the client.</li>
+ <li><p>Send a 0xFF byte to the client.</li>
- <li><p>Send a 0xFF byte to the client to indicate the end of the
- message.</li>
+ <li><p>Send the number of bytes in <var title="">raw data</var>, as
+ a 64 bit big-endian integer, to the client.</li>
+ <li><p>Send <var title="">raw data</var> to the client.</li>
+
</ol><hr><p>At any time, the server may decide to terminate the WebSocket
connection by running through the following steps. These steps
should be run when the <var title="">client terminated</var> flag is
set, if they aren't already running.</p>
- <ol><li><p>Send a 0xFF byte and a 0x00 byte to the client to indicate
- the start of the closing handshake.</li>
+ <ol><li><p>Send nine 0x00 bytes 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>
@@ -75089,12 +75030,11 @@
<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 client. The 0xFF 0x00 bytes indicate the end of
+ further data to the client. The nine 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.5.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
Modified: source
===================================================================
--- source 2010-08-04 23:07:55 UTC (rev 5240)
+++ source 2010-08-06 00:38:10 UTC (rev 5241)
@@ -81951,35 +81951,33 @@
independently from the other, send data at will.</p>
<p>Data is sent in the form of UTF-8 text. Each frame of data starts
- with a 0x00 byte and ends with a 0xFF byte, with the UTF-8 text in
- between.</p>
+ with a 0xFF byte identifying the frame type, followed by the number
+ of bytes in the data expressed as a big-endian 64 bit integer,
+ followed by the UTF-8 data.</p>
+ <p class="note">The length is the number of UTF-8 <em>bytes</em>,
+ and not the number of characters. For example, the string
+ "H̶e̸͜҉ll̡o̵̶͘"
+ has 13 Unicode code points, but is 21 bytes long.</p><!-- Zalgo -->
+
<p>The WebSocket protocol uses this framing so that specifications
that use the WebSocket protocol can expose such connections using
an event-based mechanism instead of requiring users of those
specifications to implement buffering and piecing together of
messages manually.</p>
- <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>To close the connection cleanly, a frame consisting of just nine
+ 0x00 bytes in a row is sent from one peer to ask that the other peer
+ close the connection. That corresponds to a frame type of 0x00
+ followed by a length of zero, indicating an empty frame.</p>
- <p>The protocol is designed to support other frame types in
- 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>In addition to the 0x00 and 0xFF frame types, other types might
+ in future be defined, to support binary data, fragmentation,
+ compression, multiplexing, or other features.</p>
- <p>This wire format for the data transfer part is described by the
- following non-normative ABNF, which is given in two alternative
- forms: the first describing the wire format as allowed by this
- specification, and the second describing how an arbitrary bytestream
- would be parsed.
+ <p>The wire format for the data transfer part is described by the
+ <code title="">frames</code> production of the following
+ non-normative ABNF.
<!--END complete--><!--END epub-->
<a href="#refsRFC5234">[RFC5234]</a>
<!--START complete--><!--START epub--><!--END websocket-protocol-->
@@ -81987,22 +81985,12 @@
<!--START websocket-protocol-->
</p>
- <pre>; the wire protocol as allowed by this specification
-frames = *frame
-frame = text-frame / closing-frame
-text-frame = %x00 *( UTF8-char ) %xFF
-closing-frame = %xFF %x00
+ <pre>frames = *frame
+frame = frame-type frame-length data
+frame-type = OCTET
+frame-length = 8OCTET
+data = *OCTET ; count must match the given length</pre>
-; the wire protocol including error-handling and forward-compatible parsing rules
-frames = *frame
-frame = text-frame / binary-frame
-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>
-
- <p>The UTF8-char rule is defined in the UTF-8 specification. <a
- href="#refsRFC3629">[RFC3629]</a></p>
-
<p class="note">The above ABNF is intended for a binary octet
environment.</p>
@@ -82011,23 +81999,8 @@
0x00 and 0xFF is invalid. All other frame types are reserved for
future use by future versions of this protocol.</p>
- <hr>
- <p>The following diagram summarises the protocol:</p>
- <pre>Handshake
- |
- V
-Frame type byte <--------------------------------------.
- | | |
- | `--> (0x00 to 0x7F) --> Data... --> 0xFF -->-+
- | |
- `--> (0x80 to 0xFE) --> Length --> Data... ------->-'
-
-</pre>
-
-
-
<h6>Opening handshake</h6>
<p><i>This section is non-normative.</i></p>
@@ -82302,8 +82275,9 @@
HTTP servers as an Upgrade request.</p>
<p>Based on the expert recommendation of the IANA<!-- [IANA #257455]
- -->, the WebSocket protocol by default uses port 80 for regular WebSocket connections and port 443 for WebSocket connections tunneled
- over TLS.</p>
+ -->, the WebSocket protocol by default uses port 80 for regular
+ WebSocket connections and port 443 for WebSocket connections
+ tunneled over TLS.</p>
@@ -82369,7 +82343,10 @@
but carefully designing the actual subprotocol to support this kind
of extensibility.</p>
+ <p>Subprotocol names are sequences of one or more characters in the
+ range U+0021 to U+007F.</p>
+
<!--END complete--><!--END epub-->
<!--BOILERPLATE middle-ietf-conformance-->
<!--START complete--><!--START epub-->
@@ -82403,6 +82380,7 @@
packets.</p>
+
<h5>WebSocket URLs</h5>
<h6>Parsing WebSocket URLs</h6>
@@ -82967,9 +82945,9 @@
<li>
- <p>Let <var title="">key3</var> be a string consisting of eight
- random bytes (or equivalently, a random 64 bit integer encoded in
- big-endian order).</p>
+ <p>Let <var title="">key<sub>3</sub></var> be a string consisting
+ of eight random bytes (or equivalently, a random 64 bit integer
+ encoded in big-endian order).</p>
<p class="example">For example, 0x47 0x30 0x22 0x2D 0x5A 0x3F 0x47
0x58.</p>
@@ -82978,7 +82956,7 @@
<li>
- <p>Send <var title="">key3</var> to the server.</p>
+ <p>Send <var title="">key<sub>3</sub></var> to the server.</p>
</li>
@@ -83294,6 +83272,10 @@
title="">protocols</var> list, then <span>fail the WebSocket
connection</span> and abort these steps.</p>
+ <p>If the the value contains any characters outside the range
+ U+0021 to U+007F, then <span>fail the WebSocket
+ connection</span> and abort these steps.</p>
+
<p>Otherwise, let the <dfn>selected WebSocket subprotocol</dfn>
be the entry's value.</p>
@@ -83574,135 +83556,95 @@
<li>
- <p>Let <var title="">error</var> be false.</p>
+ <p>Try to read eight more bytes from the server. Let <var
+ title="">frame length</var> be the result of interpreting those
+ eight bytes as a big-endian 64 bit integer.</p>
</li>
<li>
- <p>Handle the <var title="">frame type</var> byte as follows:</p>
+ <p>Try to read <var title="">frame length</var> bytes from the
+ server. Let <var title="">raw data</var> be those bytes.</p>
- <dl>
+ </li>
- <dt>If the high-order bit of the <var title="">frame type</var>
- byte is set (i.e. if <var title="">frame type</var> <i
- title="">and</i>ed with 0x80 returns 0x80)</dt>
+ <li>
- <dd>
+ <p>Let <var title="">error</var> be false.</p>
- <p>Run these steps:</p>
+ </li>
- <ol>
+ <li>
- <li><p>Let <var title="">length</var> be zero.</p></li>
+ <p>If <var title="">frame length</var> is greater than the length
+ of data the user agent is able to deal with at this time, set <var
+ title="">error</var> to true.</p>
- <li id="ws-cd-length"><p><i>Length</i>: Read a byte, let <var
- title="">b</var> be that byte.</p></li>
+ <p>User agents should ensure they are always able to deal with
+ lengths up to at least 65536 bytes.</p>
- <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>
+ <p class="note">The minimum expected supported length will likely
+ be increased in future revisions of this protocol.</p>
- <li><p>Multiply <var title="">length</var> by 128, add <var
- title="">b<sub title="">v</sub></var> to that result, and store
- the final result in <var title="">length</var>.</p></li>
+ </li>
- <li><p>If the high-order bit of <var title="">b</var> is set
- (i.e. if <var title="">b</var> <i title="">and</i>ed with 0x80
- returns 0x80), then return to the step above labeled <a
- href="#ws-cd-length"><i>length</i></a>.</p></li>
+ <li>
- <li>
+ <p>If <var title="">error</var> is still false, handle the <var
+ title="">frame type</var> byte as follows:</p>
- <p>Read <var title="">length</var> bytes.</p>
+ <dl>
- <p class="warning">It is possible for a server to (innocently
- or maliciously) send frames with lengths greater than
- 2<sup>31</sup> or 2<sup>32</sup> bytes, overflowing a signed
- or unsigned 32-bit integer. User agents may therefore impose
- implementation-specific limits on the lengths of invalid
- frames that they will skip; even supporting frames 2GB in
- length is considered, at the time of writing, as going well
- above and beyond the call of duty.</p>
+ <dt>If the <var title="">frame type</var> byte is 0x00</dt>
- </li>
+ <dd>
- <li><p>Discard the read bytes.</p></li>
+ <p>If <var title="">frame length</var> is not zero, then set
+ <var title="">error</var> to true. Otherwise, run these
+ steps:</p>
- <li>
+ <ol>
- <p>If the <var title="">frame type</var> is 0xFF and the <var
- title="">length</var> was 0, then run the following
- substeps:</p>
+ <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>
- <ol>
+ <li>Wait until either <span>the WebSocket closing handshake
+ has started</span> or the <span>WebSocket connection is
+ closed</span>.</li>
- <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>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>Wait until either <span>the WebSocket closing handshake
- has started</span> or the <span>WebSocket connection is
- closed</span>.</li>
+ <li>Abort these steps. Any data on the connection after the
+ 0x00 frame is discarded.</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>
-
- </li>
-
- <li>
-
- <p>Otherwise, if the <var title="">frame type</var> is not
- 0xFF or if the <var title="">length</var> was not 0, let <var
- title="">error</var> be true.</p>
-
- </li>
-
</ol>
</dd>
- <dt>If the high-order bit of the <var title="">frame type</var>
- byte is <em>not</em> set (i.e. if <var title="">frame type</var>
- <i title="">and</i>ed with 0x80 returns 0x00)</dt>
+ <dt>If the <var title="">frame type</var> byte is 0xFF</dt>
<dd>
- <p>Run these steps:</p>
+ <p><dfn>A WebSocket message has been received</dfn> with
+ obtained by interpreting <var title="">raw data</var> as a UTF-8
+ string.</p>
- <ol>
+ </dd>
- <li><p>Let <var title="">raw data</var> be an empty byte array.</p></li>
+ <dt>Otherwise (the <var title="">frame type</var> byte is in the range 0x01 to 0xFE)</dt>
- <li id="ws-cd-data"><p><i>Data</i>: Read a byte, let <var
- title="">b</var> be that byte.</p>
+ <dd>
- <li><p>If <var title="">b</var> is not 0xFF, then append <var
- title="">b</var> to <var title="">raw data</var> and return to
- the previous step (labeled <a
- href="#ws-cd-data"><i>data</i></a>).</p></li>
+ <p>Set <var title="">error</var> to true.</p>
- <li><p>Interpret <var title="">raw data</var> as a UTF-8
- string, and store that string in <var title="">data</var>.</p>
-
- <li><p>If <var title="">frame type</var> is 0x00, then <dfn>a
- WebSocket message has been received</dfn> with text <var
- title="">data</var>. Otherwise, discard the data and let <var
- title="">error</var> be true.</p></li>
-
- </ol>
-
</dd>
</dl>
@@ -83712,7 +83654,8 @@
<li>
<p>If <var title="">error</var> is true, then <dfn>a WebSocket
- error has been detected</dfn>.</p>
+ error has been detected</dfn>. Discard <var title="">raw
+ data</var>.</p>
</li>
@@ -83720,8 +83663,7 @@
</ol>
- <p>If the user agent is faced with content that is too large to be
- handled appropriately, runs out of resources for buffering incoming
+ <p>If the user agent runs out of resources for buffering incoming
data, or hits an artificial resource limit intended to avoid
resource starvation, then it must <span>fail the WebSocket
connection</span>.</p>
@@ -83735,13 +83677,16 @@
<ol>
- <li><p>Send a 0x00 byte to the server.</p></li>
+ <li><p>Encode the text in <var title="">data</var> using UTF-8 to
+ obtain the byte stream <var title="">bytes</var>.</p></li>
- <li><p>Encode <var title="">data</var> using UTF-8 and send the
- resulting byte stream to the server.</p></li>
-
<li><p>Send a 0xFF byte to the server.</p></li>
+ <li><p>Send the number of bytes in <var title="">bytes</var>, as
+ a 64 bit big-endian integer, to the server.</p></li>
+
+ <li><p>Send <var title="">raw data</var> to the server.</p></li>
+
</ol>
<p>Once <span>the WebSocket closing handshake has started</span>,
@@ -83759,10 +83704,8 @@
<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 nine 0x00 bytes 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
@@ -83777,7 +83720,7 @@
<p class="note">If the user agent initiates it, the closing
handshake <span title="the WebSocket closing handshake has
- finished">finishes</span> once the server returns the 0xFF frame, as
+ finished">finishes</span> once the server returns the 0x00 frame, as
described above.</p>
<hr>
@@ -83786,12 +83729,7 @@
server, the user agent must <span>fail the WebSocket
connection</span>.</p>
- <!-- v2: People often request the ability to send binary blobs over
- this API; we should also look into allowing name/value pairs,
- arrays, and numbers using send() instead of just strings and binary
- data. -->
-
<h6>Handling errors in UTF-8 from the server</h6>
<p>When a client is to interpret a byte stream as UTF-8 but finds
@@ -84365,119 +84303,86 @@
<h6 id="ws-sd-framing">Data framing</h6>
<p>The server must run through the following steps to process the
- bytes sent by the client. If at any point during these steps a read
+ bytes sent by the client. If at any point during these steps a read
is attempted but fails because the <span>WebSocket connection is
closed</span>, then abort.</p>
<ol>
- <li id="ws-sd-frame"><p><i title="">Frame</i>: Read a byte from the
- client. Let <var title="">type</var> be that byte.</p></li>
-
<li>
- <p>If the most significant bit of <var title="">type</var> is not
- set, then run the following steps:</p>
+ <p>Try to read a byte from the client. Let <var title="">frame
+ type</var> be that byte.</p>
- <ol>
+ </li>
- <li><p>If <var title="">type</var> is not a 0x00 byte, then the
- server may abort these steps and either immediately disconnect
- from the client or set the <var title="">client terminated</var>
- flag.</p></li>
+ <li>
- <li><p>Let <var title="">raw data</var> be an empty byte
- array.</p></li>
+ <p>Try to read eight more bytes from the client. Let <var
+ title="">frame length</var> be the result of interpreting those
+ eight bytes as a big-endian 64 bit integer.</p>
- <li id="ws-sd-data"><p><i>Data</i>: Read a byte, let <var
- title="">b</var> be that byte.</p></li>
+ </li>
- <li><p>If <var title="">b</var> is not 0xFF, then append <var
- title="">b</var> to <var title="">raw data</var> and return to
- the previous step (labeled <a
- href="#ws-sd-data"><i>data</i></a>).</p></li>
+ <li>
- <li><p>If <var title="">type</var> was 0x00, interpret <var
- title="">raw data</var> as a UTF-8 string, and apply whatever
- server-specific processing is to occur for the resulting string
- (the message from the client).</p>
+ <p>Try to read <var title="">frame length</var> bytes from the
+ client. Let <var title="">raw data</var> be those bytes.</p>
- </ol>
+ </li>
- <p>Otherwise, the most significant bit of <var title="">type</var>
- is set. Run the following steps.</p>
+ <li>
- <ol>
+ <p>If <var title="">frame length</var> is greater than the length
+ of data the server is able to deal with at this time, the server
+ may abort these steps and either immediately disconnect from the
+ client or set the <var title="">client terminated</var>
+ flag. Alternatively, the server may just discard this frame and
+ jump back to the first step.</p>
- <li><p>If <var title="">type</var> is not a 0xFF byte, then the
- server may abort these steps and either immediately disconnect
- from the client or set the <var title="">client terminated</var>
- flag.</p></li>
+ </li>
- <li><p>Let <var title="">length</var> be zero.</p></li>
+ <li>
- <li id="ws-sd-length"><p><i>Length</i>: Read a byte, let <var
- title="">b</var> be that byte.</p></li>
+ <p>Handle the <var title="">frame type</var> byte as follows:</p>
- <li>
+ <dl>
- <p>If <var title="">b</var> is not a 0x00 byte, then run these
- substeps:</p>
+ <dt>If the <var title="">frame type</var> byte is 0x00 and the <var title="">frame length</var> is 0</dt>
- <ol>
+ <dd>
- <li><p>The server may abort these steps and either immediately
- disconnect from the client or set the <var title="">client
- terminated</var> flag.</p></li>
+ <p>Set the <var title="">client terminated</var> flag and abort
+ these steps. All further data sent by the client should be
+ discarded.</p>
- <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>
+ </dd>
- <li><p>Multiply <var title="">length</var> by 128, add <var
- title="">b<sub title="">v</sub></var> to that result, and store
- the final result in <var title="">length</var>.</p></li>
+ <dt>If the <var title="">frame type</var> byte is 0xFF</dt>
- <li><p>If the high-order bit of <var title="">b</var> is set
- (i.e. if <var title="">b</var> <i title="">and</i>ed with 0x80
- returns 0x80), then return to the step above labeled <a
- href="#ws-sd-length"><i>length</i></a>.</p></li>
+ <dd>
- <li>
+ <p>Interpret <var title="">raw data</var> as a UTF-8 string, and
+ apply whatever server-specific processing is to occur for the
+ resulting string (the message from the client).</p>
- <p>Read <var title="">length</var> bytes.</p>
+ </dd>
- <p class="warning">It is possible for a malicious client to send
- frames with lengths greater than 2<sup>31</sup> or
- 2<sup>32</sup> bytes, overflowing a signed or unsigned 32-bit
- integer. Servers may therefore impose implementation-specific
- limits on the lengths of invalid frames that they will skip, if
- they support skipping such frames at all. If a server cannot
- correctly skip past a long frame, then the server must abort
- these steps (discarding all future data), and should either
- immediately disconnect from the client or set the <var
- title="">client terminated</var> flag.</p>
+ <dt>Otherwise</dt>
- </li>
+ <dd>
- <li><p>Discard the read bytes.</p></li>
+ <p>The server may abort these steps and either immediately
+ disconnect from the client or set the <var title="">client
+ terminated</var> flag.</p>
- </ol>
+ </dd>
- </li>
+ </dl>
- <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>
- <li><p>Return to the step labeled <a
- href="#ws-sd-frame"><i>frame</i></a>.</p></li>
+ <li><p>Return to the first step to read the next byte.</p></li>
</ol>
@@ -84488,15 +84393,16 @@
<ol>
- <li><p>Send a 0x00 byte to the client to indicate the start of a
- string.</p></li>
+ <li><p>Encode the text using UTF-8 to obtain the byte stream <var
+ title="">raw data</var>.</p></li>
- <li><p>Encode <var title="">data</var> using UTF-8 and send the
- resulting byte stream to the client.</p></li>
+ <li><p>Send a 0xFF byte to the client.</p></li>
- <li><p>Send a 0xFF byte to the client to indicate the end of the
- message.</p></li>
+ <li><p>Send the number of bytes in <var title="">raw data</var>, as
+ a 64 bit big-endian integer, to the client.</p></li>
+ <li><p>Send <var title="">raw data</var> to the client.</p></li>
+
</ol>
<hr>
@@ -84508,8 +84414,8 @@
<ol>
- <li><p>Send a 0xFF byte and a 0x00 byte to the client to indicate
- the start of the closing handshake.</p></li>
+ <li><p>Send nine 0x00 bytes to the client to indicate the start of
+ the closing handshake.</p></li>
<li><p>Wait until the <var title="">client terminated</var> flag
has been set, or until a server-defined timeout expires.</p></li>
@@ -84519,12 +84425,11 @@
</ol>
<p>Once these steps have started, the server must not send any
- further data to the client. The 0xFF 0x00 bytes indicate the end of
+ further data to the client. The nine 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
More information about the Commit-Watchers
mailing list