idnits 2.17.1 draft-ietf-hybi-permessage-compression-06.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. 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 : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (March 13, 2013) is 4063 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. 'LZ77' Summary: 0 errors (**), 0 flaws (~~), 1 warning (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 HyBi Working Group T. Yoshino 3 Internet-Draft Google, Inc. 4 Intended status: Standards Track March 13, 2013 5 Expires: September 14, 2013 7 Compression Extensions for WebSocket 8 draft-ietf-hybi-permessage-compression-06 10 Abstract 12 This document specifies a framework for creating WebSocket extensions 13 that add compression functionality to the WebSocket Protocol. 14 Extensions based on this framework compress the payload data portion 15 of non-control WebSocket messages on per-message basis using a 16 specified compression algorithm. One reserved bit RSV1 in the 17 WebSocket frame header is allocated to control application of 18 compression for each message. This document also specifies one 19 specific compression extension using the DEFLATE algorithm. 21 Please send feedback to the hybi@ietf.org mailing list. 23 Status of this Memo 25 This Internet-Draft is submitted to IETF in full conformance with the 26 provisions of BCP 78 and BCP 79. 28 Internet-Drafts are working documents of the Internet Engineering 29 Task Force (IETF). Note that other groups may also distribute 30 working documents as Internet-Drafts. The list of current Internet- 31 Drafts is at http://datatracker.ietf.org/drafts/current. 33 Internet-Drafts are draft documents valid for a maximum of six months 34 and may be updated, replaced, or obsoleted by other documents at any 35 time. It is inappropriate to use Internet-Drafts as reference 36 material or to cite them other than as "work in progress." 38 This Internet-Draft will expire on September 14, 2013. 40 Copyright Notice 42 Copyright (c) 2013 IETF Trust and the persons identified as the 43 document authors. All rights reserved. 45 This document is subject to BCP 78 and the IETF Trust's Legal 46 Provisions Relating to IETF Documents 47 (http://trustee.ietf.org/license-info) in effect on the date of 48 publication of this document. Please review these documents 49 carefully, as they describe your rights and restrictions with respect 50 to this document. Code Components extracted from this document must 51 include Simplified BSD License text as described in Section 4.e of 52 the Trust Legal Provisions and are provided without warranty as 53 described in the Simplified BSD License. 55 Table of Contents 57 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 58 2. Conformance Requirements and Terminology . . . . . . . . . . . 4 59 3. WebSocket Per-message Compression Extension . . . . . . . . . 5 60 4. Extension Negotiation . . . . . . . . . . . . . . . . . . . . 6 61 4.1. Negotiation Examples . . . . . . . . . . . . . . . . . . . 6 62 5. Framing . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 63 5.1. Sending . . . . . . . . . . . . . . . . . . . . . . . . . 8 64 5.2. Receiving . . . . . . . . . . . . . . . . . . . . . . . . 8 65 6. permessage-deflate extension . . . . . . . . . . . . . . . . . 9 66 6.1. Method Parameters . . . . . . . . . . . . . . . . . . . . 10 67 6.1.1. Context Takeover Control . . . . . . . . . . . . . . . 10 68 6.1.2. Limiting the LZ77 sliding window size . . . . . . . . 10 69 6.1.3. Example . . . . . . . . . . . . . . . . . . . . . . . 11 70 6.2. Payload Data Transformation . . . . . . . . . . . . . . . 12 71 6.2.1. Compression . . . . . . . . . . . . . . . . . . . . . 12 72 6.2.2. Decompression . . . . . . . . . . . . . . . . . . . . 13 73 6.2.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 14 74 6.3. Intermediaries . . . . . . . . . . . . . . . . . . . . . . 17 75 6.4. Implementation Notes . . . . . . . . . . . . . . . . . . . 17 76 7. Security Considerations . . . . . . . . . . . . . . . . . . . 18 77 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 19 78 8.1. Registration of the "permessage-deflate" WebSocket 79 Extension Name . . . . . . . . . . . . . . . . . . . . . . 19 80 8.2. Registration of the "Per-message Compressed" WebSocket 81 Framing Header Bit . . . . . . . . . . . . . . . . . . . . 19 82 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 20 83 10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21 84 10.1. Normative References . . . . . . . . . . . . . . . . . . . 21 85 10.2. Informative References . . . . . . . . . . . . . . . . . . 21 86 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 22 88 1. Introduction 90 This document specifies a framework to apply a compression algorithm 91 to octets exchanged over the WebSocket Protocol [RFC6455]. This 92 framework uses the extension concept for the WebSocket Protocol is 93 introduced in the Section 9 of [RFC6455]. By specifying basic 94 extension negotiation process excluding algorithm specific extension 95 parameters in detail and a general method of transforming contents of 96 WebSocket messages using a compression algorithm, this framework 97 allows us to define WebSocket Per-message Compression Extensions 98 (PMCEs) to the WebSocket Protocol individually for various 99 compression algorithms. A WebSocket client and a WebSocket server 100 negotiate use of a PMCE and determines parameters to configure the 101 compression algorithm during the WebSocket opening handshake. The 102 client and server then exchange non-control messages using frames 103 with compressed data in the payload data portion. Documents 104 specifying individual PMCEs describe how to negotiate parameters and 105 how to transform octets in the payload data portion. A WebSocket 106 client may offer multiple PMCEs during the WebSocket opening 107 handshake. The WebSocket server received those offers may choose and 108 accept preferred one from them. PMCEs use the RSV1 bit of the 109 WebSocket frame header to indicate whether the message is compressed 110 or not, so that we can choose not to compress messages with 111 incompressible contents. 113 This document also specifies one specific PMCE based on the DEFLATE 114 [RFC1951] algorithm. The extension name of the PMCE is "permessage- 115 deflate". We chose the DEFLATE since it's widely available as a 116 library on various platforms and the overhead of the DEFLATE is 117 small. To align the end of compressed data to octet boundary, this 118 extension uses the algorithm described in the Section 2.1 of the PPP 119 Deflate Protocol [RFC1979]. Endpoints can take over the LZ77 sliding 120 window [LZ77] used to build frames for previous messages to get 121 better compression ratio. For resource-limited devices, this 122 extension provides parameters to limit memory usage for compression 123 context. 125 2. Conformance Requirements and Terminology 127 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 128 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 129 document are to be interpreted as described in [RFC2119]. 131 Requirements phrased in the imperative as part of algorithms (such as 132 "strip any leading space characters" or "return false and abort these 133 steps") are to be interpreted with the meaning of the key word 134 ("MUST", "SHOULD", "MAY", etc.) used in introducing the algorithm. 136 Conformance requirements phrased as algorithms or specific steps can 137 be implemented in any manner, so long as the end result is 138 equivalent. In particular, the algorithms defined in this 139 specification are intended to be easy to understand and are not 140 intended to be performant. 142 This document references the procedure to _Fail the WebSocket 143 Connection_. This procedure is defined in the Section 7.1.7 of 144 [RFC6455]. 146 This document references the event that _the WebSocket Connection is 147 established_. This event is defined in the Section 4.1 of [RFC6455]. 149 This document uses the Argumented Backus-Naur Form (ABNF) notation of 150 [RFC5234]. The DIGIT (decimal 0-9) rule is included by reference, as 151 defined in the Appendix B.1 of [RFC5234]. 153 3. WebSocket Per-message Compression Extension 155 WebSocket Per-message Compression Extensions (PMCEs) are individually 156 defined for various compression algorithms, and are registered in the 157 WebSocket Extension Name Registry. Each PMCE refers to this 158 framework and defines: 160 o The content to put in the "Sec-WebSocket-Extensions" header, 161 including the extension name of the PMCE and any applicable 162 extension parameters 164 o How to interpret extension parameters exchanged during the opening 165 handshake 167 o How to transform payload data portion of messages. 169 One such extension is defined in Section 6 of this document and is 170 registered in Section 8. Other PMCEs may be defined in other 171 documents. 173 PMCEs operate only on non-control messages. 175 This document allocates the RSV1 bit of the WebSocket header for 176 PMCEs, and calls the bit the "Per-message Compressed" bit. This bit 177 indicates whether the compression method is applied to the contents 178 of the message or not. An endpoint MUST NOT offer or accept use of 179 any other extension using the RSV1 bit together with a PMCE. The 180 "Per-message Compressed" bit MUST NOT be set on control frames and 181 non-first fragments of a data message. Messages with the 182 "Per-message Compressed" bit set (only on the first fragment if the 183 message is fragmented) are called "compressed messages" and have 184 compressed data in their payload data portion. Messages with the 185 "Per-message Compressed" bit unset are called "uncompressed messages" 186 and have uncompressed data in their payload data portion. 188 A server MUST NOT accept a PMCE offer together with a non-PMCE 189 extension if the PMCE will be applied to output of the non-PMCE and 190 any of the following conditions is met: 192 o Frame boundary of frames output by the non-PMCE extension needs to 193 be preserved. 195 o The non-PMCE uses the "Extension data" field or any of the 196 reserved bits on the WebSocket header as per-frame attribute. 198 Section 4 describes basic extension negotiation process. Section 5 199 describes how to apply the compression algorithm with negotiated 200 parameters to the contents of WebSocket messages. 202 4. Extension Negotiation 204 To offer use of a PMCE, a client includes a 205 "Sec-WebSocket-Extensions" header element with the extension name of 206 the offered PMCE in the "Sec-WebSocket-Extensions" header in the 207 client's opening handshake of the WebSocket connection. Extension 208 parameters in the element represent the PMCE offer in detail for 209 example by listing capability of the client and preferred values for 210 the algorithm's configuration parameters to use. A client offers 211 multiple PMCE choices to the server by including multiple elements, 212 one for each PMCE offered. The set of elements MAY include multiple 213 PMCEs with the same extension name to offer use of the same algorithm 214 with different configurations. 216 To accept use of an offered PMCE, a server includes a 217 "Sec-WebSocket-Extensions" header element with the extension name of 218 the offered extension in the "Sec-WebSocket-Extensions" header in the 219 server's opening handshake of the WebSocket connection. Extension 220 parameters in the element represent the configuration parameters of 221 the PMCE to use in detail. The element MUST represent a PMCE that is 222 fully supported by the server. The server rejects all offered PMCEs 223 by not including any element with PMCE names, in which case the 224 connection proceeds without Per-message Compression. 226 If the server responds with no PMCE element in the 227 "Sec-WebSocket-Extensions" header and _the WebSocket Connection is 228 established_, both endpoints MUST proceed without Per-message 229 Compression. If the server gives an invalid response, such as 230 accepting a PMCE that the client did not offer, the client MUST _Fail 231 the WebSocket Connection_. 233 If the server responds with a valid PMCE element in the 234 "Sec-WebSocket-Extensions" header and _the WebSocket Connection is 235 established_, both endpoints MUST use the algorithm described in 236 Section 5 to exchange messages, using the payload data transformation 237 procedure of the PMCE returned by the server. 239 4.1. Negotiation Examples 241 The followings are example values for the "Sec-WebSocket-Extensions" 242 header offering PMCEs. permessage-foo and permessage-bar in the 243 examples are hypothetical extension names of PMCEs for compression 244 algorithm foo and bar. 246 o Offer the permessage-foo. 248 permessage-foo 250 o Offer the permessage-foo with a parameter x with a value of 10. 252 permessage-foo; x=10 254 The value MAY be quoted. 256 permessage-foo; x="10" 258 o Offer the permessage-foo as first choice and the permessage-bar as 259 a fallback plan. 261 permessage-foo, permessage-bar 263 o Offer the permessage-foo with a parameter use_y which enables a 264 feature y as first choice, and the permessage-foo without the 265 use_y parameter as a fallback plan. 267 permessage-foo; use_y, permessage-foo 269 5. Framing 271 5.1. Sending 273 An endpoint uses the following algorithm to compressed a message to 274 send. 276 1. Compress the payload data portion of the message using the 277 compression algorithm. 279 2. Build frame(s) for the message by putting the resulting octets 280 instead of the original octets. 282 3. Set the "Per-message Compressed" bit of the first fragment to 1. 284 PMCEs don't change the opcode field. The payload data portion in 285 outgoing frames output by a PMCE is not subject to the constraints 286 for the original data type. At the receiver, the payload data 287 portion after decompressing is subject to the constraints for the 288 original data type again. 290 To send an uncompressed message, an endpoint sets the "Per-message 291 Compressed" bit of the first fragment of the message to 0. The 292 payload data portion of the message is sent as-is without applying 293 the compression. 295 5.2. Receiving 297 To receive a compressed message, an endpoint decompress the payload 298 data portion in the frames of the message. 300 An endpoint receives an uncompressed message as-is without 301 decompression. 303 6. permessage-deflate extension 305 This section specifies a specific PMCE called "permessage-deflate". 306 It compresses the payload data portion of messages using the DEFLATE 307 [RFC1951] and the byte boundary aligning method introduced in 308 [RFC1979]. 310 The registered extension name for this extension is 311 "permessage-deflate". 313 The following 4 extension parameters are defined for this extension. 315 o "s2c_no_context_takeover" 317 o "c2s_no_context_takeover" 319 o "s2c_max_window_bits" 321 o "c2s_max_window_bits" 323 A server MUST decline a "permessage-deflate" offer if any of the 324 following conditions is met: 326 o The offer has any extension parameter unknown to the server. 328 o The offer has any extension parameter with an invalid value. 330 o The offer has multiple extension parameters with the same name. 332 o The server doesn't support the offered configuration. 334 A client MUST _Fail the WebSocket Connection_ if the server accepted 335 a "permessage-deflate" offer with a response meeting any of the 336 following condition: 338 o The response has any extension parameter unknown to the client. 340 o The response has any extension parameter with an invalid value. 342 o The response has multiple extension parameters with the same name. 344 o The client doesn't support the configuration the response 345 represents. 347 6.1. Method Parameters 349 6.1.1. Context Takeover Control 351 A client MAY attach the "s2c_no_context_takeover" extension 352 parameter. The "s2c_no_context_takeover" extension parameter has no 353 value. If a server received the "s2c_no_context_takeover" extension 354 parameter, the server MUST NOT use the same LZ77 sliding window to 355 compress two or more messages. Servers SHOULD be able to accept the 356 "s2c_no_context_takeover" parameter. A server accepts an offer with 357 this extension parameter by including the "s2c_no_context_takeover" 358 extension parameter in the response. If a server accepted an offer 359 with this extension parameter, the server MUST empty its LZ77 sliding 360 window to compress messages to send each time the server builds a new 361 message. 363 A server MAY attach the "c2s_no_context_takeover" extension parameter 364 to disallow the client to use the LZ77 sliding window used to build 365 frames for the last message the client sent to build frames for the 366 next message to send. The "c2s_no_context_takeover" extension 367 parameter has no value. Clients SHOULD be able to accept the 368 "c2s_no_context_takeover" parameter. A client that received this 369 parameter MUST reset its LZ77 sliding window for sending to empty for 370 each message. 372 6.1.2. Limiting the LZ77 sliding window size 374 A client MAY attach the "s2c_max_window_bits" extension parameter to 375 limit the LZ77 sliding window size that the server uses to build 376 messages. This extension parameter MUST have a decimal integer value 377 in the range between 8 to 15 indicating the base-2 logarithm of the 378 LZ77 sliding window size. 380 s2c_max_window_bits = 1*DIGIT 382 A server declines an offer with this extension parameter if the 383 server doesn't support the extension parameter. A server accepts an 384 offer with this extension parameter by including the extension 385 parameter with the same value as the offer in the response. If a 386 server accepts an offer with this extension parameter, the server 387 MUST NOT use LZ77 sliding window size greater than the size specified 388 by the extension parameter to compress messages 390 A client MAY attach the "c2s_max_window_bits" extension parameter if 391 the client can adjust LZ77 sliding window size based on the 392 "c2s_max_window_bits" sent by the server. This parameter has no 393 value. 395 If a server received and accepts an offer with the 396 "c2s_max_window_bits" extension parameter, the server MAY include the 397 "c2s_max_window_bits" parameter in the response to the offer to limit 398 the LZ77 sliding window size that the client uses to build messages. 399 If a server received and accepts an offer without the 400 "c2s_max_window_bits" extension parameter, the server MUST NOT 401 include the "c2s_max_window_bits" extension parameter in the response 402 to the offer. The "c2s_max_window_bits" extension parameter in the 403 server's opening handshake MUST have a decimal integer value in the 404 range between 8 to 15 indicating the base-2 logarithm of the LZ77 405 sliding window size. 407 c2s_max_window_bits = 1*DIGIT 409 If a client received the "c2s_max_window_bits" extension parameter, 410 the client MUST NOT use LZ77 sliding window size greater than the 411 size specified by the extension parameter to build messages. 413 6.1.3. Example 415 The simplest "Sec-WebSocket-Extensions" header in a client's opening 416 handshake to offer use of the permessage-deflate is the following: 418 Sec-WebSocket-Extensions: permessage-deflate 420 Since the "c2s_max_window_bits" extension parameter is not specified, 421 the server may not accept the offer with the "c2s_max_window_bits" 422 extension parameter. The simplest "Sec-WebSocket-Extensions" header 423 in a server's opening handshake to accept use of the permessage- 424 deflate is the same. 426 The following offer sent by a client is asking the server to use the 427 LZ77 sliding window size of 1,024 bytes or less and declaring that 428 the client can accept the "c2s_max_window_bits" extension parameter. 430 Sec-WebSocket-Extensions: 431 permessage-deflate; 432 c2s_max_window_bits; s2c_max_window_bits=10 434 This offer might be rejected by the server because the server doesn't 435 support the "s2c_max_window_bits" extension parameter. This is fine 436 if the "s2c_max_window_bits" is mandatory for the client, but if the 437 client want to fallback to the "permessage-deflate" without the 438 "s2c_max_window_bits", the client should offer the fallback option in 439 addition like this: 441 Sec-WebSocket-Extensions: 442 permessage-deflate; 443 c2s_max_window_bits; s2c_max_window_bits=10, 444 permessage-deflate; 445 c2s_max_window_bits 447 This example offers two configurations so that the server can accept 448 permessage-deflate by picking supported one from them. To accept the 449 first option, the server sends back this for example: 451 Sec-WebSocket-Extensions: 452 permessage-deflate; s2c_max_window_bits=10 454 And to accept the second option, the server sends back this for 455 example: 457 Sec-WebSocket-Extensions: permessage-deflate 459 6.2. Payload Data Transformation 461 6.2.1. Compression 463 An endpoint uses the following algorithm to compress a message. 465 1. Compress all the octets of the payload data portion of the 466 message using the DEFLATE. 468 2. If the resulting data does not end with an empty DEFLATE block 469 with no compression (the "BTYPE" bit is set to 0), append an 470 empty DEFLATE block with no compression to the tail end. 472 3. Remove 4 octets (that are 0x00 0x00 0xff 0xff) from the tail end. 473 After this step, the last octet of the compressed data contains 474 (possibly part of) the DEFLATE header bits with the "BTYPE" bit 475 set to 0. 477 In using the DEFLATE in the first step above: 479 o An endpoints MAY use multiple DEFLATE blocks to compress one 480 message. 482 o An endpoints MAY use DEFLATE blocks of any type. 484 o An endpoints MAY use both DEFLATE blocks with the "BFINAL" bit set 485 to 0 and DEFLATE blocks with the "BFINAL" bit set to 1. 487 o When any DEFLATE block with the "BFINAL" bit set to 1 doesn't end 488 at byte boundary, an endpoint adds minimal padding bits of 0 to 489 make it end at byte boundary. The next DEFLATE block follows the 490 padded data if any. 492 An endpoint MUST NOT use an LZ77 sliding window longer than 32,768 493 bytes to compress messages to send. 495 If a server accepts an offer with the "c2s_no_context_takeover" 496 extension parameter, the client MUST empty its LZ77 sliding window to 497 compress messages to send each time the client compresses a new 498 message to send. Otherwise, the client MAY take over the LZ77 499 sliding window used to build the last compressed message. 501 If a server accepts an offer with the "s2c_no_context_takeover" 502 extension parameter, the server MUST empty its LZ77 sliding window to 503 compress messages to send each time the server compresses a new 504 message to send. Otherwise, the server MAY take over the LZ77 505 sliding window used to build the last compressed message. 507 If a server accepts an offer with the "c2s_max_window_bits" extension 508 parameter with a value of w, the client MUST NOT use an LZ77 sliding 509 window longer than w-th power of 2 bytes to compress messages to 510 send. 512 If a server accepts an offer with the "s2c_max_window_bits" extension 513 parameter with a value of w, the server MUST NOT use an LZ77 sliding 514 window longer than w-th power of 2 bytes to compress messages to 515 send. 517 6.2.2. Decompression 519 An endpoint uses the following algorithm to decompress a message. 521 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the 522 payload data portion of the message. 524 2. Decompress the resulting data using the DEFLATE. 526 If a server accepts an offer with the "s2c_no_context_takeover" 527 extension parameter, the client MAY empty its LZ77 sliding window to 528 decompress received messages each time the client decompresses a new 529 received message. Otherwise, the client MUST take over the LZ77 530 sliding window used to process the last compressed message. 532 If a server accepts an offer with the "c2s_no_context_takeover" 533 extension parameter, the server MAY empty its LZ77 sliding window to 534 decompress received messages each time the server decompresses a new 535 received message. Otherwise, the server MUST take over the LZ77 536 sliding window used to process the last compressed message. 538 If a server accepts an offer with the "s2c_max_window_bits" extension 539 parameter with a value of w, the client MAY reduce the size of its 540 LZ77 sliding window to decompress received messages down to the w-th 541 power of 2 bytes. Otherwise, the client MUST use a 32,768 byte LZ77 542 sliding window to decompress received messages. 544 If a server accepts an offer with the "c2s_max_window_bits" extension 545 parameter with a value of w, the server MAY reduce the size of its 546 LZ77 sliding window to decompress received messages down to the w-th 547 power of 2 bytes. Otherwise, the server MUST use a 32,768 byte LZ77 548 sliding window to decompress received messages. 550 6.2.3. Examples 552 This section introduces examples of how the permessage-deflate 553 transforms messages. 555 6.2.3.1. A message compressed using 1 compressed DEFLATE block 557 Suppose that an endpoint sends a text message "Hello". If the 558 endpoint uses 1 compressed DEFLATE block (compressed with fixed 559 Huffman code and the "BFINAL" bit is not set) to compress the 560 message, the endpoint obtains the compressed data to put in the 561 payload data portion as follows. 563 The endpoint compresses "Hello" into 1 compressed DEFLATE block and 564 flushes the resulting data into a byte array using an empty DEFLATE 565 block with no compression: 567 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 0x00 0xff 0xff 569 By stripping 0x00 0x00 0xff 0xff from the tail end, the endpoint gets 570 the data to put in the payload data portion: 572 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 574 Suppose that the endpoint sends this compressed message without 575 fragmentation. The endpoint builds one frame by putting the whole 576 compressed data in the payload data portion of the frame: 578 0xc1 0x07 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 580 The first 2 octets (0xc1 0x07) are the WebSocket frame header (FIN=1, 581 RSV1=1, RSV2=0, RSV3=0, opcode=text, MASK=0, Payload length=7). The 582 following figure shows what value is set in each field of the 583 WebSocket frame header. 585 0 1 586 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 587 +-+-+-+-+-------+-+-------------+ 588 |F|R|R|R| opcode|M| Payload len | 589 |I|S|S|S| |A| | 590 |N|V|V|V| |S| | 591 | |1|2|3| |K| | 592 +-+-+-+-+-------+-+-------------+ 593 |1|1|0|0| 1 |0| 7 | 594 +-+-+-+-+-------+-+-------------+ 596 Suppose that the endpoint sends the compressed message with 597 fragmentation. The endpoint splits the compressed data into 598 fragments and builds frames for each fragment. For example, if the 599 fragments are 3 and 4 octet, the first frame is: 601 0x41 0x03 0xf2 0x48 0xcd 603 and the second frame is: 605 0x80 0x04 0xc9 0xc9 0x07 0x00 607 Note that the RSV1 bit is set only on the first frame. 609 6.2.3.2. Sharing LZ77 Sliding Window 611 Suppose that a client has sent a message "Hello" as a compressed 612 message and will send the same message "Hello" again as a compressed 613 message. If the server has accepted the offer with the 614 "c2s_no_context_takeover" extension parameter, the server compresses 615 the payload data portion of the next message into the same bytes (if 616 the server uses the same "BTYPE" value and "BFINAL" value): 618 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 620 If the server hasn't accepted the offer with the 621 "c2s_no_context_takeover" extension parameter, the server can 622 compress the payload data portion of the next message into shorter 623 bytes utilizing the history in the LZ77 sliding window: 625 0xf2 0x00 0x11 0x00 0x00 627 Note that even if any uncompressed message (any message with the RSV1 628 bit unset) is inserted between the two "Hello" messages, such a 629 message doesn't make any change on the LZ77 sliding window. 631 6.2.3.3. Using a DEFLATE Block with No Compression 633 Suppose that an endpoint compresses a text message "Hello" using a 634 DEFLATE block with no compression. A DEFLATE block with no 635 compression containing "Hello" flushed into a byte array using 636 another but empty DEFLATE block with no compression is: 638 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 639 0x00 0x00 0xff 0xff 641 The endpoint strips the 4 octets at the tail end: 643 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 645 The endpoint builds a frame by putting the resulting data in the 646 payload data portion of the frame: 648 0xc1 0x0b 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 650 The first 2 octets (0xc1 0x0b) are the WebSocket frame header (FIN=1, 651 RSV1=1, RSV2=0, RSV3=0, opcode=text, MASK=0, Payload length=7). Note 652 that the RSV1 bit is set for this message (only on the first fragment 653 if the message is fragmented) because the RSV1 bit is set when the 654 DEFLATE is applied to the message and it includes the case only 655 DEFLATE blocks with no compression are used. 657 6.2.3.4. Using a DEFLATE Block with BFINAL Set to 1 659 On platform where the flush method using an empty DEFLATE block with 660 no compression is not avaiable, implementors can choose to flush data 661 using DEFLATE blocks with "BFINAL" set to 1. Using a DEFLATE block 662 with "BFINAL" set to 1 and "BTYPE" set to 1, "Hello" is compressed 663 into: 665 0xf3 0x48 0xcd 0xc9 0xc9 0x07 0x00 667 So, payload of a message containing "Hello" compressed using this 668 method is: 670 0xf3 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 672 The last 1 octet (0x00) contains the header bits with "BFINAL" set to 673 0 and "BTYPE" set to 0, and 7 padding bits of 0. This octet is 674 necessary to allow the payload to be decompressed in the same manner 675 as messages flushed using DEFLATE blocks with BFINAL unset. 677 6.2.3.5. Two DEFLATE Blocks in 1 Message 679 Two or more DEFLATE blocks may be used in 1 message. 681 0xf2 0x48 0x05 0x00 0x00 0x00 0xff 0xff 0xca 0xc9 0xc9 0x07 0x00 683 The first 3 octets (0xf2 0x48 0x05) and the least significant two 684 bits of the 4th octet (0x00) consist one DEFLATE block with "BFINAL" 685 set to 0 and "BTYPE" set to 1 containing "He";. The rest of the 4th 686 octet contains the header bits with "BFINAL" set to 0 and "BTYPE" set 687 to 0, and the 3 padding bits of 0. Together with the following 4 688 octets (0x00 0x00 0xff 0xff), the header bits consist an empty 689 DEFLATE block with no compression. A DEFLATE block containing "llo" 690 follows the empty DEFLATE block. 692 6.3. Intermediaries 694 When an intermediary forwards messages, the intermediary MAY add, 695 change or remove Per-message Compression on the messages. The 696 elements in the "Sec-WebSocket-Extensions" for the PMCE in the 697 opening handshakes with the connected client and server must be 698 altered by the intermediary accordingly to match the new framing. 700 6.4. Implementation Notes 702 On most common software development platforms, their DEFLATE 703 compression library provide a method to align compressed data to byte 704 boundaries using an empty DEFLATE block with no compression. For 705 example, Zlib [Zlib] does this when "Z_SYNC_FLUSH" is passed to the 706 deflate function. 708 To attain sufficient compression ratio, the LZ77 sliding window size 709 of 1,024 or more is RECOMMENDED. 711 7. Security Considerations 713 There is a known exploit for combination of a secure transport 714 protocol and a dictionary based compression [CRIME]. Implementors 715 should give attention to this point when integrating this extension 716 with other extensions or protocols. 718 8. IANA Considerations 720 8.1. Registration of the "permessage-deflate" WebSocket Extension Name 722 This section describes a WebSocket extension name registration in the 723 WebSocket Extension Name Registry [RFC6455]. 725 Extension Identifier 726 permessage-deflate 728 Extension Common Name 729 WebSocket Per-message Deflate 731 Extension Definition 732 This document. 734 Known Incompatible Extensions 735 None 737 The "permessage-deflate" extension name is used in the 738 "Sec-WebSocket-Extensions" header in the WebSocket opening handshake 739 to negotiate use of the permessage-deflate extension. 741 8.2. Registration of the "Per-message Compressed" WebSocket Framing 742 Header Bit 744 This section describes a WebSocket framing header bit registration in 745 the WebSocket Framing Header Bits Registry [RFC6455]. 747 Header Bit 748 RSV1 750 Common Name 751 Per-message Compressed 753 Meaning 754 The message is compressed or not. 756 Reference 757 Section 5 of this document. 759 The "Per-message Compressed" framing header bit is used on the first 760 fragment of non-control messages to indicate whether the payload data 761 portion of the message is compressed by the PMCE or not. 763 9. Acknowledgements 765 Special thanks to Patrick McManus who wrote up the initial 766 specification of a DEFLATE-based compression extension for the 767 WebSocket Protocol to which I referred to write this specification. 769 Thank you to the following people who participated in discussions on 770 the HyBi WG and contributed ideas and/or provided detailed reviews 771 (the list is likely to be incomplete): Alexey Melnikov, Arman 772 Djusupov, Bjoern Hoehrmann, Brian McKelvey, Greg Wilkins, Inaki Baz 773 Castillo, Jamie Lokier, Joakim Erdfelt, John A. Tamplin, Julian 774 Reschke, Kenichi Ishibashi, Mark Nottingham, Peter Thorson, Roberto 775 Peon and Simone Bordet. Note that people listed above didn't 776 necessarily endorse the end result of this work. 778 10. References 780 10.1. Normative References 782 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 783 Specifications: ABNF", STD 68, RFC 5234, January 2008. 785 [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", 786 RFC 6455, December 2011. 788 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 789 Requirement Levels", BCP 14, RFC 2119, March 1997. 791 [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for 792 Sequential Data Compression", IEEE Transactions on 793 Information Theory, Vol. 23, No. 3, pp. 337-343. 795 10.2. Informative References 797 [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification 798 version 1.3", RFC 1951, May 1996. 800 [RFC1979] Woods, J., "PPP Deflate Protocol", RFC 1979, August 1996. 802 [Zlib] Gailly, J. and M. Adler, "Zlib", . 804 [CRIME] Rizzo, J. and T. Duong, "The CRIME attack", Ekoparty 2012, 805 September 2012. 807 Author's Address 809 Takeshi Yoshino 810 Google, Inc. 812 Email: tyoshino@google.com