idnits 2.17.1 draft-hixie-thewebsocketprotocol-10.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- ** The document seems to lack a License Notice according IETF Trust Provisions of 28 Dec 2009, Section 6.b.ii or Provisions of 12 Sep 2009 Section 6.b -- however, there's a paragraph with a matching beginning. Boilerplate error? (You're using the IETF Trust Provisions' Section 6.b License Notice from 12 Feb 2009 rather than one of the newer Notices. See https://trustee.ietf.org/license-info/.) Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([HTML5]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document doesn't use any RFC 2119 keywords, yet has text resembling RFC 2119 boilerplate text. -- The document date (April 24, 2009) is 5473 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Possible downref: Non-RFC (?) normative reference: ref. 'HTML5' ** Obsolete normative reference: RFC 2109 (Obsoleted by RFC 2965) ** Obsolete normative reference: RFC 2246 (Obsoleted by RFC 4346) ** Obsolete normative reference: RFC 2616 (Obsoleted by RFC 7230, RFC 7231, RFC 7232, RFC 7233, RFC 7234, RFC 7235) ** Obsolete normative reference: RFC 2965 (Obsoleted by RFC 6265) Summary: 6 errors (**), 0 flaws (~~), 2 warnings (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group I. Hickson 3 Internet-Draft Google, Inc. 4 Intended status: Standards Track April 24, 2009 5 Expires: October 26, 2009 7 The Web Socket protocol 8 draft-hixie-thewebsocketprotocol-10 10 Status of this Memo 12 This Internet-Draft is submitted to IETF in full conformance with the 13 provisions of BCP 78 and BCP 79. 15 Internet-Drafts are working documents of the Internet Engineering 16 Task Force (IETF), its areas, and its working groups. Note that 17 other groups may also distribute working documents as Internet- 18 Drafts. 20 Internet-Drafts are draft documents valid for a maximum of six months 21 and may be updated, replaced, or obsoleted by other documents at any 22 time. It is inappropriate to use Internet-Drafts as reference 23 material or to cite them other than as "work in progress." 25 The list of current Internet-Drafts can be accessed at 26 http://www.ietf.org/ietf/1id-abstracts.txt. 28 The list of Internet-Draft Shadow Directories can be accessed at 29 http://www.ietf.org/shadow.html. 31 This Internet-Draft will expire on October 26, 2009. 33 Copyright Notice 35 Copyright (c) 2009 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents in effect on the date of 40 publication of this document (http://trustee.ietf.org/license-info). 41 Please review these documents carefully, as they describe your rights 42 and restrictions with respect to this document. 44 Abstract 46 This protocol enables two-way communication between a user agent 47 running untrusted code running in a controlled environment to a 48 remote host that understands the protocol. It is intended to fail to 49 communicate with servers of pre-existing protocols like SMTP or HTTP, 50 while allowing HTTP servers to opt-in to supporting this protocol if 51 desired. It is designed to be easy to implement on the server side. 53 Author's note 55 This document is automatically generated from, and is therefore a 56 subset of, the HTML5 specification produced by the WHATWG. [HTML5] 58 Table of Contents 60 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 61 2. Conformance requirements . . . . . . . . . . . . . . . . . . . 5 62 3. Client-side requirements . . . . . . . . . . . . . . . . . . . 6 63 3.1. Handshake . . . . . . . . . . . . . . . . . . . . . . . . 6 64 3.2. Data framing . . . . . . . . . . . . . . . . . . . . . . . 12 65 4. Server-side requirements . . . . . . . . . . . . . . . . . . . 15 66 4.1. Minimal handshake . . . . . . . . . . . . . . . . . . . . 15 67 4.2. Handshake details . . . . . . . . . . . . . . . . . . . . 15 68 4.3. Data framing . . . . . . . . . . . . . . . . . . . . . . . 16 69 5. Closing the connection . . . . . . . . . . . . . . . . . . . . 18 70 6. Security considerations . . . . . . . . . . . . . . . . . . . 19 71 7. IANA considerations . . . . . . . . . . . . . . . . . . . . . 20 72 8. Normative References . . . . . . . . . . . . . . . . . . . . . 21 73 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 22 75 1. Introduction 77 ** ISSUE ** ... 79 2. Conformance requirements 81 All diagrams, examples, and notes in this specification are non- 82 normative, as are all sections explicitly marked non-normative. 83 Everything else in this specification is normative. 85 The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", 86 "RECOMMENDED", "MAY", and "OPTIONAL" in the normative parts of this 87 document are to be interpreted as described in RFC2119. For 88 readability, these words do not appear in all uppercase letters in 89 this specification. [RFC2119] 91 Requirements phrased in the imperative as part of algorithms (such as 92 "strip any leading space characters" or "return false and abort these 93 steps") are to be interpreted with the meaning of the key word 94 ("must", "should", "may", etc) used in introducing the algorithm. 96 Conformance requirements phrased as algorithms or specific steps may 97 be implemented in any manner, so long as the end result is 98 equivalent. (In particular, the algorithms defined in this 99 specification are intended to be easy to follow, and not intended to 100 be performant.) 102 Implementations may impose implementation-specific limits on 103 otherwise unconstrained inputs, e.g. to prevent denial of service 104 attacks, to guard against running out of memory, or to work around 105 platform-specific limitations. 107 The conformance classes defined by this specification are user agents 108 and servers. 110 3. Client-side requirements 112 _This section only applies to user agents, not to servers._ 114 NOTE: This specification doesn't currently define a limit to the 115 number of simultaneous connections that a client can establish to a 116 server. 118 3.1. Handshake 120 When the user agent is to *establish a Web Socket connection* to a 121 host /host/, optionally on port /port/, from an origin /origin/, with 122 a flag /secure/, with a particular /resource name/, and optionally 123 with a particular /protocol/, it must run the following steps. 125 NOTE: The /host/ and /origin/ strings will be all-lowercase when this 126 algorithm is invoked. 128 1. If there is no explicit /port/, then: if /secure/ is false, let 129 /port/ be 81, otherwise let /port/ be 815. 131 2. If the user agent is configured to use a proxy to connect to 132 host /host/ and/or port /port/, then connect to that proxy and 133 ask it to open a TCP/IP connection to the host given by /host/ 134 and the port given by /port/. 136 EXAMPLE: For example, if the user agent uses an HTTP proxy 137 for all traffic, then if it was to try to connect to port 80 138 on server example.com, it might send the following lines to 139 the proxy server: 141 CONNECT example.com HTTP/1.1 143 If there was a password, the connection might look like: 145 CONNECT example.com HTTP/1.1 146 Proxy-authorization: Basic ZWRuYW1vZGU6bm9jYXBlcyE= 148 Otherwise, if the user agent is not configured to use a proxy, 149 then open a TCP/IP connection to the host given by /host/ and 150 the port given by /port/. 152 3. If the connection could not be opened, then fail the Web Socket 153 connection and abort these steps. 155 4. If /secure/ is true, perform a TLS handshake over the 156 connection. If this fails (e.g. the server's certificate could 157 not be verified), then fail the Web Socket connection and abort 158 these steps. Otherwise, all further communication on this 159 channel must run through the encrypted tunnel. [RFC2246] 161 5. Send the following bytes to the remote side (the server): 163 47 45 54 20 165 Send the /resource name/ value, encoded as US-ASCII. 167 Send the following bytes: 169 20 48 54 54 50 2f 31 2e 31 0d 0a 55 70 67 72 61 170 64 65 3a 20 57 65 62 53 6f 63 6b 65 74 0d 0a 43 171 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 61 172 64 65 0d 0a 174 NOTE: The string "GET ", the path, " HTTP/1.1", CRLF, the string 175 "Upgrade: WebSocket", CRLF, and the string "Connection: 176 Upgrade", CRLF. 178 6. Send the following bytes: 180 48 6f 73 74 3a 20 182 Send the /host/ value, encoded as US-ASCII. 184 Send the following bytes: 186 0d 0a 188 NOTE: The string "Host: ", the host, and CRLF. 190 7. Send the following bytes: 192 4f 72 69 67 69 6e 3a 20 194 Send the /origin/ value, encoded as US-ASCII. 196 NOTE: The /origin/ value is a string that was passed to this 197 algorithm. 199 Send the following bytes: 201 0d 0a 203 NOTE: The string "Origin: ", the origin, and CRLF. 205 8. If there is no /protocol/, then skip this step. 207 Othewrise, send the following bytes: 209 57 65 62 53 6f 63 6b 65 74 2d 50 72 6f 74 6f 63 210 6f 6c 3a 20 212 Send the /protocol/ value, encoded as US-ASCII. 214 Send the following bytes: 216 0d 0a 218 NOTE: The string "WebSocket-Protocol: ", the protocol, and CRLF. 220 9. If the client has any authentication information or cookies that 221 would be relevant to a resource accessed over HTTP, if /secure/ 222 is false, or HTTPS, if it is true, on host /host/, port /port/, 223 with /resource name/ as the path (and possibly query 224 parameters), then HTTP headers that would be appropriate for 225 that information should be sent at this point. [RFC2616] 226 [RFC2109] [RFC2965] 228 Each header must be on a line of its own (each ending with a CR 229 LF sequence). For the purposes of this step, each header must 230 not be split into multiple lines (despite HTTP otherwise 231 allowing this with continuation lines). 233 EXAMPLE: For example, if the server had a username and 234 password that applied to |http://example.com/socket|, and the 235 Web Socket was being opened to |ws://example.com:80/socket|, 236 it could send them: 238 Authorization: Basic d2FsbGU6ZXZl 240 However, it would not send them if the Web Socket was being 241 opened to |ws://example.com/socket|, as that uses a different 242 port (81, not 80). 244 10. Send the following bytes: 246 0d 0a 248 NOTE: Just a CRLF (a blank line). 250 11. Read the first 85 bytes from the server. If the connection 251 closes before 85 bytes are received, or if the first 85 bytes 252 aren't exactly equal to the following bytes, then fail the Web 253 Socket connection and abort these steps. 255 48 54 54 50 2f 31 2e 31 20 31 30 31 20 57 65 62 256 20 53 6f 63 6b 65 74 20 50 72 6f 74 6f 63 6f 6c 257 20 48 61 6e 64 73 68 61 6b 65 0d 0a 55 70 67 72 258 61 64 65 3a 20 57 65 62 53 6f 63 6b 65 74 0d 0a 259 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 260 61 64 65 0d 0a 262 NOTE: The string "HTTP/1.1 101 Web Socket Protocol Handshake", 263 CRLF, the string "Upgrade: WebSocket", CRLF, the string 264 "Connection: Upgrade", CRLF. 266 12. Let /headers/ be a list of name-value pairs, initially empty. 268 13. _Header_: Let /name/ and /value/ be empty byte arrays. 270 14. Read a byte from the server. 272 If the connection closes before this byte is received, then fail 273 the Web Socket connection and abort these steps. 275 Otherwise, handle the byte as described in the appropriate entry 276 below: 278 -> If the byte is 0x0d (ASCII CR) 279 If the /name/ byte array is empty, then jump to the headers 280 processing step. Otherwise, fail the Web Socket connection 281 and abort these steps. 283 -> If the byte is 0x0a (ASCII LF) 284 Fail the Web Socket connection and abort these steps. 286 -> If the byte is 0x3a (ASCII ":") 287 Move on to the next step. 289 -> If the byte is in the range 0x41 .. 0x5a (ASCII "A" .. "Z") 290 Append a byte whose value is the byte's value plus 0x20 to 291 the /name/ byte array and redo this step for the next byte. 293 -> Otherwise 294 Append the byte to the /name/ byte array and redo this step 295 for the next byte. 297 NOTE: This reads a header name, terminated by a colon, 298 converting upper-case ASCII letters to lowercase, and aborting 299 if a stray CR or LF is found. 301 15. Read a byte from the server. 303 If the connection closes before this byte is received, then fail 304 the Web Socket connection and abort these steps. 306 Otherwise, handle the byte as described in the appropriate entry 307 below: 309 -> If the byte is 0x20 (ASCII space) 310 Ignore the byte and move on to the next step. 312 -> Otherwise 313 Treat the byte as described by the list in the next step, 314 then move on to that next step for real. 316 NOTE: This skips past a space character after the colon, if 317 necessary. 319 16. Read a byte from the server. 321 If the connection closes before this byte is received, then fail 322 the Web Socket connection and abort these steps. 324 Otherwise, handle the byte as described in the appropriate entry 325 below: 327 -> If the byte is 0x0d (ASCII CR) 328 Move on to the next step. 330 -> If the byte is 0x0a (ASCII LF) 331 Fail the Web Socket connection and abort these steps. 333 -> Otherwise 334 Append the byte to the /name/ byte array and redo this step 335 for the next byte. 337 NOTE: This reads a header value, terminated by a CRLF. 339 17. Read a byte from the server. 341 If the connection closes before this byte is received, or if the 342 byte is not a 0x0a byte (ASCII LF), then fail the Web Socket 343 connection and abort these steps. 345 NOTE: This skips past the LF byte of the CRLF after the header. 347 18. Append an entry to the /headers/ list that has the name given by 348 the string obtained by interpreting the /name/ byte array as a 349 UTF-8 byte stream and the value given by the string obtained by 350 interpreting the /value/ byte array as a UTF-8 byte stream. 352 19. Return to the "Header" step above. 354 20. _Headers processing_: If there is not exactly one entry in the 355 /headers/ list whose name is "websocket-origin", or if there is 356 not exactly one entry in the /headers/ list whose name is 357 "websocket-location", or if the /protocol/ was specified but 358 there is not exactly one entry in the /headers/ list whose name 359 is "websocket-protocol", or if there are any entries in the 360 /headers/ list whose names are the empty string, then fail the 361 Web Socket connection and abort these steps. 363 21. Read a byte from the server. 365 If the connection closes before this byte is received, or if the 366 byte is not a 0x0a byte (ASCII LF), then fail the Web Socket 367 connection and abort these steps. 369 NOTE: This skips past the LF byte of the CRLF after the blank 370 line after the headers. 372 22. Handle each entry in the /headers/ list as follows: 374 -> If the entry's name is "websocket-origin|" 375 If the value is not exactly equal to /origin/, converted to 376 lowercase, then fail the Web Socket connection and abort 377 these steps. 379 -> If the entry's name is "websocket-location|" 380 If the value is not exactly equal to a string consisting of 381 the following components in the same order, then fail the Web 382 Socket connection and abort these steps: 384 1. The string "ws" if /secure/ is false and "wss" if 385 /secure/ is true 387 2. The three characters "://". 389 3. The value of /host/. 391 4. If /secure/ is false and /port/ is not 81, or if /secure/ 392 is true and /port/ is not 815: a ":" character followed 393 by the value of /port/. 395 5. The value of /resource name/. 397 -> If the entry's name is "websocket-protocol|" 398 If there was a /protocol/ specified, and the value is not 399 exactly equal to /protocol/, then fail the Web Socket 400 connection and abort these steps. (If no /protocol/ was 401 specified, the header is ignored.) 403 -> If the entry's name is "set-cookie|" or "set-cookie2|" or 404 another cookie-related header name 405 Handle the cookie as defined by the appropriate spec, with 406 the resource being the one with the host /host/, the port 407 /port/, the path (and possibly query parameters) /resource 408 name/, and the scheme |http| if /secure/ is false and |https| 409 if /secure/ is true. [RFC2109] [RFC2965] 411 -> Any other name 412 Ignore it. 414 23. The *Web Socket connection is established*. Now the user agent 415 must send and receive to and from the connection as described in 416 the next section. 418 To *fail the Web Socket connection*, the user agent must close the 419 Web Socket connection, and may report the problem to the user (which 420 would be especially useful for developers). However, user agents 421 must not convey the failure information to the script that attempted 422 the connection in a way distinguishable from the Web Socket being 423 closed normally. 425 3.2. Data framing 427 Once a Web Socket connection is established, the user agent must run 428 through the following state machine for the bytes sent by the server. 430 1. Try to read a byte from the server. Let /frame type/ be that 431 byte. 433 If no byte could be read because the Web Socket connection is 434 closed, then abort. 436 2. Handle the /frame type/ byte as follows: 438 If the high-order bit of the /frame type/ byte is set (i.e. if 439 /frame type/ _and_ed with 0x80 returns 0x80) 440 Run these steps. If at any point during these steps a read is 441 attempted but fails because the Web Socket connection is 442 closed, then abort. 444 1. Let /length/ be zero. 446 2. _Length_: Read a byte, let /b/ be that byte. 448 3. Let /b_v/ be integer corresponding to the low 7 bits of 449 /b/ (the value you would get by _and_ing /b/ with 0x7f). 451 4. Multiply /length/ by 128, add /b_v/ to that result, and 452 store the final result in /length/. 454 5. If the high-order bit of /b/ is set (i.e. if /b/ _and_ed 455 with 0x80 returns 0x80), then return to the step above 456 labeled _length_. 458 6. Read /length/ bytes. 460 7. Discard the read bytes. 462 If the high-order bit of the /frame type/ byte is _not_ set (i.e. 463 if /frame type/ _and_ed with 0x80 returns 0x00) 464 Run these steps. If at any point during these steps a read is 465 attempted but fails because the Web Socket connection is 466 closed, then abort. 468 1. Let /raw data/ be an empty byte array. 470 2. _Data_: Read a byte, let /b/ be that byte. 472 3. If /b/ is not 0xff, then append /b/ to /raw data/ and 473 return to the previous step (labeled _data_). 475 4. Interpret /raw data/ as a UTF-8 string, and store that 476 string in /data/. 478 5. If /frame type/ is 0x00, then *a message has been 479 received* with text /data/. Otherwise, discard the data. 481 3. Return to the first step to read the next byte. 483 If the user agent is faced with content that is too large to be 484 handled appropriately, then it must fail the Web Socket connection. 486 Once a Web Socket connection is established, the user agent must use 487 the following steps to *send /data/ using the Web Socket*: 489 1. Send a 0x00 byte to the server. 491 2. Encode /data/ using UTF-8 and send the resulting byte stream to 492 the server. 494 3. Send a 0xff byte to the server. 496 4. Server-side requirements 498 _This section only applies to servers._ 500 4.1. Minimal handshake 502 NOTE: This section describes the minimal requirements for a server- 503 side implementation of Web Sockets. 505 Listen on a port for TCP/IP. Upon receiving a connection request, 506 open a connection and send the following bytes back to the client: 508 48 54 54 50 2f 31 2e 31 20 31 30 31 20 57 65 62 509 20 53 6f 63 6b 65 74 20 50 72 6f 74 6f 63 6f 6c 510 20 48 61 6e 64 73 68 61 6b 65 0d 0a 55 70 67 72 511 61 64 65 3a 20 57 65 62 53 6f 63 6b 65 74 0d 0a 512 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 55 70 67 72 513 61 64 65 0d 0a 515 Send the string "WebSocket-Origin" followed by a U+003A COLON (":") 516 followed by the ASCII serialization of the origin from which the 517 server is willing to accept connections, followed by a CRLF pair 518 (0x0d 0x0a). 520 For instance: 522 WebSocket-Origin: http://example.com 524 Send the string "WebSocket-Location" followed by a U+003A COLON (":") 525 followed by the URL of the Web Socket script, followed by a CRLF pair 526 (0x0d 0x0a). 528 For instance: 530 WebSocket-Location: ws://example.com:80/demo 532 Send another CRLF pair (0x0d 0x0a). 534 Read (and discard) data from the client until four bytes 0x0d 0x0a 535 0x0d 0x0a are read. 537 If the connection isn't dropped at this point, go to the data framing 538 section. 540 4.2. Handshake details 542 The previous section ignores the data that is transmitted by the 543 client during the handshake. 545 The data sent by the client consists of a number of fields separated 546 by CR LF pairs (bytes 0x0d 0x0a). 548 The first field consists of three tokens separated by space 549 characters (byte 0x20). The middle token is the path being opened. 550 If the server supports multiple paths, then the server should echo 551 the value of this field in the initial handshake, as part of the URL 552 given on the |WebSocket-Location| line (after the appropriate scheme 553 and host). 555 The remaining fields consist of name-value pairs, with the name part 556 separated from the value part by a colon and a space (bytes 0x3a 557 0x20). Of these, several are interesting: 559 Host (bytes 48 6f 73 74) 560 The value gives the hostname that the client intended to use when 561 opening the Web Socket. It would be of interest in particular to 562 virtual hosting environments, where one server might serve 563 multiple hosts, and might therefore want to return different data. 565 The right host has to be output as part of the URL given on the 566 |WebSocket-Location| line of the handshake described above, to 567 verify that the server knows that it is really representing that 568 host. 570 Origin (bytes 4f 72 69 67 69 6e) 571 The value gives the scheme, hostname, and port (if it's not the 572 default port for the given scheme) of the page that asked the 573 client to open the Web Socket. It would be interesting if the 574 server's operator had deals with operators of other sites, since 575 the server could then decide how to respond (or indeed, _whether_ 576 to respond) based on which site was requesting a connection. 578 If the server supports connections from more than one origin, then 579 the server should echo the value of this field in the initial 580 handshake, on the |WebSocket-Origin| line. 582 Other fields 583 Other fields can be used, such as "Cookie" or "Authorization", for 584 authentication purposes. 586 4.3. Data framing 588 NOTE: This section only describes how to handle content that this 589 specification allows user agents to send (text). It doesn't handle 590 any arbitrary content in the same way that the requirements on user 591 agents defined earlier handle any content including possible future 592 extensions to the protocols. 594 The server should run through the following steps to process the 595 bytes sent by the client: 597 1. Read a byte from the client. Assuming everything is going 598 according to plan, it will be a 0x00 byte. Behavior for the 599 server is undefined if the byte is not 0x00. 601 2. Let /raw data/ be an empty byte array. 603 3. _Data_: Read a byte, let /b/ be that byte. 605 4. If /b/ is not 0xff, then append /b/ to /raw data/ and return to 606 the previous step (labeled _data_). 608 5. Interpret /raw data/ as a UTF-8 string, and apply whatever 609 server-specific processing should occur for the resulting string. 611 6. Return to the first step to read the next byte. 613 The server should run through the following steps to send strings to 614 the client: 616 1. Send a 0x00 byte to the client to indicate the start of a string. 618 2. Encode /data/ using UTF-8 and send the resulting byte stream to 619 the client. 621 3. Send a 0xff byte to the client to indicate the end of the 622 message. 624 5. Closing the connection 626 To *close the Web Socket connection*, either the user agent or the 627 server closes the TCP/IP connection. There is no closing handshake. 628 Whether the user agent or the server closes the connection, it is 629 said that the *Web Socket connection is closed*. 631 Servers may close the Web Socket connection whenever desired. 633 User agents should not close the Web Socket connection arbitrarily. 635 6. Security considerations 637 ** ISSUE ** ... 639 7. IANA considerations 641 ** ISSUE ** ...(two URI schemes, two ports, HTTP Upgrade keyword) 643 8. Normative References 645 [HTML5] Hickson, I., "HTML5", April 2009. 647 [RFC2109] Kristol, D. and L. Montulli, "HTTP State Management 648 Mechanism", RFC 2109, February 1997. 650 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 651 Requirement Levels", BCP 14, RFC 2119, March 1997. 653 [RFC2246] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0", 654 RFC 2246, January 1999. 656 [RFC2616] Fielding, R., Gettys, J., Mogul, J., Frystyk, H., 657 Masinter, L., Leach, P., and T. Berners-Lee, "Hypertext 658 Transfer Protocol -- HTTP/1.1", RFC 2616, June 1999. 660 [RFC2965] Kristol, D. and L. Montulli, "HTTP State Management 661 Mechanism", RFC 2965, October 2000. 663 Author's Address 665 Ian Hickson 666 Google, Inc. 668 Email: ian@hixie.ch 669 URI: http://ln.hixie.ch/