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 >
- [hybi] Opera's Pre-Last Call review of websocket … Simon Pieters
- Re: [hybi] Opera's Pre-Last Call review of websoc… Julian Reschke
- Re: [hybi] Opera's Pre-Last Call review of websoc… Julian Reschke
- Re: [hybi] Opera's Pre-Last Call review of websoc… Ian Fette (イアンフェッティ)
- Re: [hybi] Opera's Pre-Last Call review of websoc… Simon Pieters
- Re: [hybi] Opera's Pre-Last Call review of websoc… Simon Pieters