idnits 2.17.1 draft-ietf-hybi-permessage-compression-17.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 (January 22, 2014) is 3737 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) ** Downref: Normative reference to an Informational RFC: RFC 1951 -- Possible downref: Non-RFC (?) normative reference: ref. 'LZ77' Summary: 1 error (**), 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 January 22, 2014 5 Expires: July 26, 2014 7 Compression Extensions for WebSocket 8 draft-ietf-hybi-permessage-compression-17 10 Abstract 12 This document specifies a framework for creating WebSocket extensions 13 that add compression functionality to the WebSocket Protocol. An 14 extension based on this framework compresses the payload data portion 15 of non-control WebSocket messages on a per-message basis using 16 parameters negotiated during the opening handshake. This framework 17 provides a general method to apply a compression algorithm to the 18 contents of WebSocket messages. For each compression algorithm, an 19 extension is defined by specifying parameter negotiation and 20 compression algorithm in detail. This document also specifies one 21 specific compression extension using the DEFLATE algorithm. 23 Please send feedback to the hybi@ietf.org mailing list. 25 Status of this Memo 27 This Internet-Draft is submitted to IETF in full conformance with the 28 provisions of BCP 78 and BCP 79. 30 Internet-Drafts are working documents of the Internet Engineering 31 Task Force (IETF). Note that other groups may also distribute 32 working documents as Internet-Drafts. The list of current Internet- 33 Drafts is at http://datatracker.ietf.org/drafts/current. 35 Internet-Drafts are draft documents valid for a maximum of six months 36 and may be updated, replaced, or obsoleted by other documents at any 37 time. It is inappropriate to use Internet-Drafts as reference 38 material or to cite them other than as "work in progress." 40 This Internet-Draft will expire on July 26, 2014. 42 Copyright Notice 44 Copyright (c) 2014 IETF Trust and the persons identified as the 45 document authors. All rights reserved. 47 This document is subject to BCP 78 and the IETF Trust's Legal 48 Provisions Relating to IETF Documents 49 (http://trustee.ietf.org/license-info) in effect on the date of 50 publication of this document. Please review these documents 51 carefully, as they describe your rights and restrictions with respect 52 to this document. Code Components extracted from this document must 53 include Simplified BSD License text as described in Section 4.e of 54 the Trust Legal Provisions and are provided without warranty as 55 described in the Simplified BSD License. 57 Table of Contents 59 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 60 2. Conformance Requirements and Terminology . . . . . . . . . . . 4 61 3. Complementary Terminology . . . . . . . . . . . . . . . . . . 5 62 4. WebSocket Per-message Compression Extension . . . . . . . . . 6 63 5. Extension Negotiation . . . . . . . . . . . . . . . . . . . . 7 64 5.1. Negotiation Examples . . . . . . . . . . . . . . . . . . . 9 65 6. Framing . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 66 6.1. Compression . . . . . . . . . . . . . . . . . . . . . . . 11 67 6.2. Decompression . . . . . . . . . . . . . . . . . . . . . . 12 68 7. Intermediaries . . . . . . . . . . . . . . . . . . . . . . . . 14 69 8. permessage-deflate extension . . . . . . . . . . . . . . . . . 15 70 8.1. Method Parameters . . . . . . . . . . . . . . . . . . . . 16 71 8.1.1. Context Takeover Control . . . . . . . . . . . . . . . 16 72 8.1.2. Limiting the LZ77 sliding window size . . . . . . . . 18 73 8.1.3. Example . . . . . . . . . . . . . . . . . . . . . . . 20 74 8.2. Message Payload Transformation . . . . . . . . . . . . . . 21 75 8.2.1. Compression . . . . . . . . . . . . . . . . . . . . . 21 76 8.2.2. Decompression . . . . . . . . . . . . . . . . . . . . 22 77 8.2.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 23 78 8.3. Implementation Notes . . . . . . . . . . . . . . . . . . . 27 79 8.4. Intermediaries . . . . . . . . . . . . . . . . . . . . . . 27 80 9. Security Considerations . . . . . . . . . . . . . . . . . . . 28 81 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 82 10.1. Registration of the "permessage-deflate" WebSocket 83 Extension Name . . . . . . . . . . . . . . . . . . . . . . 29 84 10.2. Registration of the "Per-message Compressed" WebSocket 85 Framing Header Bit . . . . . . . . . . . . . . . . . . . . 29 86 11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 30 87 12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 31 88 12.1. Normative References . . . . . . . . . . . . . . . . . . . 31 89 12.2. Informative References . . . . . . . . . . . . . . . . . . 31 90 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 32 92 1. Introduction 94 This document specifies a framework to add compression functionality 95 to the WebSocket Protocol [RFC6455]. This framework specifies how to 96 define WebSocket Per-message Compression Extensions (PMCEs) 97 individually for various compression algorithms based on the 98 extension concept of the WebSocket Protocol specified in Section 9 of 99 [RFC6455]. A WebSocket client and a peer WebSocket server negotiate 100 use of a PMCE and determine parameters to configure the compression 101 algorithm during the WebSocket opening handshake. The client and 102 server can then exchange non-control messages using frames with 103 compressed data in the payload data portion. This framework 104 specifies a general method to apply a compression algorithm to the 105 contents of WebSocket messages. A document specifying an individual 106 PMCE describes how to negotiate configuration parameters for the 107 compression algorithm and how to transform (compress and decompress) 108 data in the payload data portion in detail. A WebSocket client may 109 offer multiple PMCEs during the WebSocket opening handshake. A peer 110 WebSocket server received those offers may choose and accept 111 preferred one or decline all of them. PMCEs use the RSV1 bit of the 112 WebSocket frame header to indicate whether a message is compressed or 113 not, so that an endpoint can choose not to compress messages with 114 incompressible contents. 116 This document also specifies one specific PMCE based on the DEFLATE 117 [RFC1951] algorithm. The extension name of the PMCE is "permessage- 118 deflate". We chose DEFLATE since it's widely available as a library 119 on various platforms and the overhead is small. To align the end of 120 compressed data to an octet boundary, this extension uses the 121 algorithm described in Section 2.1 of [RFC1979]. Endpoints can take 122 over the LZ77 sliding window [LZ77] used to build frames for previous 123 messages to get better compression ratio. For resource-limited 124 devices, this extension provides parameters to limit memory usage for 125 compression context. 127 2. Conformance Requirements and Terminology 129 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 130 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 131 document are to be interpreted as described in [RFC2119]. 133 Requirements phrased in the imperative as part of algorithms (such as 134 "strip any leading space characters" or "return false and abort these 135 steps") are to be interpreted with the meaning of the key word 136 ("MUST", "SHOULD", "MAY", etc.) used in introducing the algorithm. 138 Conformance requirements phrased as algorithms or specific steps can 139 be implemented in any manner, so long as the end result is 140 equivalent. In particular, the algorithms defined in this 141 specification are intended to be easy to understand and are not 142 intended to be performant. 144 This document references the procedure to _Fail the WebSocket 145 Connection_. This procedure is defined in Section 7.1.7 of 146 [RFC6455]. 148 This document references the event that _The WebSocket Connection is 149 Established_ and the event that _A WebSocket Message Has Been 150 Received_. These events are defined in Section 4.1 and Section 6.2, 151 respectively, of [RFC6455]. 153 This document uses the Argumented Backus-Naur Form (ABNF) notation of 154 [RFC5234]. The DIGIT (decimal 0-9) rule is included by reference, as 155 defined in the Appendix B.1 of [RFC5234]. 157 3. Complementary Terminology 159 This document defines some terms about WebSocket and WebSocket 160 Extension mechanism that are underspecified or not defined at all in 161 [RFC6455]. This terminology is effective only in this document and 162 any other documents that refer to this section. 164 Non-control message means a message that consists of non-control 165 frames as defined in Section 5.6 of [RFC6455]. 167 Message payload (or payload of a message) means concatenation of the 168 payload data portion of all frames representing a single message, as 169 well as how /data/ is formed from in Section 6.2 of [RFC6455]. 171 Extension in use next to extension X means the extension listed next 172 to X in the "Sec-WebSocket-Extensions" header in the server's opening 173 handshake as defined in Section 9.1 of [RFC6455]. Such an extension 174 is applied to outgoing data from the application right after X on 175 sender side but applied right before X to incoming data from the 176 underlying transport. 178 Extension negotiation offer means each element in the 179 "Sec-WebSocket-Extensions" header in the client's opening handshake. 181 Extension negotiation response means each element in the 182 "Sec-WebSocket-Extensions" header in the server's opening handshake. 184 Accept an extension negotiation offer means including a corresponding 185 extension negotiation response in the "Sec-WebSocket-Extensions" 186 header in the server's opening handshake. 188 Decline an extension negotiation offer means not including a 189 corresponding extension negotiation response in the 190 "Sec-WebSocket-Extensions" header in the server's opening handshake. 192 4. WebSocket Per-message Compression Extension 194 WebSocket Per-message Compression Extensions (PMCEs) are extensions 195 to the WebSocket Protocol enabling compression functionality. PMCEs 196 are built based on Section 9 of [RFC6455]. PMCEs are individually 197 defined for each compression algorithm to be implemented, and are 198 registered in the WebSocket Extension Name Registry created in 199 Section 11.4 of [RFC6455]. Each PMCE refers to this framework and 200 defines the following: 202 o The content to put in the "Sec-WebSocket-Extensions" header. The 203 content includes the extension name of the PMCE and any applicable 204 extension parameters. 206 o How to interpret extension parameters exchanged during the opening 207 handshake 209 o How to transform the payload of a message. 211 One such extension is defined in Section 8 of this document and is 212 registered in Section 10. Other PMCEs may be defined in other 213 documents. 215 Section 5 describes the basic extension negotiation process. 216 Section 6 describes how to apply the compression algorithm with 217 negotiated parameters to the contents of WebSocket messages. 219 5. Extension Negotiation 221 To offer use of a PMCE, a client includes a 222 "Sec-WebSocket-Extensions" header element with the extension name of 223 the PMCE in the "Sec-WebSocket-Extensions" header in the client's 224 opening handshake of the WebSocket connection. Extension parameters 225 in the element represent the PMCE offer in detail. For example, a 226 client lists preferred configuration parameter values for the 227 compression algorithm of the PMCE. A client offers multiple PMCE 228 choices to the server by including multiple elements in the 229 "Sec-WebSocket-Extensions" header, one for each PMCE offered. The 230 set of elements MAY include multiple PMCEs with the same extension 231 name to offer use of the same algorithm with different configuration 232 parameters. The order of elements means the client's preference. An 233 element precedes another element has higher preference. It is 234 RECOMMENDED that a server accepts PMCEs with higher preference if the 235 server supports it. 237 A PMCE negotiation offer informs requests and/or hints to the server. 238 A request in a PMCE negotiation offer indicates constraints on the 239 server's behavior that must be satisfied if the server accepts the 240 offer. A hint in a PMCE negotiation offer indicates information 241 about the client's behavior that the server may either safely ignore 242 or refer to when the server decides its behavior. 244 To accept use of an offered PMCE, a server includes a 245 "Sec-WebSocket-Extensions" header element with the extension name of 246 the PMCE in the "Sec-WebSocket-Extensions" header in the server's 247 opening handshake of the WebSocket connection. Extension parameters 248 in the element represent the configuration parameters of the PMCE to 249 use in detail. We call these extension parameters and their values 250 "agreed parameters". The element MUST represent a PMCE that is fully 251 supported by the server. The contents of the element doesn't need to 252 be exactly the same as one of the received extension negotiation 253 offers. For example, an extension negotiation offer with an 254 extension parameter "X" indicating availability of the feature X may 255 be accepted with an element without the extension parameter meaning 256 that the server declined use of the feature. 258 "Agreed parameters" MUST represent how the requests and hints in the 259 client's extension negotiation offer have been handled in addition to 260 the server's requests and hints on the client's behavior, so that the 261 client can configure its behavior without identifying which PMCE 262 extension negotiation offer has been accepted. 264 For example, if a client sends an extension negotiation offer 265 including a parameter "enable_compression" and another without the 266 parameter, the server accepts the former by sending back an element 267 including a parameter that acknowledges "enable_compression". The 268 name of the acknowledging parameter doesn't need to be the same as 269 the offer. 271 General negotiation flow will be like the followings. How to handle 272 parameters in detail will be specified in the specifications for each 273 PMCEs. 275 A client makes an offer including parameters identifying the 276 followings: 278 o Hints about how the client is planning to compress data 280 o Requests about how the server compresses data 282 o Limitation of the client's compression functionality 284 The peer server uses these parameters, makes a determination of its 285 behavior based on them if it can and wants to proceed with this PMCE 286 enabled, and responds to the client with parameters identifying the 287 followings: 289 o Requests about how the client compresses data 291 o How the server will compress data 293 The client uses these parameters from the server make a determination 294 of its behavior based on them if it can and wants to proceed. 295 Otherwise, the client starts closing handshake with close code 1010. 297 There can be compression features that can be applied separately for 298 each direction. For such features, the acknowledging parameter and 299 the parameter for the reverse direction must be chosen to be 300 distinguishable from each other. For example, we can add "server_" 301 prefix to parameters affecting data sent from a server and "client_" 302 prefix to ones affecting data sent from a client to make them 303 distinguishable. 305 A server MUST NOT accept a PMCE extension negotiation offer together 306 with another extension if the PMCE will conflict with the extension 307 on use of the RSV1 bit. A client that receives a response accepting 308 a PMCE extension negotiation offer together with such an extension 309 MUST _Fail the WebSocket Connection_. 311 A server MUST NOT accept a PMCE extension negotiation offer together 312 with another extension if the PMCE will be applied to output of the 313 extension and any of the following conditions applies to the 314 extension: 316 o The extension requires boundary of fragments to be preserved 317 between output from the extension at the sender and input to the 318 extension at the receiver. 320 o The extension uses the "Extension data" field or any of the 321 reserved bits on the WebSocket header as per-frame attribute. 323 A client receiving a response accepting a PMCE extension negotiation 324 offer together with such an extension MUST _Fail the WebSocket 325 Connection_. 327 A server declines all offered PMCEs by not including any element with 328 PMCE names. If a server responds with no PMCE element in the 329 "Sec-WebSocket-Extensions" header, both endpoints proceed without 330 Per-message Compression once _the WebSocket Connection is 331 established_. 333 If a server gives an invalid response, such as accepting a PMCE that 334 the client did not offer, the client MUST _Fail the WebSocket 335 Connection_. 337 If a server responds with a valid PMCE element in the 338 "Sec-WebSocket-Extensions" header and _the WebSocket Connection is 339 established_, both endpoints MUST use the algorithm described in 340 Section 6 to exchange messages, using the message payload 341 transformation (compressing and decompressing) procedure of the PMCE 342 returned by the server. 344 5.1. Negotiation Examples 346 The followings are example values for the "Sec-WebSocket-Extensions" 347 header offering PMCEs. permessage-foo and permessage-bar in the 348 examples are hypothetical extension names of PMCEs for compression 349 algorithm foo and bar. 351 o Offer the permessage-foo. 353 permessage-foo 355 o Offer the permessage-foo with a parameter x with a value of 10. 357 permessage-foo; x=10 359 The value MAY be quoted. 361 permessage-foo; x="10" 363 o Offer the permessage-foo as first choice and the permessage-bar as 364 a fallback plan. 366 permessage-foo, permessage-bar 368 o Offer the permessage-foo with a parameter use_y which enables a 369 feature y as first choice, and the permessage-foo without the 370 use_y parameter as a fallback plan. 372 permessage-foo; use_y, permessage-foo 374 6. Framing 376 PMCEs operate only on non-control messages. 378 This document allocates the RSV1 bit of the WebSocket header for 379 PMCEs, and calls the bit the "Per-message Compressed" bit. On a 380 WebSocket connection where a PMCE is in use, this bit indicates 381 whether a message is compressed or not. 383 A message with the "Per-message Compressed" bit set on the first 384 fragment of the message is called a "compressed message". Frames of 385 a compressed message have compressed data in the payload data 386 portion. An endpoint receiving a compressed message decompresses the 387 concatenation of the compressed data of the frames of the message by 388 following the decompression procedure specified by the PMCE in use. 389 The endpoint uses the bytes corresponding to the application data 390 portion in this decompressed data for the _A WebSocket Message Has 391 Been Received_ event instead of the received data as-is. 393 A message with the "Per-message Compressed" bit unset on the first 394 fragment of the message is called an "uncompressed message". Frames 395 of an uncompressed message have uncompressed original data as-is in 396 the payload data portion. An endpoint received an uncompressed 397 message uses the concatenation of the application data portion of the 398 frames of the message as-is for the _A WebSocket Message Has Been 399 Received_ event. 401 6.1. Compression 403 An endpoint MUST use the following algorithm to send a message in the 404 form of a compressed message. 406 1. Compress the message payload of the original message by following 407 the compression procedure of the PMCE. The original message may 408 be input from the application layer or output of another 409 WebSocket extension depending on what extensions were negotiated. 411 2. If this PMCE is the last extension to process outgoing messages, 412 build frame(s) by using the compressed data instead of the 413 original data for the message payload, and setting the 414 "Per-message Compressed" bit of the first frame, then send the 415 frame(s) as described in Section 6.1 of RFC6455. Otherwise, pass 416 the transformed message payload and modified header values 417 including "Per-message Compressed" bit value set to 1 to the 418 extension next to the PMCE. If the extension expects frames as 419 input, build a frame for the message and pass it. 421 An endpoint MUST use the following algorithm to send a message in the 422 form of an uncompressed message. If this PMCE is the last extension 423 to process outgoing messages, build frame(s) by using the original 424 data for the payload data portion as-is and unsetting the 425 "Per-message Compressed" bit of the first frame, then send the 426 frame(s) as described in Section 6.1 of RFC6455. Otherwise, pass the 427 message payload and header values to the extension next to the PMCE 428 as-is. If the extension expects frames as input, build a frame for 429 the message and pass it. 431 An endpoint MUST NOT set the "Per-message Compressed" bit of control 432 frames and non-first fragments of a data message. An endpoint 433 received such a frame MUST _Fail the WebSocket Connection_. 435 PMCEs don't change the opcode field. The opcode of the first frame 436 of a compress message indicates the opcode of the original message. 438 The payload data portion in frames generated by a PMCE is not subject 439 to the constraints for the original data type. For example, the 440 concatenation of the data corresponding to the application data 441 portion of frames of a compressed text message is not required to be 442 valid UTF-8. At the receiver, the payload data portion after 443 decompression is subject to the constraints for the original data 444 type again. 446 6.2. Decompression 448 An endpoint MUST use the following algorithm to receive a message in 449 the form of a compressed message. 451 1. Concatenate the payload data portion of the received frames of 452 the compressed message. The received frames may direct input 453 from underlying transport or output of another WebSocket 454 extension depending on what extensions were negotiated. 456 2. Decompress the concatenation by following the decompression 457 procedure of the PMCE. 459 3. If this is the last extension to process incoming messages, 460 deliver the _A WebSocket Message Has Been Received_ event to the 461 application layer with the decompressed message payload and 462 header values including the "Per-message Compressed" bit unset to 463 0. Otherwise, pass the decompressed message payload and header 464 values including the "Per-message Compressed" bit unset to 0 to 465 the extension next to the PMCE. If the extension expects frames 466 as input, build a frame for the message and pass it. 468 An endpoint MUST use the following algorithm to receive a message in 469 the form of an uncompressed message. If this PMCE is the last 470 extension to process incoming messages, deliver the _A WebSocket 471 Message Has Been Received_ event to the application layer with the 472 received message payload and header values as-is. Otherwise, pass 473 the message payload and header values to the extension next to the 474 PMCE as-is. If the extension expects frames as input, build a frame 475 for the message and pass it. 477 7. Intermediaries 479 When an intermediary proxies a WebSocket connection, the intermediary 480 MAY add, change or remove Per-message Compression on the messages if 481 the intermediary meets all of the following conditions: 483 o The intermediary understands that Per-message Compression. 485 o The intermediary can read all of proxied data including the 486 opening handshake request, opening handshake response, and 487 messages. 489 o The intermediary can alter the proxied data before forwarding them 490 accordingly to conform to the constraints of the new combination 491 of extensions. For example, if a PMCE is removed from messages, 492 the corresponding element in the "Sec-WebSocket-Extensions" in the 493 opening handshake response must also be removed. 495 Otherwise, the intermediary MUST NOT make any change on the proxied 496 data. 498 8. permessage-deflate extension 500 This section specifies a specific PMCE called "permessage-deflate". 501 It compresses the payload of a message using the DEFLATE algorithm 502 [RFC1951] and the byte boundary aligning method introduced in 503 [RFC1979]. 505 This section uses the term "byte" with the same meaning as RFC1951, 506 i.e. 8 bits stored or transmitted as a unit (same as an octet). 508 The registered extension name for this extension is 509 "permessage-deflate". 511 Four extension parameters are defined for permessage-deflate to help 512 endpoints manage per-connection resource usage. 514 o "server_no_context_takeover" 516 o "client_no_context_takeover" 518 o "server_max_window_bits" 520 o "client_max_window_bits" 522 These represent two methods (no_context_takeover and max_window_bits) 523 of constraining memory usage that may be applied independently to 524 either direction of WebSocket traffic. The extension parameters with 525 the client_ prefix are used to negotiate DEFLATE parameters to 526 control compression on messages sent by a client and received by a 527 server. The client refers to parameters with the client_ prefix to 528 configure its compressor, while the server refers to them to 529 configure its decompressor. The extension parameters with the 530 server_ prefix are used to negotiate DEFLATE parameters to control 531 compression on messages sent by a server and received by a client. 532 The server refers to parameters with the server_ prefix to configure 533 its compressor, while the client refers to them to configure its 534 decompressor. All four parameters are defined for both a client's 535 extension negotiation offer and a server's extension negotiation 536 response. 538 A server MUST decline an extension negotiation offer for this 539 extension if any of the following conditions is met: 541 o The offer has any extension parameter not defined for use in an 542 offer. 544 o The offer has any extension parameter with an invalid value. 546 o The offer has multiple extension parameters with the same name. 548 o The server doesn't support the offered configuration. 550 A client MUST _Fail the WebSocket Connection_ if the peer server 551 accepted an extension negotiation offer for this extension with an 552 extension negotiation response meeting any of the following 553 condition: 555 o The response has any extension parameter not defined for use in a 556 response. 558 o The response has any extension parameter with an invalid value. 560 o The response has multiple extension parameters with the same name. 562 o The client doesn't support the configuration the response 563 represents. 565 The term "LZ77 sliding window" used in this section means the buffer 566 storing recently processed input. The LZ77 algorithm searches the 567 buffer for match with the next input. 569 8.1. Method Parameters 571 8.1.1. Context Takeover Control 573 8.1.1.1. server_no_context_takeover 575 A client MAY include the "server_no_context_takeover" extension 576 parameter in an extension negotiation offer. This extension 577 parameter has no value. By including this extension parameter in an 578 extension negotiation offer, a client prevents the peer server from 579 using the same LZ77 sliding window it used to build frames of the 580 last sent message to build frames of the next message. If the peer 581 server doesn't use the same LZ77 sliding window to compress multiple 582 messages, the client doesn't need to reserve memory to retain the 583 LZ77 sliding window in between messages. 585 Absence of this extension parameter in an extension negotiation offer 586 indicates that the client can receive a message which the server has 587 built using the same LZ77 sliding window the server used to build the 588 last sent message. 590 A server accepts an extension negotiation offer including the 591 "server_no_context_takeover" extension parameter by including the 592 "server_no_context_takeover" extension parameter in an extension 593 negotiation response. The "server_no_context_takeover" extension 594 parameter in an extension negotiation response has no value. 596 It is RECOMMENDED that a server supports the 597 "server_no_context_takeover" extension parameter in an extension 598 negotiation offer. 600 A server MAY include the "server_no_context_takeover" extension 601 parameter in an extension negotiation response even if the extension 602 negotiation offer being accepted by the extension negotiation 603 response didn't have the "server_no_context_takeover" extension 604 parameter. 606 8.1.1.2. client_no_context_takeover 608 A client MAY include the "client_no_context_takeover" extension 609 parameter in an extension negotiation offer. This extension 610 parameter has no value. By including this extension parameter in an 611 extension negotiation offer, a client informs the peer server a hint 612 that even if the server won't include the 613 "client_no_context_takeover" extension parameter in the extension 614 negotiation response to the offer, the client is not going to use the 615 same LZ77 sliding window it used to build frames of the last sent 616 message to build frames of the next message. 618 A server MAY include the "client_no_context_takeover" extension 619 parameter in an extension negotiation response. If the received 620 extension negotiation offer includes the "client_no_context_takeover" 621 extension parameter, the server may either ignore it or use it to 622 avoid taking over an LZ77 sliding window unnecessarily by including 623 "client_no_context_takeover" extension parameter in the extension 624 negotiation response to the offer. The "client_no_context_takeover" 625 extension parameter in an extension negotiation response has no 626 value. By including the "client_no_context_takeover" extension 627 parameter in an extension negotiation response, a server prevents the 628 peer client from using the same LZ77 sliding window it used to build 629 frames of the last sent message to build frames for the next message. 630 This reduces the amount of memory that the server has to reserve for 631 the connection. 633 Absence of this extension parameter in an extension negotiation 634 response indicates that the server can receive a message which the 635 client has built using the same LZ77 sliding window the client used 636 to build the last sent message. 638 A client MUST support the "client_no_context_takeover" extension 639 parameter in an extension negotiation response. 641 8.1.2. Limiting the LZ77 sliding window size 643 8.1.2.1. server_max_window_bits 645 A client MAY include the "server_max_window_bits" extension parameter 646 in an extension negotiation offer. This extension parameter has a 647 decimal integer value without leading zeroes between 8 to 15 648 inclusive indicating the base-2 logarithm of the LZ77 sliding window 649 size and MUST conform to the ABNF below. 651 server_max_window_bits = 1*DIGIT 653 By including this parameter in an extension negotiation offer, a 654 client limits the LZ77 sliding window size that the server uses to 655 compress messages. If the peer server uses small LZ77 sliding window 656 to compress messages, the client can reduce the memory for the LZ77 657 sliding window. 659 A server declines an extension negotiation offer with this extension 660 parameter if the server doesn't support it. 662 Absence of this extension parameter in an extension negotiation offer 663 indicates that the client can receive messages compressed using an 664 LZ77 sliding window of up to 32,768 bytes. 666 A server accepts an extension negotiation offer with this extension 667 parameter by including the "server_max_window_bits" extension 668 parameter in the extension negotiation response with the same or 669 smaller value as the extension negotiation offer. The 670 "server_max_window_bits" extension parameter in an extension 671 negotiation response has a decimal integer value without leading 672 zeroes between 8 to 15 inclusive indicating the base-2 logarithm of 673 the LZ77 sliding window size and MUST conform to the ABNF below. 675 server_max_window_bits = 1*DIGIT 677 A server MAY include the "server_max_window_bits" extension parameter 678 in an extension negotiation response even if the extension 679 negotiation offer being accepted by the extension negotiation 680 response didn't include the "server_max_window_bits" extension 681 parameter. 683 8.1.2.2. client_max_window_bits 685 A client MAY include the "client_max_window_bits" extension parameter 686 in an extension negotiation offer. This extension parameter has no 687 value or a decimal integer value without leading zeroes between 8 to 688 15 inclusive indicating the base-2 logarithm of the LZ77 sliding 689 window size. If a value is specified for this extension parameter, 690 the value MUST conform to the ABNF below. 692 client_max_window_bits = 1*DIGIT 694 By including this extension parameter in an extension negotiation 695 offer, a client informs the peer server that the client supports the 696 "client_max_window_bits" extension parameter in an extension 697 negotiation response, and optionally a hint by including an extension 698 parameter value. If the "client_max_window_bits" extension parameter 699 in an extension negotiation offer has a value, the extension 700 parameter also informs the peer server a hint that even if the server 701 won't includes the "client_max_window_bits" extension parameter in an 702 extension negotiation response with a value greater than one in the 703 extension negotiation offer or the server doesn't include the 704 extension parameter at all, the client is not going to use LZ77 705 sliding window size greater than the size specified by the value in 706 the extension negotiation offer to compress messages. 708 If a received extension negotiation offer has the 709 "client_max_window_bits" extension parameter, the server MAY include 710 the "client_max_window_bits" extension parameter in the extension 711 negotiation response to the offer. If the "client_max_window_bits" 712 extension parameter in a received extension negotiation offer has a 713 value, the server may either ignore this value or use this value to 714 avoid allocating an unnecessarily big LZ77 sliding window by 715 including the "client_max_window_bits" extension parameter in the 716 extension negotiation response to the offer with a value equal to or 717 smaller than the received value. The "client_max_window_bits" 718 extension parameter in an extension negotiation response has a 719 decimal integer value without leading zeroes between 8 to 15 720 inclusive indicating the base-2 logarithm of the LZ77 sliding window 721 size and MUST conform to the ABNF below. 723 client_max_window_bits = 1*DIGIT 725 By including this extension parameter in an extension negotiation 726 response, a server limits the LZ77 sliding window size that the 727 client uses to compress messages. This reduces the amount of memory 728 that the server has to reserve for the connection. 730 If a received extension negotiation offer doesn't have the 731 "client_max_window_bits" extension parameter, the server MUST NOT 732 include the "client_max_window_bits" extension parameter in an 733 extension negotiation response to the offer. 735 Absence of this extension parameter in an extension negotiation 736 response indicates that the server can receive messages compressed 737 using an LZ77 sliding window of up to 32,768 bytes. 739 8.1.3. Example 741 The simplest "Sec-WebSocket-Extensions" header in a client's opening 742 handshake to offer use of the permessage-deflate is the following: 744 Sec-WebSocket-Extensions: permessage-deflate 746 Since the "client_max_window_bits" extension parameter is not 747 included in this extension negotiation offer, the server MUST NOT 748 accept the offer with an extension negotiation response including the 749 "client_max_window_bits" extension parameter. The simplest 750 "Sec-WebSocket-Extensions" header in a server's opening handshake to 751 accept use of the permessage-deflate is the same. 753 The following extension negotiation offer sent by a client is asking 754 the server to use the LZ77 sliding window size of 1,024 bytes or less 755 and declaring that the client supports the "client_max_window_bits" 756 extension parameter in an extension negotiation response. 758 Sec-WebSocket-Extensions: 759 permessage-deflate; 760 client_max_window_bits; server_max_window_bits=10 762 This extension negotiation offer might be rejected by the server 763 because the server doesn't support the "server_max_window_bits" 764 extension parameter in an extension negotiation offer. This is fine 765 if the client cannot receive messages compressed using a larger 766 sliding window size, but if the client wants to fallback to the 767 "permessage-deflate" without the "server_max_window_bits" extension 768 parameter, the client can offer the fallback option explicitly like 769 this: 771 Sec-WebSocket-Extensions: 772 permessage-deflate; 773 client_max_window_bits; server_max_window_bits=10, 774 permessage-deflate; 775 client_max_window_bits 777 This extension negotiation offer lists two configurations so that the 778 server can accept permessage-deflate by picking a supported one. To 779 accept the first option, the server might send back, for example: 781 Sec-WebSocket-Extensions: 782 permessage-deflate; server_max_window_bits=10 784 And to accept the second option, the server might send back, for 785 example: 787 Sec-WebSocket-Extensions: permessage-deflate 789 8.2. Message Payload Transformation 791 8.2.1. Compression 793 An endpoint uses the following algorithm to compress a message. 795 1. Compress all the octets of the payload of the message using 796 DEFLATE. 798 2. If the resulting data does not end with an empty DEFLATE block 799 with no compression (the "BTYPE" bits is set to 00), append an 800 empty DEFLATE block with no compression to the tail end. 802 3. Remove 4 octets (that are 0x00 0x00 0xff 0xff) from the tail end. 803 After this step, the last octet of the compressed data contains 804 (possibly part of) the DEFLATE header bits with the "BTYPE" bits 805 set to 00. 807 In using DEFLATE in the first step above: 809 o An endpoint MAY use multiple DEFLATE blocks to compress one 810 message. 812 o An endpoint MAY use DEFLATE blocks of any type. 814 o An endpoint MAY use both DEFLATE blocks with the "BFINAL" bit set 815 to 0 and DEFLATE blocks with the "BFINAL" bit set to 1. 817 o When any DEFLATE block with the "BFINAL" bit set to 1 doesn't end 818 at a byte boundary, an endpoint adds minimal padding bits of 0 to 819 make it end at a byte boundary. The next DEFLATE block follows 820 the padded data if any. 822 When the message is going to be fragmented, the concatenation of all 823 payload of the fragments must be the result of running this 824 algorithm. Even when only a part of payload is available, a fragment 825 can be built by compressing the available data and aligning the end 826 of compressed data at a byte boundary. Note that for non-final 827 fragments, removal of 0x00 0x00 0xff 0xff must not be done. 829 An endpoint MUST NOT use an LZ77 sliding window longer than 32,768 830 bytes to compress messages to send. 832 If the "agreed parameters" contain the "client_no_context_takeover" 833 extension parameter, the client MUST start compressing each new 834 message with an empty LZ77 sliding window. Otherwise, the client MAY 835 take over the LZ77 sliding window used to build the last compressed 836 message. Note that even if the client has included the 837 "client_no_context_takeover" extension parameter in its offer, the 838 client MAY take over the LZ77 sliding window used to build the last 839 compressed message if the "agreed parameters" doesn't contain the 840 "client_no_context_takeover" extension parameter. The client-to- 841 server "client_no_context_takeover" extension parameter is just a 842 hint for the server to build a response. 844 If the "agreed parameters" contain the "server_no_context_takeover" 845 extension parameter, the server MUST start compressing each new 846 message with an empty LZ77 sliding window. Otherwise, the server MAY 847 take over the LZ77 sliding window used to build the last compressed 848 message. 850 If the "agreed parameters" contain the "client_max_window_bits" 851 extension parameter with a value of w, the client MUST NOT use an 852 LZ77 sliding window longer than the w-th power of 2 bytes to compress 853 messages to send. Note that even if the client has included in its 854 offer the "client_max_window_bits" extension parameter with a value 855 smaller than one in the "agreed parameters", the client MAY use an 856 LZ77 sliding window with any size to compress messages to send as 857 long as the size conforms to the "agreed parameters". The client-to- 858 server "client_max_window_bits" extension parameter is just a hint 859 for the server to build a response. 861 If the "agreed parameters" contain the "server_max_window_bits" 862 extension parameter with a value of w, the server MUST NOT use an 863 LZ77 sliding window longer than the w-th power of 2 bytes to compress 864 messages to send. 866 8.2.2. Decompression 868 An endpoint uses the following algorithm to decompress a message. 870 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the 871 payload of the message. 873 2. Decompress the resulting data using DEFLATE. 875 If the "agreed parameters" contain the "server_no_context_takeover" 876 extension parameter, the client MAY start decompressing each new 877 message with an empty LZ77 sliding window. Otherwise, the client 878 MUST take over the LZ77 sliding window used to process the last 879 compressed message. 881 If the "agreed parameters" contain the "client_no_context_takeover" 882 extension parameter, the server MAY start decompressing each new 883 message with an empty LZ77 sliding window. Otherwise, the server 884 MUST take over the LZ77 sliding window used to process the last 885 compressed message. Note that even if the client has included the 886 "client_no_context_takeover" extension parameter in its offer, the 887 server MUST take over the LZ77 sliding window used to process the 888 last compressed message if the "agreed parameters" doesn't contain 889 the "client_no_context_takeover" extension parameter. The client-to- 890 server "client_no_context_takeover" extension parameter is just a 891 hint for the server to build a response. 893 If the "agreed parameters" contain the "server_max_window_bits" 894 extension parameter with a value of w, the client MAY reduce the size 895 of its LZ77 sliding window to decompress received messages down to 896 the w-th power of 2 bytes. Otherwise, the client MUST use a 32,768 897 byte LZ77 sliding window to decompress received messages. 899 If the "agreed parameters" contain the "client_max_window_bits" 900 extension parameter with a value of w, the server MAY reduce the size 901 of its LZ77 sliding window to decompress received messages down to 902 the w-th power of 2 bytes. Otherwise, the server MUST use a 32,768 903 byte LZ77 sliding window to decompress received messages. Note that 904 even if the client has included in its offer the 905 "client_max_window_bits" extension parameter with a value smaller 906 that one in the "agreed parameters", the client MUST use an LZ77 907 sliding window of a size that conforms the "agreed parameters" to 908 compress messages to send. The client-to-server 909 "client_max_window_bits" extension parameter is just a hint for the 910 server to build a response. 912 8.2.3. Examples 914 This section introduces examples of how the permessage-deflate 915 transforms messages. 917 8.2.3.1. A message compressed using 1 compressed DEFLATE block 919 Suppose that an endpoint sends a text message "Hello". If the 920 endpoint uses 1 compressed DEFLATE block (compressed with fixed 921 Huffman code and the "BFINAL" bit is not set) to compress the 922 message, the endpoint obtains the compressed data to use for the 923 message payload as follows. 925 The endpoint compresses "Hello" into 1 compressed DEFLATE block and 926 flushes the resulting data into a byte array using an empty DEFLATE 927 block with no compression: 929 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 0x00 0xff 0xff 931 By stripping 0x00 0x00 0xff 0xff from the tail end, the endpoint gets 932 the data to use for the message payload: 934 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 936 Suppose that the endpoint sends this compressed message without 937 fragmentation. The endpoint builds one frame by putting the whole 938 compressed data in the payload data portion of the frame: 940 0xc1 0x07 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 942 The first 2 octets (0xc1 0x07) are the WebSocket frame header (FIN=1, 943 RSV1=1, RSV2=0, RSV3=0, opcode=text, MASK=0, Payload length=7). The 944 following figure shows what value is set in each field of the 945 WebSocket frame header. 947 0 1 948 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 949 +-+-+-+-+-------+-+-------------+ 950 |F|R|R|R| opcode|M| Payload len | 951 |I|S|S|S| |A| | 952 |N|V|V|V| |S| | 953 | |1|2|3| |K| | 954 +-+-+-+-+-------+-+-------------+ 955 |1|1|0|0| 1 |0| 7 | 956 +-+-+-+-+-------+-+-------------+ 958 Suppose that the endpoint sends the compressed message with 959 fragmentation. The endpoint splits the compressed data into 960 fragments and builds frames for each fragment. For example, if the 961 fragments are 3 and 4 octet, the first frame is: 963 0x41 0x03 0xf2 0x48 0xcd 965 and the second frame is: 967 0x80 0x04 0xc9 0xc9 0x07 0x00 969 Note that the RSV1 bit is set only on the first frame. 971 8.2.3.2. Sharing LZ77 Sliding Window 973 Suppose that a client has sent a message "Hello" as a compressed 974 message and will send the same message "Hello" again as a compressed 975 message. 977 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 979 This is the payload of the first message the client has sent. If the 980 "agreed parameters" contain the "client_no_context_takeover" 981 extension parameter, the client compresses the payload of the next 982 message into the same bytes (if the client uses the same "BTYPE" 983 value and "BFINAL" value). So, the payload of the second message 984 will be: 986 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 988 When concatenated with the first message: 990 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 0xf2 0x48 0xcd 0xc9 0xc9 991 0x07 0x00 993 If the "agreed parameters" did not contain the 994 "client_no_context_takeover" extension parameter, the client can 995 compress the payload of the next message into shorter bytes by 996 referencing the history in the LZ77 sliding window. So, the payload 997 of the second message will be: 999 0xf2 0x00 0x11 0x00 0x00 1001 When concatenated with the first message: 1003 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 0xf2 0x00 0x11 0x00 0x00 1005 So, 2 bytes were saved in total. 1007 Note that even if some uncompressed messages (with the RSV1 bit 1008 unset) are inserted between the two "Hello" messages, they will make 1009 no difference to the LZ77 sliding window. 1011 8.2.3.3. Using a DEFLATE Block with No Compression 1013 0xc1 0x0b 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 1015 This is a frame constituting a text message "Hello" compressed using 1016 a DEFLATE block with no compression. The first 2 octets (0xc1 0x0b) 1017 are the WebSocket frame header (FIN=1, RSV1=1, RSV2=0, RSV3=0, 1018 opcode=text, MASK=0, Payload length=7). Note that the RSV1 bit is 1019 set for this message (only on the first fragment if the message is 1020 fragmented) because the RSV1 bit is set when DEFLATE is applied to 1021 the message, including the case when only DEFLATE blocks with no 1022 compression are used. The third to 13th octet consists a payload 1023 data containing "Hello" compressed using a DEFLATE block with no 1024 compression. 1026 8.2.3.4. Using a DEFLATE Block with BFINAL Set to 1 1028 On platform where the flush method using an empty DEFLATE block with 1029 no compression is not avaiable, implementors can choose to flush data 1030 using DEFLATE blocks with "BFINAL" set to 1. 1032 0xf3 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 1034 This is a payload of a message containing "Hello" compressed using a 1035 DEFLATE block with "BFINAL" set to 1. The first 7 octets constitute 1036 a DEFLATE block with "BFINAL" set to 1 and "BTYPE" set to 01 1037 containing "Hello". The last 1 octet (0x00) contains the header bits 1038 with "BFINAL" set to 0 and "BTYPE" set to 00, and 5 padding bits of 1039 0. This octet is necessary to allow the payload to be decompressed 1040 in the same manner as messages flushed using DEFLATE blocks with 1041 BFINAL unset. 1043 8.2.3.5. Two DEFLATE Blocks in 1 Message 1045 Two or more DEFLATE blocks may be used in 1 message. 1047 0xf2 0x48 0x05 0x00 0x00 0x00 0xff 0xff 0xca 0xc9 0xc9 0x07 0x00 1049 The first 3 octets (0xf2 0x48 0x05) and the least significant two 1050 bits of the 4th octet (0x00) constitute one DEFLATE block with 1051 "BFINAL" set to 0 and "BTYPE" set to 01 containing "He". The rest of 1052 the 4th octet contains the header bits with "BFINAL" set to 0 and 1053 "BTYPE" set to 00, and the 3 padding bits of 0. Together with the 1054 following 4 octets (0x00 0x00 0xff 0xff), the header bits constitute 1055 an empty DEFLATE block with no compression. A DEFLATE block 1056 containing "llo" follows the empty DEFLATE block. 1058 8.2.3.6. Generating an Empty Fragment Manually 1060 Suppose that an endpoint is sending data with unknown size. The 1061 endpoint may encounter the end of data signal from the data source 1062 when its buffer for uncompressed data is empty. In such a case, the 1063 endpoint just needs to send the last fragment with FIN bit set to 1 1064 and payload set to DEFLATE block(s) which contains 0 byte data. If 1065 the compression library being used doesn't generate any data when its 1066 buffer is empty, an empty uncompressed DEFLATE block can be built 1067 manually and used for this purpose as follows: 1069 0x00 1071 The only octet 0x00 contains the header bits with "BFINAL" set to 0 1072 and "BTYPE" set to 00, and 5 padding bits of 0. 1074 8.3. Implementation Notes 1076 On most common software development platforms, their DEFLATE 1077 compression library provides a method to align compressed data to 1078 byte boundaries using an empty DEFLATE block with no compression. 1079 For example, Zlib [Zlib] does this when "Z_SYNC_FLUSH" is passed to 1080 the deflate function. 1082 Some platforms may provide only methods to output and process 1083 compressed data with ZLIB header and Adler-32 checksum. On such 1084 platforms, developers need to write stub code to remove and 1085 complement them manually. 1087 To obtain a useful compression ratio, an LZ77 sliding window size of 1088 1,024 or more is RECOMMENDED. 1090 On the direction where context takeover is disallowed, an endpoint 1091 can easily figure out whether a certain message will be shorter if 1092 compressed or not.. Otherwise, it's not easy to know whether future 1093 messages will benefit from having a certain message compressed. 1094 Implementor may employ some heuristics to determine this. 1096 8.4. Intermediaries 1098 When an intermediary forwards a message, the intermediary MAY change 1099 compression on the messages as far as the resulting sequence of 1100 messages conform to the constraints based on the "agreed parameters". 1101 For example, an intermediary may decompress a received message, unset 1102 the "Per-message Compressed" bit and forward it to the other peer. 1103 Since such a compression change may affect the LZ77 sliding window, 1104 the intermediary may need to parse and transform the following 1105 messages, too. 1107 9. Security Considerations 1109 There is a known exploit for combination of a secure transport 1110 protocol and history-based compression [CRIME]. Implementors should 1111 give attention to this point when integrating this extension with 1112 other extensions or protocols. 1114 10. IANA Considerations 1116 10.1. Registration of the "permessage-deflate" WebSocket Extension Name 1118 This section describes a WebSocket extension name registration in the 1119 WebSocket Extension Name Registry [RFC6455]. 1121 Extension Identifier 1122 permessage-deflate 1124 Extension Common Name 1125 WebSocket Per-message Deflate 1127 Extension Definition 1128 This document. 1130 Known Incompatible Extensions 1131 None 1133 The "permessage-deflate" extension name is used in the 1134 "Sec-WebSocket-Extensions" header in the WebSocket opening handshake 1135 to negotiate use of the permessage-deflate extension. 1137 10.2. Registration of the "Per-message Compressed" WebSocket Framing 1138 Header Bit 1140 This section describes a WebSocket framing header bit registration in 1141 the WebSocket Framing Header Bits Registry [RFC6455]. 1143 Header Bit 1144 RSV1 1146 Common Name 1147 Per-message Compressed 1149 Meaning 1150 The message is compressed or not. 1152 Reference 1153 Section 6 of this document. 1155 The "Per-message Compressed" framing header bit is used on the first 1156 fragment of non-control messages to indicate whether the payload of 1157 the message is compressed by the PMCE or not. 1159 11. Acknowledgements 1161 Special thanks to Patrick McManus who wrote up the initial 1162 specification of a DEFLATE-based compression extension for the 1163 WebSocket Protocol to which I referred to write this specification. 1165 Thank you to the following people who participated in discussions on 1166 the HyBi WG and contributed ideas and/or provided detailed reviews 1167 (the list is likely to be incomplete): Adam Rice, Alexey Melnikov, 1168 Arman Djusupov, Bjoern Hoehrmann, Brian McKelvey, Dario Crivelli, 1169 Greg Wilkins, Inaki Baz Castillo, Jamie Lokier, Joakim Erdfelt, John 1170 A. Tamplin, Julian Reschke, Kenichi Ishibashi, Mark Nottingham, Peter 1171 Thorson, Roberto Peon, Simone Bordet and Tobias Oberstein. Note that 1172 people listed above didn't necessarily endorse the end result of this 1173 work. 1175 12. References 1177 12.1. Normative References 1179 [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification 1180 version 1.3", RFC 1951, May 1996. 1182 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 1183 Specifications: ABNF", STD 68, RFC 5234, January 2008. 1185 [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", 1186 RFC 6455, December 2011. 1188 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1189 Requirement Levels", BCP 14, RFC 2119, March 1997. 1191 [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for 1192 Sequential Data Compression", IEEE Transactions on 1193 Information Theory, Vol. 23, No. 3, pp. 337-343. 1195 12.2. Informative References 1197 [RFC1979] Woods, J., "PPP Deflate Protocol", RFC 1979, August 1996. 1199 [Zlib] Gailly, J. and M. Adler, "Zlib", . 1201 [CRIME] Rizzo, J. and T. Duong, "The CRIME attack", Ekoparty 2012, 1202 September 2012. 1204 Author's Address 1206 Takeshi Yoshino 1207 Google, Inc. 1209 Email: tyoshino@google.com