Re: [hybi] Opera's Pre-Last Call review of websocket -06

Ian Fette (イアンフェッティ) <ifette@google.com> Fri, 22 April 2011 01:45 UTC

Return-Path: <ifette@google.com>
X-Original-To: hybi@ietfc.amsl.com
Delivered-To: hybi@ietfc.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfc.amsl.com (Postfix) with ESMTP id 1272EE0719 for <hybi@ietfc.amsl.com>; Thu, 21 Apr 2011 18:45:41 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -106.376
X-Spam-Level:
X-Spam-Status: No, score=-106.376 tagged_above=-999 required=5 tests=[AWL=0.700, BAYES_00=-2.599, FM_FORGED_GMAIL=0.622, GB_I_LETTER=-2, HTML_MESSAGE=0.001, J_CHICKENPOX_14=0.6, MIME_8BIT_HEADER=0.3, RCVD_IN_DNSWL_MED=-4, USER_IN_WHITELIST=-100]
Received: from mail.ietf.org ([208.66.40.236]) by localhost (ietfc.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id jOMLFOMOuiS3 for <hybi@ietfc.amsl.com>; Thu, 21 Apr 2011 18:45:28 -0700 (PDT)
Received: from smtp-out.google.com (smtp-out.google.com [216.239.44.51]) by ietfc.amsl.com (Postfix) with ESMTP id 7A6C4E06E2 for <hybi@ietf.org>; Thu, 21 Apr 2011 18:45:28 -0700 (PDT)
Received: from kpbe18.cbf.corp.google.com (kpbe18.cbf.corp.google.com [172.25.105.82]) by smtp-out.google.com with ESMTP id p3M1jRFx002339 for <hybi@ietf.org>; Thu, 21 Apr 2011 18:45:27 -0700
DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=google.com; s=beta; t=1303436728; bh=ztzEwHqQn2wwlblUFebxks/YkPk=; h=MIME-Version:Reply-To:In-Reply-To:References:Date:Message-ID: Subject:From:To:Cc:Content-Type; b=xXkGaDWUf8jlWOrrH/XEn8+coZXF9HGhn0SDuSkwiMhiZeLFy+ZMF3SzvUehkGgdu jGUOX2TXKk4ZJzlbDJG1Q==
Received: from qwc23 (qwc23.prod.google.com [10.241.193.151]) by kpbe18.cbf.corp.google.com with ESMTP id p3M1j02F016880 (version=TLSv1/SSLv3 cipher=RC4-SHA bits=128 verify=NOT) for <hybi@ietf.org>; Thu, 21 Apr 2011 18:45:26 -0700
Received: by qwc23 with SMTP id 23so183790qwc.17 for <hybi@ietf.org>; Thu, 21 Apr 2011 18:45:26 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=beta; h=domainkey-signature:mime-version:reply-to:in-reply-to:references :date:message-id:subject:from:to:cc:content-type; bh=QfwCI6QtAYW9vkzmJYaU2hU38JC9S16uSW5Uawmixoc=; b=cmzxf0cn//nMBnVyFuFn7qij9QBqJLPfwvJtJmYuHKVlgFedOn9sTWacXhW/OEIvao PsVbh3ZWkPpicyZvZQ9A==
DomainKey-Signature: a=rsa-sha1; c=nofws; d=google.com; s=beta; h=mime-version:reply-to:in-reply-to:references:date:message-id :subject:from:to:cc:content-type; b=NIpVJESqXAq+Zufqw//DCD3L4hLr7/6lF1Yh8m/R8OH/GuEo5b8RdUQHNIznYHEbma e/9ByKuYcJOIEY4YDNRA==
MIME-Version: 1.0
Received: by 10.229.44.198 with SMTP id b6mr466020qcf.67.1303436725550; Thu, 21 Apr 2011 18:45:25 -0700 (PDT)
Received: by 10.229.0.137 with HTTP; Thu, 21 Apr 2011 18:45:25 -0700 (PDT)
In-Reply-To: <op.vteywfw6idj3kv@simon-pieterss-macbook.local>
References: <op.vs9bponnidj3kv@simon-pieterss-macbook.local> <op.vs9li6der4mipi@emoller-pc.gothenburg.osa> <op.vteywfw6idj3kv@simon-pieterss-macbook.local>
Date: Thu, 21 Apr 2011 18:45:25 -0700
Message-ID: <BANLkTimTC2nf13eCrOZ0E_ZBPueFMxwpmA@mail.gmail.com>
From: "Ian Fette (イアンフェッティ)" <ifette@google.com>
To: Simon Pieters <simonp@opera.com>
Content-Type: multipart/alternative; boundary="0016364184ff038cd304a17803e2"
X-System-Of-Record: true
Cc: "hybi@ietf.org" <hybi@ietf.org>
Subject: Re: [hybi] Opera's Pre-Last Call review of websocket -06
X-BeenThere: hybi@ietf.org
X-Mailman-Version: 2.1.12
Precedence: list
Reply-To: ifette@google.com
List-Id: Server-Initiated HTTP <hybi.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/hybi>, <mailto:hybi-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/hybi>
List-Post: <mailto:hybi@ietf.org>
List-Help: <mailto:hybi-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/hybi>, <mailto:hybi-request@ietf.org?subject=subscribe>
X-List-Received-Date: Fri, 22 Apr 2011 01:45:41 -0000

On Mon, Apr 4, 2011 at 5:42 AM, Simon Pieters <simonp@opera.com> wrote:

> Hi,
>
> We have reviewed
> http://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-06
>
> The introduction section is non-normative but has a number of MUSTs. Please
> don't have any requirements in the introduction.
>

I have ensured that normative requirements are now consistently upper case.
There are no upper case MUSTs left in the non-normative introduction in the
draf that will be 07.


>
> Why was Sec-WebSocket-Location removed?
>


It is now redundant given that there's a path specified in the get request.


>
> The spec does not define "WebSocket connection is established", "a
> WebSocket message has been received", "a WebSocket error has been detected",
> "the WebSocket closing handshake has started", which means that the API
> spec's hooks don't work and you would never get any 'open', 'message' or
> 'error' events.
>

I will have to take a look at this with Hixie, there also need to be some
changes to the HTML spec that we've discussed (e.g. adding binary). I will
consult with him to make sure the appropriate hooks are present.


>
> Should probably have some text about when pings may be sent.
>


Added "An endpoint MAY send a Ping message any time after the connection
          is established and before the connection is closed. NOTE: A ping
          message may serve either as a keepalive, or to verify that the
          remote endpoint is still responsive."


>
> Should better cover error handling, e.g. what should happen when the high
> bit is set on the 63-bit length, what happens when the RSV bits are set,
> what should happen when FIN is set but opcode is 0x00, or a control frame is
> fragmented or has length greater than 125? I'd prefer detailed algorithms
> that covered every possible case, so that it is easy to argue that all cases
> are covered and so that it is clear when to fire relevant events and how
> many, etc. Just having a list with cases that are 'errors' does not make it
> clear when the error is to be detected or what should be done when multiple
> error cases match.
>

We added a section on error codes for Close frames, that said I did want to
leave a bit of flexibility for implementors to provide more specific errors.
There are a few areas where I explicitly said an endpoint MAY send the
following error code, I don't know if we should say MUST for each possible
error? Frankly, most of them are likely to just be 1002 Protocol Error, and
unrecoverable and useless to a developer beyond the fact a protocol error
occurred.



>
>
>  2.  Conformance requirements
>>  All diagrams, examples, and notes in this specification are non-
>>   normative, as are all sections explicitly marked non-normative.
>>   Everything else in this specification is normative.
>>  The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT",
>>   "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this
>>   document are to be interpreted as described in RFC2119.  For
>>   readability, these words do not appear in all uppercase letters in
>>   this specification.  [RFC2119]
>>
>
> It seems this specification uses a mix of lowercase and all uppercase.
>

Fixed.



>
>    Requirements phrased in the imperative as part of algorithms (such as
>>   "strip any leading space characters" or "return false and abort these
>>   steps") are to be interpreted with the meaning of the key word
>>   ("must", "should", "may", etc) used in introducing the algorithm.
>>  Conformance requirements phrased as algorithms or specific steps may
>>   be implemented in any manner, so long as the end result is
>>   equivalent.  (In particular, the algorithms defined in this
>>   specification are intended to be easy to follow, and not intended to
>>   be performant.)
>>  Implementations may impose implementation-specific limits on
>>   otherwise unconstrained inputs, e.g. to prevent denial of service
>>   attacks, to guard against running out of memory, or to work around
>>   platform-specific limitations.
>>  The conformance classes defined by this specification are user agents
>>   and servers.
>> 2.1.  Terminology
>>  *ASCII* shall mean the character-encoding scheme defined in
>>   [ANSI.X3-4.1986].
>>  *Converting a string to ASCII lowercase* means replacing all
>>   characters in the range U+0041 to U+005A (i.e.  LATIN CAPITAL LETTER
>>   A to LATIN CAPITAL LETTER Z) with the corresponding characters in the
>>   range U+0061 to U+007A (i.e.  LATIN SMALL LETTER A to LATIN SMALL
>>   LETTER Z).
>>  Comparing two strings in an *ASCII case-insensitive* manner means
>>   comparing them exactly, code point for code point, except that the
>>   characters in the range U+0041 to U+005A (i.e.  LATIN CAPITAL LETTER
>>   A to LATIN CAPITAL LETTER Z) and the corresponding characters in the
>>   range U+0061 to U+007A (i.e.  LATIN SMALL LETTER A to LATIN SMALL
>>   LETTER Z) are considered to also match.
>>  The term "URI" is used in this section in a manner consistent with
>>   the terminology used in HTML, namely, to denote a string that might
>>   or might not be a valid URI or IRI and to which certain error
>>   handling behaviors will be applied when the string is parsed.
>>   [RFC3986]
>>
>
> HTML calls it "URL", so doesn't seem particularly consistent.
>

I have been chastised to use IRI and URI consistently.



>
>    When an implementation is required to _send_ data as part of the
>>   WebSocket protocol, the implementation may delay the actual
>>   transmission arbitrarily, e.g. buffering data so as to send fewer IP
>>   packets.
>> 3.  WebSocket URIs
>> 3.1.  Parsing WebSocket URIs
>>  The steps to *parse a WebSocket URI's components* from a string /uri/
>>   are as follows.  These steps return either a /host/, a /port/, a
>>   /resource name/, and a /secure/ flag, or they fail.
>>  1.   If the /uri/ string is not an absolute URI, then fail this
>>        algorithm.  [RFC3986] [RFC3987]
>>  2.   Resolve the /uri/ string using the resolve a Web address
>>        algorithm defined by the Web addresses specification, with the
>>        URI character encoding set to UTF-8.  [RFC3629] [RFC3986]
>>        [RFC3987]
>>       NOTE: It doesn't matter what it is resolved relative to, since
>>        we already know it is an absolute URI at this point.
>>  3.   If /uri/ does not have a <scheme> component whose value, when
>>        converted to ASCII lowercase, is either "ws" or "wss", then fail
>>        this algorithm.
>>  4.   If /uri/ has a <fragment> component, then fail this algorithm.
>>  5.   If the <scheme> component of /uri/ is "ws", set /secure/ to
>>        false; otherwise, if the <scheme> component is "wss", set
>>        /secure/ to true; otherwise, fail this algorithm.
>>
>
> We already know it's either "ws" or "wss", so this can't fail.
>


True, but it doesn't seem to hurt...


>
>    6.   Let /host/ be the value of the <host> component of /uri/,
>>        converted to ASCII lowercase.
>>  7.   If /uri/ has a <port> component, then let /port/ be that
>>        component's value; otherwise, there is no explicit /port/.
>>  8.   If there is no explicit /port/, then: if /secure/ is false, let
>>        /port/ be 80, otherwise let /port/ be 443.
>>  9.   Let /resource name/ be the value of the <path> component (which
>>        might be empty) of /uri/.
>>  10.  If /resource name/ is the empty string, set it to a single
>>        character U+002F SOLIDUS (/).
>>  11.  If /uri/ has a <query> component, then append a single U+003F
>>        QUESTION MARK character (?) to /resource name/, followed by the
>>        value of the <query> component.
>>  12.  Return /host/, /port/, /resource name/, and /secure/.
>> 3.2.  Constructing WebSocket URIs
>>  The steps to *construct a WebSocket URI* from a /host/, a /port/, a
>>   /resource name/, and a /secure/ flag, are as follows:
>>  1.  Let /uri/ be the empty string.
>>  2.  If the /secure/ flag is false, then append the string "ws://" to
>>       /uri/.  Otherwise, append the string "wss://" to /uri/.
>>  3.  Append /host/ to /uri/.
>>  4.  If the /secure/ flag is false and port is not 80, or if the
>>       /secure/ flag is true and port is not 443, then append the string
>>       ":" followed by /port/ to /uri/.
>>  5.  Append /resource name/ to /uri/.
>>  6.  Return /uri/.
>> 3.3.  Valid WebSocket URIs
>>  For a WebSocket URI to be considered valid, the following conditions
>>   MUST hold.
>>  o  The /host/ must be ASCII-only (i.e. it must have been punycode-
>>      encoded already if necessary, and MUST NOT contain any characters
>>      above U+007E).
>>  o  The /resource name/ string must be a non-empty string of
>>      characters in the range U+0021 to U+007E that starts with a U+002F
>>      SOLIDUS character (/).
>>  Any WebSocket URIs not meeting the above criteria are considered
>>   invalid, and a client MUST NOT attempt to make a connection to an
>>   invalid WebSocket URI.  A client SHOULD attempt to parse a URI
>>   obtained from any external source (such as a web site or a user)
>>   using the steps specified in Section 3.1 to obtain a valid WebSocket
>>   URI, but MUST NOT attempt to connect with such an unparsed URI, and
>>   instead only use the parsed version and only if that version is
>>   considered valid by the criteria above.
>> 4.  Data Framing
>> 4.1.  Overview
>>  In the WebSocket protocol, data is transmitted using a sequence of
>>   frames.  Frames sent from the client to the server are masked to
>>   avoid confusing network intermediaries, such as intercepting proxies.
>>   Frames sent from the server to the client are not masked.
>>  The base framing protocol defines a frame type with an opcode, a
>>   payload length, and designated locations for extension and
>>   application data, which together define the _payload_ data.  Certain
>>   bits and opcodes are reserved for future expansion of the protocol.
>>   As such, In the absence of extensions negotiated during the opening
>>   handshake (Section 5), all reserved bits MUST be 0 and reserved
>>   opcode values MUST NOT be used.
>>  A data frame MAY be transmitted by either the client or the server at
>>   any time after handshake completion and before that endpoint has sent
>>   a close message (Section 4.5.1).
>> 4.2.  Client-to-Server Masking
>>  The client MUST mask all frames sent to the server.
>>  The masking-key is contained completely within the frame.
>>  The masking-key is a 32-bit value chosen at random by the client.
>>   The masking-key MUST be derived from a strong source of entropy, and
>>   the masking-key for a given frame MUST NOT make it simple for a
>>   server to predict the masking-key for a subsequent frame.
>>  Each masked frame consists of a 32-bit masking-key followed by
>>   masked-data:
>>    masked-frame  = masking-key masked-data
>>     masking-key   = 4full-octet
>>     masked-data   = *full-octet
>>     full-octet    = %x00-FF
>>  The masked-data is the clear-text frame "encrypted" using a simple
>>   XOR cipher as follows.
>>  Octet i of the masked-data is the XOR of octet i of the clear text
>>   frame with octet i modulo 4 of the masking-key:
>>    j              = i MOD 4
>>     masked-octet-i = clear-text-octet-i XOR octet-j-of-masking-key
>>  When preparing a masked-frame, the client MUST pick a fresh masking-
>>   key uniformly at random from the set of allowed 32-bit values.  The
>>   unpredictability of the masking-nonce is essential to prevent the
>>   author of malicious application data from selecting the bytes that
>>   appear on the wire.
>> 4.3.  Base Framing Protocol
>>  This wire format for the data transfer part is described by the ABNF
>>   given in detail in this section.  A high level overview of the
>>   framing is given in the following figure.  [RFC5234]
>>     0                   1                   2                   3
>>      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
>>     +-+-+-+-+-------+-+-------------+-------------------------------+
>>     |F|R|R|R| opcode|R| Payload len |    Extended payload length    |
>>     |I|S|S|S|  (4)  |S|     (7)     |             (16/63)           |
>>     |N|V|V|V|       |V|             |   (if payload len==126/127)   |
>>     | |1|2|3|       |4|             |                               |
>>     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
>>     |     Extended payload length continued, if payload len == 127  |
>>     + - - - - - - - - - - - - - - - +-------------------------------+
>>     |                               |         Extension data        |
>>     +-------------------------------+ - - - - - - - - - - - - - - - +
>>     :                                                               :
>>     +---------------------------------------------------------------+
>>     :                       Application data                        :
>>     +---------------------------------------------------------------+
>>  FIN:  1 bit
>>     Indicates that this is the final fragment in a message.  The first
>>      fragment may also be the final fragment.
>>  RSV1, RSV2, RSV3, RSV4:  1 bit each
>>     Must be 0 unless an extension is negotiated which defines meanings
>>      for non-zero values
>>  Opcode:  4 bits
>>     Defines the interpretation of the payload data
>>  Payload length:  7 bits
>>     The length of the payload: if 0-125, that is the payload length.
>>      If 126, the following 2 bytes interpreted as a 16 bit unsigned
>>      integer are the payload length.  If 127, the following 8 bytes
>>      interpreted as a 64-bit unsigned integer (the high bit must be 0)
>>      are the payload length.  Multibyte length quantities are expressed
>>      in network byte order.  The payload length is the length of the
>>      Extension data + the length of the Application Data.  The length
>>      of the Extension data may be zero, in which case the Payload
>>      length is the length of the Application data.
>>  Extension data:  n bytes
>>     The extension data is 0 bytes unless there is a reserved op-code
>>      or reserved bit present in the frame which indicates an extension
>>      has been negotiated.  Any extension MUST specify the length of the
>>      extension data, or how that length may be calculated, and its use
>>      MUST be negotiated during the handshake.  If present, the
>>      extension data is included in the total payload length.
>>  Application data:  n bytes
>>     Arbitrary application data, taking up the remainder of the frame
>>      after any extension data.  The length of the Application data is
>>      equal to the payload length minus the length of the Extension
>>      data.
>>  The base framing protocol is formally defined by the following ABNF
>>   [RFC5234]:
>>     ws-frame               = frame-fin
>>                               frame-rsv1
>>                               frame-rsv2
>>                               frame-rsv3
>>                               frame-opcode
>>                               frame-rsv4
>>                               frame-length
>>                               frame-extension
>>                               application-data;
>>     frame-fin              = %x0 ; more frames of this message follow
>>                             / %x1 ; final frame of message
>>     frame-rsv1             = %x0 ; 1 bit, must be 0
>>     frame-rsv2             = %x0 ; 1 bit, must be 0
>>     frame-rsv3             = %x0 ; 1 bit, must be 0
>>     frame-opcode           = %x0 ; continuation frame
>>                             / %x1 ; connection close
>>                             / %x2 ; ping
>>                             / %x3 ; pong
>>                             / %x4 ; text frame
>>                             / %x5 ; binary frame
>>                             / %x6-F ; reserved
>>     frame-rsv4             = %x0 ; 1 bit, must be 0
>>     frame-length           = %x00-7D
>>                             / %x7E frame-length-16
>>                             / %x7F frame-length-63
>>     frame-length-16        = %x0000-FFFF
>>     frame-length-63        = %x0000000000000000-7FFFFFFFFFFFFFFF
>>     frame-extension        = *( %x00-FF ) ; to be defined later
>>     application-data       = *( %x00-FF )
>> 4.4.  Fragmentation
>>  The primary purpose of fragmentation is to allow sending a message
>>   that is of unknown size when the message is started without having to
>>   buffer that message.  If messages couldn't be fragmented, then an
>>   endpoint would have to buffer the entire message so its length could
>>   be counted before first byte is sent.  With fragmentation, a server
>>   or intermediary may choose a reasonable size buffer, and when the
>>   buffer is full write a fragment to the network.
>>  A secondary use-case for fragmentation is for multiplexing, where it
>>   is not desirable for a large message on one logical channel to
>>   monopolize the output channel, so the MUX needs to be free to split
>>   the message into smaller fragments to better share the output
>>   channel.
>>  The following rules apply to fragmentation:
>>  o  An unfragmented message consists of a single frame with the FIN
>>      bit set and an opcode other than 0.
>>  o  A fragmented message consists of a single frame with the FIN bit
>>      clear and an opcode other than 0, followed by zero or more frames
>>      with the FIN bit clear and the opcode set to 0, and terminated by
>>      a single frame with the FIN bit set and an opcode of 0.  Its
>>      content is the concatenation of the application data from each of
>>      those frames in order.  As an example, for a text message sent as
>>      three fragments, the first fragment would have an opcode of 0x4
>>      and a FIN bit clear, the second fragment would have an opcode of
>>      0x0 and a FIN bit clear, and the third fragment would have an
>>      opcode of 0x0 and a FIN bit that is set.
>>  o  Control frames MAY be injected in the middle of a fragmented
>>      message.  Control frames themselves MUST NOT be fragmented. _Note:
>>      if control frames could not be interjected, the latency of a ping,
>>      for example, would be very long if behind a large message.  As
>>      such, an endpoint MUST be capable of handling control frames in
>>      the middle of a fragmented message._
>>
>
> Please don't have MUSTs inside notes, since the conformance section
> says notes are non-normative.
>


fixed


>
>    o  A sender MAY create fragments of any size for non control
>>      messages.
>>  o  Clients and servers MUST support receiving both fragmented and
>>      unfragmented messages.
>>  o  An intermediary MAY change the fragmentation of a message if the
>>      message uses only opcode and reserved bit values known to the
>>      intermediary.
>>  o  As a consequence of these rules, all fragments of a message are of
>>      the same type, as set by the first fragment's opcode.  Since
>>      Control frames cannot be fragmented, the type for all fragments in
>>      a message MUST be either text or binary, or one of the reserved
>>      opcodes.
>> 4.5.  Control Frames
>>  Control frames have opcodes of 0x01 (Close), 0x02 (Ping), or 0x03
>>   (Pong).  Control frames are used to communicate state about the
>>   websocket.  Control frames can be interjected in the middle of a
>>   fragmented message.
>>  All control frames MUST be 125 bytes or less in length and MUST NOT
>>   be fragmented.
>> 4.5.1.  Close
>>  The Close message contains an opcode of 0x01.
>>  The Close message MAY contain a body (the "application data" portion
>>   of the frame) that indicates a reason for closing, such as an
>>   endpoint shutting down, an endpoint having received a message too
>>   large, or an endpoint having received a message that does not conform
>>   to the format expected by the other endpoint.  If there is a body,
>>   the first two bytes of the body MUST be a 2-byte integer (in network
>>   byte order) representing a status code defined in Section 7.4.
>>   Following the 2-byte integer the body MAY contain UTF-8 encoded data,
>>   the interpretation of which is not defined by this specification.
>>  The application MUST NOT send any more data messages after sending a
>>   close message.
>>
>
> What are 'data messages'? I see data frames, but not data messages. Are
> control frames allowed to be sent after close?
>


Changed to be data frames. Control frames I believe should still be allowed.
Let's say you send a close frame and don't get a response, perhaps you try
again? Though I don't feel especially strongly here.


>
>    If an endpoint receives a Close message and that endpoint did not
>>   previously send a Close message, the endpoint MUST send a Close
>>   message in response.  It SHOULD do so as soon as is practical.
>>  After both sending and receiving a close message, an endpoint
>>   considers the websocket connection closed, and SHOULD close the
>>   underlying TCP connection.
>>  If a client and server both send a Close message at the same time,
>>   both endpoints will have sent and received a Close message and should
>>   consider the websocket connection closed and close the underlying TCP
>>   connection.
>> 4.5.2.  Ping
>>  The Ping message contains an opcode of 0x02.
>>  Upon receipt of a Ping message, an endpoint MUST send a Pong message
>>   in response.  It SHOULD do so as soon as is practical.  The message
>>   bodies of the Ping and Pong MUST be the same.
>> 4.5.3.  Pong
>>  The Pong message contains an opcode of 0x03.
>>  Upon receipt of a Ping message, an endpoint MUST send a Pong message
>>   in response.  It SHOULD do so as soon as is practical.  The message
>>   bodies of the Ping and Pong MUST be the same.  A Pong is issued only
>>   in response to the most recent Ping.
>>
>
> This text is identical to the text in the previous section, except for
> the last sentence. I suggest stating the requirements only once, and
> making the last sentence normative by including a MUST.
>


In the latest draft there are some differences.  fixed re: the last
sentence.


>
>  4.6.  Data Frames
>>  All frame types not listed in Section 4.5 are data frames, which
>>   transport application-layer data.  The opcode determines the
>>   interpretation of the application data:
>>  Text
>>     The payload data is text data encoded as UTF-8.
>>  Binary
>>     The payload data is arbitrary binary data whose interpretation is
>>      solely up to the application layer.
>> 4.7.  Examples
>>  _This section is non-normative._
>>  o  A single-frame text message
>>     *  0x84 0x05 0x48 0x65 0x6c 0x6c 0x6f (contains "Hello")
>>  o  A fragmented text message
>>     *  0x04 0x03 0x48 0x65 0x6c (contains "Hel")
>>     *  0x80 0x02 0x6c 0x6f (contains "lo")
>>  o  Ping request and response
>>     *  0x82 0x05 0x48 0x65 0x6c 0x6c 0x6f (contains a body of "Hello",
>>         but the contents of the body are arbitrary)
>>     *  0x83 0x05 0x48 0x65 0x6c 0x6c 0x6f (contains a body of "Hello",
>>         matching the body of the ping)
>>  o  256 bytes binary message in a single frame
>>     *  0x85 0x7E 0x0100 [256 bytes of binary data]
>>  o  64KiB binary message in a single frame
>>     *  0x85 0x7F 0x0000000000010000 [65536 bytes of binary data]
>> 4.8.  Extensibility
>>  The protocol is designed to allow for extensions, which will add
>>   capabilities to the base protocols.  The endpoints of a connection
>>   MUST negotiate the use of any extensions during the handshake.  This
>>   specification provides opcodes 0x6 through 0xF, the extension data
>>   field, and the frame-rsv1, frame-rsv2, frame-rsv3, and frame-rsv4
>>   bits of the frame header for use by extensions.  The negotiation of
>>   extensions is discussed in further detail in Section 8.1.  Below are
>>   some anticipated uses of extensions.  This list is neither complete
>>   nor proscriptive.
>>  o  Extension data may be placed in the payload before the application
>>      data.
>>  o  Reserved bits can be allocated for per-frame needs.
>>  o  Reserved opcode values can be defined.
>>  o  Reserved bits can be allocated to the opcode field if more opcode
>>      values are needed.
>>  o  A reserved bit or an "extension" opcode can be defined which
>>      allocates additional bits out of the payload area to define larger
>>      opcodes or more per-frame bits.
>> 5.  Opening Handshake
>> 5.1.  Client Requirements
>>  User agents running in controlled environments, e.g. browsers on
>>   mobile handsets tied to specific carriers, may offload the management
>>   of the connection to another agent on the network.  In such a
>>   situation, the user agent for the purposes of conformance is
>>   considered to include both the handset software and any such agents.
>>  When the user agent is to *establish a WebSocket connection* to a
>>   WebSocket URI /uri/, it must meet the following requirements.  In the
>>   following text, we will use terms from Section 3 such as "/host/" and
>>   "/secure/ flag" as defined in that section.
>>
>
> Section 11 says that specifications are to feed this algorithm with
> /host/, /port/, /resource name/, /secure/, /origin/ and /subprotocol/.
> Not /uri/. The WebSocket API invokes this algorithm in accordance with
> section 11. Please make this text closer to what it is in -00.
>


I have tried to address this by essentially saying the algorithm can be
invoked with a URI when then the algorithms in section 3 are invoked to
break down that URI, or the algorithm can be invoked by passing in the
parameters specified in section 11. I think it results in the same net
effect and is somewhat cleaner.


>
> Actually the WebSocket API also has a /defer cookies/ flag. It seems
> this has not been incorporated into the spec, or has been dropped at
> some point. Please take in the defer cookies stuff from
> http://www.whatwg.org/specs/web-socket-protocol/ (the opening paragraph
> in section 5, step 46 and 47 in the algorithm, and the *apply the
> cookies* definition.
>


There are a few hooks that are not consistent, /defer cookies/ was one of
them. I need to sit down with Hixie as part of review and iron these out. I
don't think reviving /defer cookies/ would be sufficient.





>
>    1.  The WebSocket URI and its components MUST be valid according to
>>       Section 3.3.  If any of the requirements are not met, the client
>>       MUST fail the WebSocket connection and abort these steps.
>>
>
> Checking this is the responsibility of the API spec, by invoking "parse
> a WebSocket URI's components" defined in this specification. If it
> fails to parse, this algorithm is not invoked to begin with.
>

The API spec is not necessarily the only thing that could use the protocol.
I don't see harm in leaving this in.


>
>    2.  If the user agent already has a WebSocket connection to the
>>       remote host (IP address) identified by /host/, even if known by
>>       another name, the user agent MUST wait until that connection has
>>       been established or for that connection to have failed.  There
>>       MUST be no more than one connection in a CONNECTING state.  If
>>
>
> Regardless of host? So we serialize tabs as well?
>

I'm not sure I understand what you mean by serializing tabs? The intent was
that if a.com resolves to 1.2.3.4 and b.com also resolves to 1.2.3.4, a
connection to b.com should wait while a connection to a.com is establishing.


>
>        multiple connections to the same IP address are attempted
>>       simultaneously, the user agent MUST serialize them so that there
>>       is no more than one connection at a time running through the
>>       following steps.
>>      If the user agent cannot determine the IP address of the remote
>>       host (for example because all communication is being done through
>>       a proxy server that performs DNS queries itself), then the user
>>       agent MUST assume for the purposes of this step that each host
>>       name refers to a distinct remote host, but should instead limit
>>       the total number of simultaneous connections that are not
>>       established to a reasonably low number (e.g., in a Web browser,
>>       to the number of tabs the user has open).
>>      NOTE: This makes it harder for a script to perform a denial of
>>       service attack by just opening a large number of WebSocket
>>       connections to a remote host.  A server can further reduce the
>>       load on itself when attacked by making use of this by pausing
>>       before closing the connection, as that will reduce the rate at
>>       which the client reconnects.
>>      NOTE: There is no limit to the number of established WebSocket
>>       connections a user agent can have with a single remote host.
>>
>
> No upper limit?
>

correct



>
>        Servers can refuse to connect users with an excessive number of
>>       connections, or disconnect resource-hogging users when suffering
>>       high load.
>>  3.  _Proxy Usage_: If the user agent is configured to use a proxy
>>       when using the WebSocket protocol to connect to host /host/
>>       and/or port /port/, then the user agent SHOULD connect to that
>>       proxy and ask it to open a TCP connection to the host given by
>>       /host/ and the port given by /port/.
>>         EXAMPLE: For example, if the user agent uses an HTTP proxy for
>>          all traffic, then if it was to try to connect to port 80 on
>>          server example.com, it might send the following lines to the
>>          proxy server:
>>             CONNECT example.com:80 HTTP/1.1
>>              Host: example.com
>>         If there was a password, the connection might look like:
>>             CONNECT example.com:80 HTTP/1.1
>>              Host: example.com
>>              Proxy-authorization: Basic ZWRuYW1vZGU6bm9jYXBlcyE=
>>      If the user agent is not configured to use a proxy, then a direct
>>       TCP connection SHOULD be opened to the host given by /host/ and
>>       the port given by /port/.
>>      NOTE: Implementations that do not expose explicit UI for
>>       selecting a proxy for WebSocket connections separate from other
>>       proxies are encouraged to use a SOCKS proxy for WebSocket
>>       connections, if available, or failing that, to prefer the proxy
>>       configured for HTTPS connections over the proxy configured for
>>       HTTP connections.
>>      For the purpose of proxy autoconfiguration scripts, the URI to
>>       pass the function must be constructed from /host/, /port/,
>>       /resource name/, and the /secure/ flag using the steps to
>>       construct a WebSocket URI.
>>      NOTE: The WebSocket protocol can be identified in proxy
>>       autoconfiguration scripts from the scheme ("ws:" for unencrypted
>>       connections and "wss:" for encrypted connections).
>>  4.  If the connection could not be opened, either because a direct
>>       connection failed or because any proxy used returned an error,
>>       then the user agent MUST fail the WebSocket connection and abort
>>       the connection attempt.
>>  5.  If /secure/ is true, the user agent MUST perform a TLS handshake
>>       over the connection.  If this fails (e.g. the server's
>>       certificate could not be verified), then the user agent MUST fail
>>
>
> What about popping open a dialogue if the cert is self signed?
>


I think that's up to the UA. The protocol doesn't specify how the
certificate is verified. If verifying it involves displaying a prompt to the
user, that is IMO at the discretion of the UA..


>
>        the WebSocket connection and abort the connection.  Otherwise,
>>       all further communication on this channel MUST run through the
>>       encrypted tunnel.  [RFC2246]
>>      User agents MUST use the Server Name Indication extension in the
>>       TLS handshake.  [RFC4366]
>>  Once a connection to the server has been established (including a
>>   connection via a proxy or over a TLS-encrypted tunnel), the client
>>   MUST send a handshake to the server.  The handshake consists of an
>>   HTTP upgrade request, along with a list of required and optional
>>   headers.  The requirements for this handshake are as follows.
>>  1.   The handshake must be a valid HTTP request as specified by
>>        [RFC2616].
>>  2.   The Method of the request MUST be GET and the HTTP version MUST
>>        be at least 1.1.
>>       For example, if the WebSocket URI is "ws://example.com/chat",
>>        The first line sent SHOULD be "GET /chat HTTP/1.1"
>>
>
> Please don't use SHOULD in an example, since examples are non-normative.
>

made lower case


>
>    3.   The request must contain a "Request-URI" as part of the GET
>>        method.  This MUST match the /resource name/ Section 3.
>>  4.   The request MUST contain a "Host" header whose value is equal to
>>        the authority component of the WebSocket URI.
>>
>
> Make it equal to /host/ since parsing a WebSocket URI's components will
> convert it to lowercase.
>

done



>
>    5.   The request MUST contain an "Upgrade" header whose value is
>>        equal to "websocket".
>>  6.   The request MUST contain a "Connection" header whose value MUST
>>        include the "Upgrade" token.
>>  7.   The request MUST include a header with the name "Sec-WebSocket-
>>        Key".  The value of this header MUST be a nonce consisting of a
>>        randomly selected 16-byte value that has been base64-encoded
>>        [RFC3548].  The nonce MUST be randomly selected randomly for
>>        each connection.
>>
>
> Double randomly.
>

fixed ;-)



>
>         NOTE: As an example, if the randomly selected value was the
>>        sequence of bytes 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09
>>        0x0a 0x0b 0x0c 0x0d 0x0e 0x0f 0x10, the value of the header
>>        would be "AQIDBAUGBwgJCgsMDQ4PEC=="
>>  8.   The request MUST include a header with the name "Sec-WebSocket-
>>        Origin" if the request is coming from a browser client.  If the
>>
>
> Maybe the conformance section should have different conformance classes
> for browesr clients and non-browser clients.
>


I'm not going to touch this one late in the game. How strongly do you feel?


>
>         connection is from a non-browser client, the request MAY include
>>        this header if the semantics of that client match the use-case
>>        described here for browser clients.  The value of this header
>>        MUST be the ASCII serialization of origin of the context in
>>        which the code establishing the connection is running, and MUST
>>        be lower-case.  The value MUST NOT contain letters in the range
>>        U+0041 to U+005A (i.e.  LATIN CAPITAL LETTER A to LATIN CAPITAL
>>        LETTER Z) [I-D.ietf-websec-origin].
>>       As an example, if code is running on www.example.com attempting
>>        to establish a connection to ww2.example.com, the value of the
>>        header would be "http://www.example.com".
>>  9.   The request MUST include a header with the name "Sec-WebSocket-
>>        Version".  The value of this header must be 6.
>>  10.  The request MAY include a header with the name "Sec-WebSocket-
>>        Protocol".  If present, this value indicates the subprotocol(s)
>>        the client wishes to speak.  The elements that comprise this
>>        value MUST be non-empty strings with characters in the range
>>        U+0021 to U+007E and MUST all be unique.  The ABNF for the value
>>
>
> and MUST all be unique strings. (just to make sure you don't think the
> characters must be unique)
>

done


>
>         of this header is 1#(token | quoted-string), where the
>>        definitions of constructs and rules are as given in [RFC2616].
>>
>
> I'd like this to say that, at least for browser clients, if the
> algorithm was invoked with a non-empty list of /subprotocols/ then the
> header MUST be included, with the values of /subprotocols/ joined by a
> comma and a space, and otherwise MUST NOT be included. Otherwise a
> browser would be conforming for requesting subprotocols at random.
>

It seems like that should be in the API requirement, not the protocol
requirement?


>
>    11.  The request MAY include a header with the name "Sec-WebSocket-
>>        Extensions".  If present, this value indicates the protocol-
>>        level extension(s) the client wishes to speak.  The
>>        interpretation and format of this header is described in
>>        Section 8.1.
>>  12.  The request MAY include headers associated with sending cookies,
>>        as defined by the appropriate specifications
>>        [I-D.ietf-httpstate-cookie].
>>
>
> Any cookies at random? I'd like, at least for browser clients, for this
> to be tighter, as it was in -00.
>

again, i need to sync with hixie on the cross-spec hooks.



>
>    Once the client's opening handshake has been sent, the client MUST
>>   wait for a response from the server before sending any further data.
>>   The client MUST validate the server's response as follows:
>>  o  If the status code received from the server is not 101, the client
>>      MUST fail the WebSocket connection.
>>  o  If the response lacks an Upgrade header or the Upgrade header
>>      contains a value that is not an ASCII case-insensitive match for
>>      the value "websocket", the client MUST fail the WebSocket
>>      connection.
>>  o  If the response lacks a Connection header or the Connection header
>>      contains a value that is not an ASCII case-insensitive match for
>>      the value "Upgrade", the client MUST fail the WebSocket
>>      connection.
>>  o  If the response lacks a Sec-WebSocket-Accept header or the Sec-
>>      WebSocket-Accept contains a value other than the base64-encoded
>>      SHA-1 of the concatenation of the Sec-WebSocket-Key (as a string,
>>      not base64-decoded) with the string "258EAFA5-E914-47DA-95CA-
>>      C5AB0DC85B11", the client MUST fail the WebSocket connection.
>>
>
> -00 had rules for failing the websocket connection if the response had
> certain other errors, like the wrong type of linebreaks. What's the
> deal now? I haven't reviewed the security implications, but there may
> be some if clients are tolerant in their parsing of the server's
> handshake.
>

The group had a big push towards "it's HTTP and is HTTP compatibile" so this
all got re-written... if it's valid HTTP then it's OK, if it's not then not
-- that was my interpretation...


>
>    Where the algorithm above requires that a user agent fail the
>>   WebSocket connection, the user agent may first read an arbitrary
>>   number of further bytes from the connection (and then discard them)
>>   before actually *failing the WebSocket connection*.  Similarly, if a
>>   user agent can show that the bytes read from the connection so far
>>   are such that there is no subsequent sequence of bytes that the
>>   server can send that would not result in the user agent being
>>   required to *fail the WebSocket connection*, the user agent may
>>   immediately *fail the WebSocket connection* without waiting for those
>>   bytes.
>>  NOTE: The previous paragraph is intended to make it conforming for
>>   user agents to implement the algorithm in subtly different ways that
>>   are equivalent in all ways except that they terminate the connection
>>   at earlier or later points.  For example, it enables an
>>   implementation to buffer the entire handshake response before
>>   checking it, or to verify each field as it is received rather than
>>   collecting all the fields and then checking them as a block.
>>
>
> It seems these two paragraphs aren't needed anymore when you don't have
> a detailed algorithm but just some bullet points.
>
>  5.2.  Server-side requirements
>>  _This section only applies to servers._
>>  Servers may offload the management of the connection to other agents
>>   on the network, for example load balancers and reverse proxies.  In
>>   such a situation, the server for the purposes of conformance is
>>   considered to include all parts of the server-side infrastructure
>>   from the first device to terminate the TCP connection all the way to
>>   the server that processes requests and sends responses.
>>  EXAMPLE: For example, a data center might have a server that responds
>>   to WebSocket requests with an appropriate handshake, and then passes
>>   the connection to another server to actually process the data frames.
>>   For the purposes of this specification, the "server" is the
>>   combination of both computers.
>> 5.2.1.  Reading the client's opening handshake
>>  When a client starts a WebSocket connection, it sends its part of 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.
>>  The client handshake consists of the following parts.  If the server,
>>   while reading the handshake, finds that the client did not send a
>>   handshake that matches the description below, the server must abort
>>   the WebSocket connection.
>>  1.  An HTTP/1.1 or higher GET request, including a "Request-URI"
>>       [RFC2616] that should be interpreted as a /resource name/
>>       Section 3.
>>  2.  A "Host" header containing the server's authority.
>>  3.  A "Sec-WebSocket-Key" header with a base64-encoded value that,
>>       when decoded, is 16 bytes in length.
>>  4.  A "Sec-WebSocket-Version" header, with a value of 6.
>>  5.  Optionally, a "Sec-WebSocket-Origin" header.  This header is sent
>>       by all browser clients.  A connection attempt lacking this header
>>       SHOULD NOT be interpreted as coming from a browser client.
>>  6.  Optionally, a "Sec-WebSocket-Protocol header, with a list of
>>       values indicating which protocols the client would like to speak,
>>       ordered by preference.
>>
>
> Missing quote.
>
> -00 was stricter about the Sec-WebSocket-Protocol header: if the algorithm
> was fed with an empty /subprotocols/ then the header must not be included,
> else the header must be included with the values of /subprotocols/. I prefer
> that over anything-goes "optinally".
>
>    7.  Optionally, a "Sec-WebSocket-Extensions" header, with a list of
>>       values indicating which extensions the client would like to
>>       speak.  The interpretation of this header is discussed in
>>       Section 8.1.
>>  8.  Optionally, other headers, such as those used to send cookies to
>>       a server.  Unknown headers MUST be ignored.
>> 5.2.2.  Sending the server's opening handshake
>>  When a client establishes a WebSocket connection to a server, the
>>   server must complete the following steps to accept the connection and
>>   send the server's opening handshake.
>>  1.  If the server supports encryption, perform a TLS handshake over
>>       the connection.  If this fails (e.g. the client indicated a host
>>
>
> If the server supports encryption? A bit unclear... if can support
> encryption but the requested URL might be ws:
>


will chat with hixie on cross-protocol things, frankly I hold firm that tls
with http:// is rather useless and i really don't worry about it for ws...



>
>        name in the extended client hello "server_name" extension that
>>       the server does not host), then close the connection; otherwise,
>>       all further communication for the connection (including the
>>       server handshake) must run through the encrypted tunnel.
>>       [RFC2246]
>>  2.  Establish the following information:
>>      /origin/
>>          The |Sec-WebSocket-Origin| header in the client's handshake
>>          indicates the origin of the script establishing the
>>          connection.  The origin is serialized to ASCII and converted
>>          to lowercase.  The server MAY use this information as part of
>>          a determination of whether to accept the incoming connection.
>>
>
> I'd like a warning here that if the server doesn't validate the origin,
> it means that it will accept connections from anywhere. Normally it's
> the browser's responsibility to enforce same-origin restrictions, but
> with websockets it's the server application developer's responsibility,
> and this needs to be pointed out explicitly IMHO.
>
> I see now that there's a paragraph discussing this in security
> considerations. I'd be happy with a pointer to security considerations
> here.
>

done


>
>        /key/
>>          The |Sec-WebSocket-Key| header in the client's handshake
>>          includes a base64-encoded value that, if decoded, is 16 bytes
>>          in length.  This (encoded) value is used in the creation of
>>          the server's handshake to indicate an acceptance of the
>>          connection.  It is not necessary for the server to base64-
>>          decode the Sec-WebSocket-Key value.
>>      /version/
>>          The |Sec-WebSocket-Version| header in the client's handshake
>>          includes the version of the WebSocket protocol the client is
>>          attempting to communicate with.  If this version does not
>>          match a version understood by the server, the server MUST
>>          abort the WebSocket connection.  The server MAY send a non-200
>>          response code with a |Sec-WebSocket-Version| header indicating
>>          the version(s) the server is capable of understanding along
>>          with this non-200 response code.
>>      /resource name/
>>          An identifier for the service provided by the server.  If the
>>          server provides multiple services, then the value should be
>>          derived from the resource name given in the client's handshake
>>          from the Request-URI [RFC2616] of the GET method.
>>      /subprotocol/
>>          A (possibly empty) list representing the subprotocol the
>>          server is ready to use.  If the server supports multiple
>>          subprotocols, then the value should be derived from the
>>          client's handshake, specifically by selecting one of the
>>          values from the "Sec-WebSocket-Protocol" field.  The absence
>>          of such a field is equivalent to the null value.  The empty
>>          string is not the same as the null value for these purposes.
>>      /extensions/
>>          A (possibly empty) list representing the protocol-level
>>          extensions the server is ready to use.  If the server supports
>>          multiple extensions, then the value should be derived from the
>>          client's handshake, specifically by selecting one or more of
>>          the values from the "Sec-WebSocket-Extensions" field.  The
>>          absence of such a field is equivalent to the null value.  The
>>          empty string is not the same as the null value for these
>>          purposes.  Extensions not listed by the client MUST NOT be
>>          listed.  The method by which these values should be selected
>>          and interpreted is discussed in Section 8.1.
>>  3.  If the server chooses to accept the incoming connection, it must
>>       reply with a valid HTTP response indicating the following.
>>      1.  A 101 response code.  Such a response could look like
>>           "HTTP/1.1 101 Switching Protocols"
>>      2.  A "Sec-WebSocket-Accept" header.  The value of this header is
>>           constructed by concatenating /key/, defined above in
>>           Paragraph 2 of Section 5.2.2, with the string "258EAFA5-E914-
>>           47DA-95CA-C5AB0DC85B11", taking the SHA-1 hash of this
>>           concatenated value to obtain a 20-byte value, and base64-
>>           encoding this 20-byte hash.
>>          NOTE: As an example, if the value of the "Sec-WebSocket-Key"
>>           header in the client's handshake were
>>           "dGhlIHNhbXBsZSBub25jZQ==", the server would append the
>>           string "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" to form the
>>           string "dGhlIHNhbXBsZSBub25jZQ==258EAFA5-E914-47DA-95CA-
>>           C5AB0DC85B11".  The server would then take the SHA-1 hash of
>>           this string, giving the value 0xb3 0x7a 0x4f 0x2c 0xc0 0x62
>>           0x4f 0x16 0x90 0xf6 0x46 0x06 0xcf 0x38 0x59 0x45 0xb2 0xbe
>>           0xc4 0xea.  This value is then base64-encoded, to give the
>>           value "s3pPLMBiTxaQ9kYGzzhZRbK+xOo=", which would be returned
>>           in the "Sec-WebSocket-Accept" header.
>>      3.  Optionally, a "Sec-WebSocket-Protocol" header, with a value
>>           /subprotocol/ as defined in Paragraph 2 of Section 5.2.2.
>>      4.  Optionally, a "Sec-WebSocket-Extensions" header, with a value
>>           /extensions/ as defined in Paragraph 2 of Section 5.2.2.
>>  This completes the server's handshake.  If the server finishes these
>>   steps without aborting the WebSocket connection, and if the client
>>   does not then fail the WebSocket connection, then the connection is
>>   established and the server may begin sending and receiving data, as
>>   described in the next section.
>>
>
> The next section doesn't describe sending and receiving data.
>


done



>
>  6.  Error Handling
>> 6.1.  Handling errors in UTF-8 from the server
>>  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 be
>>   interpreted as a U+FFFD REPLACEMENT CHARACTER.
>>
>
> Maybe use the HTML spec's definition of UTF-8 with error handling:
>
> http://www.whatwg.org/specs/web-apps/current-work/complete/infrastructure.html#decoded-as-utf-8,-with-error-handling
>
>  6.2.  Handling errors in UTF-8 from the client
>>  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, behavior is
>>   undefined.  A server could close the connection, convert invalid byte
>>   sequences to U+FFFD REPLACEMENT CHARACTERs, store the data verbatim,
>>   or perform application-specific processing.  Subprotocols layered on
>>   the WebSocket protocol might define specific behavior for servers.
>> 7.  Closing the connection
>> 7.1.  Definitions
>> 7.1.1.  Close the WebSocket Connection
>>  To _Close the WebSocket Connection_, an endpoint closes the
>>   underlying TCP connection.  An endpoint SHOULD use a method that
>>   cleanly closes the TCP connection, discarding any trailing bytes that
>>   may be received.  And endpoint MAY close the connection via any means
>>
>
> s/And/An/
>

done


>
>    available when necessary, such as when under attack.
>>  As an example of how to obtain a clean closure in C using Berkeley
>>   sockets, one would call shutdown() with SHUT_WR on the socket, call
>>   recv() until obtaining a return value of 0 indicating that the peer
>>   has also performed an orderly shutdown, and finally calling close()
>>   on the socket.
>>
>
> Hmm, this example seems a bit out of place.
>
>  7.1.2.  Start the WebSocket Closing Handshake
>>  To _start the WebSocket closing handshake_, and endpoint MUST send a
>>
>
> s/and/an/
>

done


>
>    Close control frame, as described in Section 4.5.1.  Upon receiving a
>>   Close control frame, the other party sends a Close control frame in
>>   response.  Once an endpoint has both sent and received a Close
>>   control frame, that endpoint should _Close the WebSocket Connection_
>>   as defined in Section 7.1.1.
>>
>
> Again this repeats the same requirements from 4.5.1, but subtly
> different, such that it's not clear which to follow. Please only have
> the same requirement once.
>


I removed what I think is duplicative and what remains is about the minimal
set.


>
>  7.1.3.  The WebSocket Connection Is Closed
>>  When the underlying TCP connection is closed, it is said that _the
>>   WebSocket connection is closed_.  If the tcp connection was closed
>>   after the WebSocket closing handshake was completed, the WebSocket
>>   connection is said to have been closed _cleanly_.
>> 7.1.4.  Fail the WebSocket Connection
>>  Certain algorithms and specifications require a user agent to _fail
>>   the WebSocket connection_.  To do so, the user agent must _Close the
>>   WebSocket Connection_, and MAY report the problem to the user (which
>>   would be especially useful for developers) in an appropriate manner.
>>  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.
>> 7.2.  Abnormal closures
>> 7.2.1.  Client-initiated closure
>>  Certain algorithms, namely during the initial handshake, require the
>>   user agent to *fail the WebSocket connection*.  To do so, the user
>>   agent must _Close the WebSocket connection_ as previously defined,
>>   and may report the problem to the user via an appropriate mechanism
>>   (which would be especially useful for developers).
>>  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.
>> 7.2.2.  Server-initiated closure
>>  Certain algorithms require or recommend that the server _abort the
>>   WebSocket connection_ during the opening handshake.  To do so, the
>>   server must simply _close the WebSocket connection_ (Section 7.1.1).
>> 7.3.  Normal closure of connections
>>  Servers MAY close the WebSocket connection whenever desired.  User
>>   agents SHOULD NOT close the WebSocket connection arbitrarily.  In
>>   either case, an endpoint initiates a closure by following the
>>   procedures to _start the WebSocket closing handshake_
>>   (Section 7.1.2).
>> 7.4.  Status codes
>>  When closing an established connection (e.g. when sending a Close
>>   frame, after the handshake has completed), an endpoint MAY indicate a
>>   reason for closure.  The interpretation of this reason by an
>>   endpoint, and the action an endpoint should take given this reason,
>>   are left undefined by this specification.  This specification defines
>>   a set of pre-defined status codes, and specifies which ranges may be
>>   used by extensions, frameworks, and end applications.  The status
>>   code and any associated textual message are optional components of a
>>   Close frame.
>> 7.4.1.  Defined Status Codes
>>  Endpoints MAY use the following pre-defined status codes when sending
>>   a Close frame.
>>  1000
>>     1000 indicates a normal closure, meaning whatever purpose the
>>      connection was established for has been fulfilled.
>>  1001
>>     1001 indicates that an endpoint is "going away", such as a server
>>      going down, or a browser having navigated away from a page.
>>  1002
>>     1002 indicates that an endpoint is terminating the connection due
>>      to a protocol error.
>>  1003
>>     1003 indicates that an endpoint is terminating the connection
>>      because it has received a type of data it cannot accept (e.g. an
>>      endpoint that understands only text data may send this if it
>>      receives a binary message.)
>>  1004
>>     1004 indicates that an endpoint is terminating the connection
>>      because it has received a message that is too large.
>> 7.4.2.  Reserved status code ranges
>>  0-999
>>     Status codes in the range 0-999 are not used.
>>  1000-1999
>>     Status codes in the range 1000-1999 are reserved for definition by
>>      this protocol.
>>  2000-2999
>>     Status codes in the range 2000-2999 are reserved for use by
>>      extensions.
>>  3000-3999
>>     Status codes in the range 3000-3999 MAY be used by libraries and
>>      frameworks.  The interpretation of these codes is undefined by
>>      this protocol.  End applications MUST NOT use status codes in this
>>      range.
>>  4000-4999
>>     Status codes in the range 4000-4999 MAY be used by application
>>      code.  The interpretaion of these codes is undefined by this
>>      protocol.
>> 8.  Extensions
>>  WebSocket clients MAY request extensions to this specification, and
>>   WebSocket servers MAY accept some or all extensions requested by the
>>   client.  A server MUST NOT respond with any extension not requested
>>   by the client.  If extension parameters are included in negotiations
>>   between the client and the server, those parameters MUST be chosen in
>>   accordance with the specification of the extension to which the
>>   parameters apply.
>> 8.1.  Negotiating extensions
>>  A client requests extensions by including a "Sec-WebSocket-
>>   Extensions" header, which follows the normal rules for HTTP headers
>>   (see [RFC2616] section 4.2) and the value of the header is defined by
>>   the following ABNF:
>>        extension-list = 1#extension
>>         extension = extension-token *( ";" extension-param )
>>         extension-token = registered-token | private-use-token
>>         registered-token = token
>>         private-use-token = "x-" token
>>         extension-param = token [ "=" ( token | quoted-string ) ]
>>  Note that like other HTTP headers, this header may be split or
>>   combined across multiple lines.  Ergo, the following are equivalent:
>>        Sec-WebSocket-Extensions: foo
>>         Sec-WebSocket-Extensions: bar; baz=2
>>  is exactly equivalent to
>>        Sec-WebSocket-Extensions: foo, bar; baz=2
>>  Any extension-token used must either be a registered token
>>   (registration TBD), or have a prefix of "x-" to indicate a private-
>>   use token.  The parameters supplied with any given extension MUST be
>>   defined for that extension.  Note that the client is only offering to
>>   use any advertised extensions, and MUST NOT use them unless the
>>   server accepts the extension.
>>  Note that the order of extensions is significant.  Any interactions
>>   between multiple extensions MAY be defined in the documents defining
>>   the extensions.  In the absence of such definition, the
>>   interpretation is that the headers listed by the client in its
>>   request represent a preference of the headers it wishes to use, with
>>   the first options listed being most preferable.  The extensions
>>   listed by the server in response represent the extensions actually in
>>   use.  Should the extensions modify the data and/or framing, the order
>>   of operations on the data should be assumed to be the same as the
>>   order in which the extensions are listed in the server's response in
>>   the opening handshake.
>>  For example, if there are two extensions "foo" and "bar", if the
>>   header |Sec-WebSocket-Extensions| sent by the server has the value
>>   "foo, bar" then operations on the data will be made as
>>   bar(foo(data)), be those changes to the data itself (such as
>>   compression) or changes to the framing thay may "stack".
>>  Non-normative examples of acceptable extension headers:
>>     Sec-WebSocket-Extensions: deflate-stream
>>      Sec-WebSocket-Extensions: mux; max-channels=4; flow-control,
>> deflate-stream
>>      Sec-WebSocket-Extensions: x-private-extension
>>  A server accepts one or more extensions by including a |Sec-
>>   WebSocket-Extensions| header containing one or more extensions which
>>   were requested by the client.  The interpretation of any extension
>>   parameters, and what constitutes a valid response by a server to a
>>   requested set of parameters by a client, will be defined by each such
>>   extension.
>> 8.2.  Known extensions
>>  Extensions provide a mechanism for implementations to opt-in to
>>   additional protocol features.  This section defines the meaning of
>>   well-known extensions but implementations may use extensions defined
>>   separately as well.
>> 8.2.1.  Compression
>>  The registered extension token for this compression extension is
>>   "deflate-stream".
>>  The extension does not have any per message extension data and it
>>   does not define the use of any WebSocket reserved bits or op codes.
>>  Senders using this extension MUST apply RFC 1951 encodings to all
>>   bytes of the data stream following the handshake including both data
>>   and control messages.  The data stream MAY include multiple blocks of
>>   both compressed and uncompressed types as defined by RFC 1951.
>>   [RFC1951]
>>  Senders MUST NOT delay the transmission of any portion of a WebSocket
>>   message because the deflate encoding of the message does not end on a
>>   byte boundary.  The encodings for adjacent messages MAY appear in the
>>   same byte if no delay in transmission is occurred by doing so.
>> 9.  Security considerations
>>  While this protocol is intended to be used by scripts in Web pages,
>>   it can also be used directly by hosts.  Such hosts are acting on
>>   their own behalf, and can therefore send fake "Origin" fields,
>>   misleading the server.  Servers should therefore be careful about
>>   assuming that they are talking directly to scripts from known
>>   origins, and must consider that they might be accessed in unexpected
>>   ways.  In particular, a server should not trust that any input is
>>   valid.
>>  EXAMPLE: For example, if the server uses input as part of SQL
>>   queries, all input text should be escaped before being passed to the
>>   SQL server, lest the server be susceptible to SQL injection.
>>  Servers that are not intended to process input from any Web page but
>>   only for certain sites should verify the "Origin" field is an origin
>>   they expect, and should only respond with the corresponding "Sec-
>>   WebSocket-Origin" if it is an accepted origin.  Servers that only
>>   accept input from one origin can just send back that value in the
>>   "Sec-WebSocket-Origin" field, without bothering to check the client's
>>   value.
>>
>>  If at any time a server is faced with data that it does not
>>   understand, or that violates some criteria by which the server
>>   determines safety of input, or when the server sees a handshake that
>>   does not correspond to the values the server is expecting (e.g.
>>   incorrect path or origin), the server should just disconnect.  It is
>>   always safe to disconnect.
>>  The biggest security risk when sending text data using this protocol
>>   is sending data using the wrong encoding.  If an attacker can trick
>>   the server into sending data encoded as ISO-8859-1 verbatim (for
>>   instance), rather than encoded as UTF-8, then the attacker could
>>   inject arbitrary frames into the data stream.
>>  In addition to endpoints being the target of attacks via WebSockets,
>>   other parts of web infrastructure, such as proxies, may be the
>>   subject of an attack.  In particular, an intermediary may interpret a
>>   WebSocket message from a client as a request, and a message from the
>>   server as a response to that request.  For instance, an attacker
>>   could get a browser to establish a connection to its server, get the
>>   browser to send a message that looks to an intermediary like a GET
>>   request for a common piece of JavaScript on another domain, and send
>>   back a message that is interpreted as a cacheable response to that
>>   request, thus poisioning the cache for other users.  To prevent this
>>   attack, messages sent from clients are masked on the wire with a 32-
>>   bit value, to prevent an attacker from controlling the bits on the
>>   wire and thus lessen the probability of an attacker being able to
>>   construct a message that can be misinterpreted by a proxy as a non-
>>   WebSocket request.
>> 10.  IANA considerations
>> 10.1.  Registration of ws: scheme
>>  A |ws:| URI identifies a WebSocket server and resource name.
>>  URI scheme name.
>>      ws
>>  Status.
>>      Permanent.
>>  URI scheme syntax.
>>      In ABNF terms using the terminals from the URI specifications:
>>      [RFC5234] [RFC3986]
>>          "ws" ":" hier-part [ "?" query ]
>>     The path and query components form the resource name sent to the
>>      server to identify the kind of service desired.  Other components
>>      have the meanings described in RFC3986.
>>  URI scheme semantics.
>>      The only operation for this scheme is to open a connection using
>>      the WebSocket protocol.
>>  Encoding considerations.
>>      Characters in the host component that are excluded by the syntax
>>      defined above must be converted from Unicode to ASCII by applying
>>      the IDNA ToASCII algorithm to the Unicode host name, with both the
>>      AllowUnassigned and UseSTD3ASCIIRules flags set, and using the
>>      result of this algorithm as the host in the URI.  [RFC3490]
>>     Characters in other components that are excluded by the syntax
>>      defined above must be converted from Unicode to ASCII by first
>>      encoding the characters as UTF-8 and then replacing the
>>      corresponding bytes using their percent-encoded form as defined in
>>      the URI and IRI specification.  [RFC3986] [RFC3987]
>>  Applications/protocols that use this URI scheme name.
>>      WebSocket protocol.
>>  Interoperability considerations.
>>      None.
>>  Security considerations.
>>      See "Security considerations" section above.
>>  Contact.
>>      Ian Hickson <ian@hixie.ch>
>>  Author/Change controller.
>>      Ian Hickson <ian@hixie.ch>
>>  References.
>>      This document.
>> 10.2.  Registration of wss: scheme
>>  A |wss:| URI identifies a WebSocket server and resource name, and
>>   indicates that traffic over that connection is to be encrypted.
>>  URI scheme name.
>>      wss
>>  Status.
>>      Permanent.
>>  URI scheme syntax.
>>      In ABNF terms using the terminals from the URI specifications:
>>      [RFC5234] [RFC3986]
>>          "wss" ":" hier-part [ "?" query ]
>>     The path and query components form the resource name sent to the
>>      server to identify the kind of service desired.  Other components
>>      have the meanings described in RFC3986.
>>  URI scheme semantics.
>>      The only operation for this scheme is to open a connection using
>>      the WebSocket protocol, encrypted using TLS.
>>  Encoding considerations.
>>      Characters in the host component that are excluded by the syntax
>>      defined above must be converted from Unicode to ASCII by applying
>>      the IDNA ToASCII algorithm to the Unicode host name, with both the
>>      AllowUnassigned and UseSTD3ASCIIRules flags set, and using the
>>      result of this algorithm as the host in the URI.  [RFC3490]
>>     Characters in other components that are excluded by the syntax
>>      defined above must be converted from Unicode to ASCII by first
>>      encoding the characters as UTF-8 and then replacing the
>>      corresponding bytes using their percent-encoded form as defined in
>>      the URI and IRI specification.  [RFC3986] [RFC3987]
>>  Applications/protocols that use this URI scheme name.
>>      WebSocket protocol over TLS.
>>  Interoperability considerations.
>>      None.
>>  Security considerations.
>>      See "Security considerations" section above.
>>  Contact.
>>      Ian Hickson <ian@hixie.ch>
>>  Author/Change controller.
>>      Ian Hickson <ian@hixie.ch>
>>  References.
>>      This document.
>> 10.3.  Registration of the "WebSocket" HTTP Upgrade keyword
>>  Name of token.
>>      WebSocket
>>  Author/Change controller.
>>      Ian Hickson <ian@hixie.ch>
>>  Contact.
>>      Ian Hickson <ian@hixie.ch>
>>  References.
>>      This document.
>> 10.4.  Sec-WebSocket-Key
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Key
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Key| header is used in the WebSocket handshake.
>>   It is sent from the client to the server to provide part of the
>>   information used by the server to prove that it received a valid
>>   WebSocket handshake.  This helps ensure that the server does not
>>   accept connections from non-WebSocket clients (e.g.  HTTP clients)
>>   that are being abused to send data to unsuspecting WebSocket servers.
>> 10.5.  Sec-WebSocket-Extensions
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Extensions
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Extensions| header is used in the WebSocket
>>   handshake.  It is initially sent from the client to the server, and
>>   then subsequently sent from the servver to the client, to agree on a
>>   set of protocol-level extensions to use during the connection.
>> 10.6.  Sec-WebSocket-Accept
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Accept
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Accept| header is used in the WebSocket handshake.
>>   It is sent from the server to the client to confirm that the server
>>   is willing to initiate the connection.
>> 10.7.  Sec-WebSocket-Origin
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Origin
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Origin| header is used in the WebSocket handshake.
>>   It is sent from the server to the client to confirm the origin of the
>>   script that opened the connection.  This enables user agents to
>>   verify that the server is willing to serve the script that opened the
>>   connection.
>> 10.8.  Sec-WebSocket-Protocol
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Protocol
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Protocol| header is used in the WebSocket
>>   handshake.  It is sent from the client to the server and back from
>>   the server to the client to confirm the subprotocol of the
>>   connection.  This enables scripts to both select a subprotocol and be
>>   sure that the server agreed to serve that subprotocol.
>> 10.9.  Sec-WebSocket-Version
>>  This section describes a header field for registration in the
>>   Permanent Message Header Field Registry.  [RFC3864]
>>  Header field name
>>      Sec-WebSocket-Version
>>  Applicable protocol
>>      http
>>  Status
>>      reserved; do not use outside WebSocket handshake
>>  Author/Change controller
>>      IETF
>>  Specification document(s)
>>      This document is the relevant specification.
>>  Related information
>>      None.
>>  The |Sec-WebSocket-Version| header is used in the WebSocket
>>   handshake.  It is sent from the client to the server to indicate the
>>   protocol version of the connection.  This enables servers to
>>   correctly interpret the handshake and subsequent data being sent from
>>   the data, and close the connection if the server cannot interpret
>>   that data in a safe manner.
>> 11.  Using the WebSocket protocol from other specifications
>>  The WebSocket protocol is intended to be used by another
>>   specification to provide a generic mechanism for dynamic author-
>>   defined content, e.g. in a specification defining a scripted API.
>>  Such a specification first needs to "establish a WebSocket
>>   connection", providing that algorithm with:
>>  o  The destination, consisting of a /host/ and a /port/.
>>  o  A /resource name/, which allows for multiple services to be
>>      identified at one host and port.
>>  o  A /secure/ flag, which is true if the connection is to be
>>      encrypted, and false otherwise.
>>  o  An ASCII serialization of an origin that is being made responsible
>>      for the connection.  [I-D.ietf-websec-origin]
>>  o  Optionally a string identifying a protocol that is to be layered
>>      over the WebSocket connection.
>>  The /host/, /port/, /resource name/, and /secure/ flag are usually
>>   obtained from a URI using the steps to parse a WebSocket URI's
>>   components.  These steps fail if the URI does not specify a
>>   WebSocket.
>>  If a connection can be established, then it is said that the
>>   "WebSocket connection is established".
>>  If at any time the connection is to be closed, then the specification
>>   needs to use the "close the WebSocket connection" algorithm.
>>  When the connection is closed, for any reason including failure to
>>   establish the connection in the first place, it is said that the
>>   "WebSocket connection is closed".
>>  While a connection is open, the specification will need to handle the
>>   cases when "a WebSocket message has been received" with text /data/.
>>  To send some text /data/ to an open connection, the specification
>>   needs to "send /data/ using the WebSocket".
>>
>
> --
> Simon Pieters
> Opera Software
> _______________________________________________
> hybi mailing list
> hybi@ietf.org
> https://www.ietf.org/mailman/listinfo/hybi
>