| < draft-ietf-hybi-permessage-compression-22.txt | draft-ietf-hybi-permessage-compression-28.txt > | |||
|---|---|---|---|---|
| HyBi Working Group T. Yoshino | HyBi Working Group T. Yoshino | |||
| Internet-Draft Google, Inc. | Internet-Draft Google, Inc. | |||
| Intended status: Standards Track June 11, 2015 | Intended status: Standards Track August 24, 2015 | |||
| Expires: December 13, 2015 | Expires: February 25, 2016 | |||
| Compression Extensions for WebSocket | Compression Extensions for WebSocket | |||
| draft-ietf-hybi-permessage-compression-22 | draft-ietf-hybi-permessage-compression-28 | |||
| Abstract | Abstract | |||
| This document defines a framework for creating WebSocket extensions | This document defines a framework for creating WebSocket extensions | |||
| that add compression functionality to the WebSocket Protocol. An | that add compression functionality to the WebSocket Protocol. An | |||
| extension based on this framework compresses the payload data portion | extension based on this framework compresses the payload data portion | |||
| of WebSocket data messages on a per-message basis using parameters | of WebSocket data messages on a per-message basis using parameters | |||
| negotiated during the opening handshake. This framework provides a | negotiated during the opening handshake. This framework provides a | |||
| general method for applying a compression algorithm to the contents | general method for applying a compression algorithm to the contents | |||
| of WebSocket messages. Each compression algorithm has to be defined | of WebSocket messages. Each compression algorithm has to be defined | |||
| skipping to change at page 1, line 42 ¶ | skipping to change at page 1, line 42 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at http://datatracker.ietf.org/drafts/current. | Drafts is at http://datatracker.ietf.org/drafts/current. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on December 13, 2015. | This Internet-Draft will expire on February 25, 2016. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2015 IETF Trust and the persons identified as the | Copyright (c) 2015 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| skipping to change at page 2, line 25 ¶ | skipping to change at page 2, line 25 ¶ | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 2. Conformance Requirements and Terminology . . . . . . . . . . . 4 | 2. Conformance Requirements and Terminology . . . . . . . . . . . 4 | |||
| 3. Complementary Terminology . . . . . . . . . . . . . . . . . . 5 | 3. Complementary Terminology . . . . . . . . . . . . . . . . . . 5 | |||
| 4. WebSocket Per-message Compression Extension . . . . . . . . . 6 | 4. WebSocket Per-message Compression Extension . . . . . . . . . 6 | |||
| 5. Extension Negotiation . . . . . . . . . . . . . . . . . . . . 7 | 5. Extension Negotiation . . . . . . . . . . . . . . . . . . . . 7 | |||
| 5.1. General Negotiation Flow . . . . . . . . . . . . . . . . . 9 | 5.1. General Negotiation Flow . . . . . . . . . . . . . . . . . 9 | |||
| 5.2. Negotiation Examples . . . . . . . . . . . . . . . . . . . 10 | 5.2. Negotiation Examples . . . . . . . . . . . . . . . . . . . 10 | |||
| 6. Framing . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 | 6. Framing . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 6.1. Compression . . . . . . . . . . . . . . . . . . . . . . . 12 | 6.1. Compression . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 6.2. Decompression . . . . . . . . . . . . . . . . . . . . . . 13 | 6.2. Decompression . . . . . . . . . . . . . . . . . . . . . . 13 | |||
| 7. Intermediaries . . . . . . . . . . . . . . . . . . . . . . . . 15 | 7. The permessage-deflate extension . . . . . . . . . . . . . . . 15 | |||
| 8. permessage-deflate extension . . . . . . . . . . . . . . . . . 16 | 7.1. Extension Parameters . . . . . . . . . . . . . . . . . . . 16 | |||
| 8.1. Method Parameters . . . . . . . . . . . . . . . . . . . . 17 | 7.1.1. Context Takeover Control . . . . . . . . . . . . . . . 16 | |||
| 8.1.1. Context Takeover Control . . . . . . . . . . . . . . . 17 | 7.1.2. Limiting the LZ77 sliding window size . . . . . . . . 18 | |||
| 8.1.2. Limiting the LZ77 sliding window size . . . . . . . . 19 | 7.1.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 20 | |||
| 8.1.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 21 | 7.2. Message Payload Transformation . . . . . . . . . . . . . . 21 | |||
| 8.2. Message Payload Transformation . . . . . . . . . . . . . . 22 | 7.2.1. Compression . . . . . . . . . . . . . . . . . . . . . 21 | |||
| 8.2.1. Compression . . . . . . . . . . . . . . . . . . . . . 22 | 7.2.2. Decompression . . . . . . . . . . . . . . . . . . . . 22 | |||
| 8.2.2. Decompression . . . . . . . . . . . . . . . . . . . . 23 | 7.2.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 23 | |||
| 8.2.3. Examples . . . . . . . . . . . . . . . . . . . . . . . 24 | 7.3. Implementation Notes . . . . . . . . . . . . . . . . . . . 27 | |||
| 8.3. Implementation Notes . . . . . . . . . . . . . . . . . . . 28 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 28 | |||
| 8.4. Intermediaries . . . . . . . . . . . . . . . . . . . . . . 28 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 29 | |||
| 9. Security Considerations . . . . . . . . . . . . . . . . . . . 29 | 9.1. Registration of the "permessage-deflate" WebSocket | |||
| 10. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 | Extension Name . . . . . . . . . . . . . . . . . . . . . . 29 | |||
| 10.1. Registration of the "permessage-deflate" WebSocket | 9.2. Registration of the "Per-message Compressed" WebSocket | |||
| Extension Name . . . . . . . . . . . . . . . . . . . . . . 30 | Framing Header Bit . . . . . . . . . . . . . . . . . . . . 29 | |||
| 10.2. Registration of the "Per-message Compressed" WebSocket | 10. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 30 | |||
| Framing Header Bit . . . . . . . . . . . . . . . . . . . . 30 | 11. References . . . . . . . . . . . . . . . . . . . . . . . . . . 31 | |||
| 11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 31 | 11.1. Normative References . . . . . . . . . . . . . . . . . . . 31 | |||
| 12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 32 | 11.2. Informative References . . . . . . . . . . . . . . . . . . 31 | |||
| 12.1. Normative References . . . . . . . . . . . . . . . . . . . 32 | Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 32 | |||
| 12.2. Informative References . . . . . . . . . . . . . . . . . . 32 | ||||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 33 | ||||
| 1. Introduction | 1. Introduction | |||
| This document specifies a framework for adding compression | This document specifies a framework for adding compression | |||
| functionality to the WebSocket Protocol [RFC6455]. The framework | functionality to the WebSocket Protocol [RFC6455]. The framework | |||
| specifies how to define WebSocket Per-message Compression Extensions | specifies how to define WebSocket Per-message Compression Extensions | |||
| (PMCEs) for a compression algorithm based on the extension concept of | (PMCEs) for a compression algorithm based on the extension concept of | |||
| the WebSocket Protocol specified in Section 9 of [RFC6455]. A | the WebSocket Protocol specified in Section 9 of [RFC6455]. A | |||
| WebSocket client and a peer WebSocket server negotiate the use of a | WebSocket client and a peer WebSocket server negotiate the use of a | |||
| PMCE and determine the parameters required to configure the | PMCE and determine the parameters required to configure the | |||
| skipping to change at page 5, line 9 ¶ | skipping to change at page 5, line 9 ¶ | |||
| respectively, of [RFC6455]. | respectively, of [RFC6455]. | |||
| This document uses the Augmented Backus-Naur Form (ABNF) notation of | This document uses the Augmented Backus-Naur Form (ABNF) notation of | |||
| [RFC5234]. The DIGIT (decimal 0-9) rule is included by reference, as | [RFC5234]. The DIGIT (decimal 0-9) rule is included by reference, as | |||
| defined in the Appendix B.1 of [RFC5234]. | defined in the Appendix B.1 of [RFC5234]. | |||
| 3. Complementary Terminology | 3. Complementary Terminology | |||
| This document defines some terms about WebSocket and WebSocket | This document defines some terms about WebSocket and WebSocket | |||
| Extension mechanisms that are underspecified or not defined at all in | Extension mechanisms that are underspecified or not defined at all in | |||
| [RFC6455]. This terminology is effective only in this document and | [RFC6455]. | |||
| any other documents explicitly referring to this section. | ||||
| "A data message" means a message consisting of Data Frames as defined | "A data message" means a message consisting of Data Frames as defined | |||
| in Section 5.6 of [RFC6455]. | in Section 5.6 of [RFC6455]. | |||
| "A message payload (or payload of a message)" means the concatenation | "A message payload (or payload of a message)" means the concatenation | |||
| of the payload data portion of all Data Frames (see Section 6.2 of | of the payload data portion of all Data Frames (see Section 6.2 of | |||
| [RFC6455]) representing a single message. | [RFC6455]) representing a single message. | |||
| "An extension in use next to extension X" means the extension listed | "The next extension in use after extension X" means the next | |||
| next to X in the "Sec-WebSocket-Extensions" header in the server's | extension listed after X in the "Sec-WebSocket-Extensions" header in | |||
| opening handshake as defined in Section 9.1 of [RFC6455]. Such an | the server's opening handshake as defined in Section 9.1 of | |||
| extension is applied to outgoing data from the application right | [RFC6455]. Such an extension is applied to outgoing data from the | |||
| after X on the sender side, but applied right before X to incoming | application right after X on the sender side, but applied right | |||
| data from the underlying transport. | before X to incoming data from the underlying transport. | |||
| "An extension in use preceding extension X" means the extension | "An extension in use preceding extension X" means the extension | |||
| listed right before X in the "Sec-WebSocket-Extensions" header in the | listed right before X in the "Sec-WebSocket-Extensions" header in the | |||
| server's opening handshake. Such an extension is applied to outgoing | server's opening handshake. Such an extension is applied to outgoing | |||
| data from the application right before X on the sender side, but | data from the application right before X on the sender side, but | |||
| applied right after X to incoming data from the underlying transport. | applied right after X to incoming data from the underlying transport. | |||
| "An extension negotiation offer" means each element in the | "An extension negotiation offer" means each element in the | |||
| "Sec-WebSocket-Extensions" header in the client's opening handshake. | "Sec-WebSocket-Extensions" header in the client's opening handshake. | |||
| skipping to change at page 6, line 25 ¶ | skipping to change at page 6, line 25 ¶ | |||
| o The extension name of the PMCE and any applicable extension | o The extension name of the PMCE and any applicable extension | |||
| parameters that MUST be included in the "Sec-WebSocket-Extensions" | parameters that MUST be included in the "Sec-WebSocket-Extensions" | |||
| header during the extension negotiation offer/response. | header during the extension negotiation offer/response. | |||
| o How to interpret the extension parameters exchanged during the | o How to interpret the extension parameters exchanged during the | |||
| opening handshake. | opening handshake. | |||
| o How to transform the payload of a message. | o How to transform the payload of a message. | |||
| One PMCE extension is defined in Section 8 of this document and is | One PMCE is defined in Section 7 of this document and is registered | |||
| registered in Section 10. Other PMCEs may be defined in the future | in Section 9. Other PMCEs may be defined in the future in other | |||
| in other documents. | documents. | |||
| Section 5 describes the basic extension negotiation process. | Section 5 describes the basic extension negotiation process. | |||
| Section 6 describes how to apply the compression algorithm with | Section 6 describes how to apply the compression algorithm with | |||
| negotiated parameters to the contents of WebSocket messages. | negotiated parameters to the contents of WebSocket messages. | |||
| 5. Extension Negotiation | 5. Extension Negotiation | |||
| To offer use of a PMCE, a client MUST include the extension name of | To offer use of a PMCE, a client MUST include the extension name of | |||
| the PMCE in the "Sec-WebSocket-Extensions" header field of its | the PMCE in the "Sec-WebSocket-Extensions" header field of its | |||
| opening handshake of the WebSocket connection. Extension parameters | opening handshake of the WebSocket connection. Extension parameters | |||
| skipping to change at page 7, line 50 ¶ | skipping to change at page 7, line 50 ¶ | |||
| A hint in a PMCE negotiation offer provides information about the | A hint in a PMCE negotiation offer provides information about the | |||
| client's behavior that the server may either safely ignore or refer | client's behavior that the server may either safely ignore or refer | |||
| to when the server decides its behavior. For example, suppose that a | to when the server decides its behavior. For example, suppose that a | |||
| client sends data compressed with the DEFLATE algorithm to a server. | client sends data compressed with the DEFLATE algorithm to a server. | |||
| The client must keep the original bytes of data that it recently | The client must keep the original bytes of data that it recently | |||
| compressed and sent to the server. The server must keep the result | compressed and sent to the server. The server must keep the result | |||
| of decompressing the bytes of data that it recently received from the | of decompressing the bytes of data that it recently received from the | |||
| client. The LZ77 window size of the server must not be less than the | client. The LZ77 window size of the server must not be less than the | |||
| LZ77 window size of the client. In a PMCE negotiation offer, the | LZ77 window size of the client. In a PMCE negotiation offer, the | |||
| client may inform the maximum LZ77 window size the client can afford | client MAY inform the maximum LZ77 window size the client can afford | |||
| so that the server can choose to use an LZ77 window size that is not | so that the server can choose to use an LZ77 window size that is not | |||
| greater than the maximum size of the client. This information is an | greater than the maximum size of the client. This information is an | |||
| example of a hint in a PMCE negotiation offer. It's waste of memory | example of a hint in a PMCE negotiation offer. It's waste of memory | |||
| to use an LZ77 window size greater than the LZ77 window size the | to use an LZ77 window size greater than the LZ77 window size the | |||
| client actually uses. Using the hint, the server can avoid the waste | client actually uses. Using the hint, the server can avoid the waste | |||
| of memory. Since the hint itself doesn't specify the constraints on | of memory. Since the hint itself doesn't specify the constraints on | |||
| the endpoints, the server must use the "agreed parameters" (defined | the endpoints, the server must use the "agreed parameters" (defined | |||
| below) to explicitly ask the client not to use an LZ77 window size | below) to explicitly ask the client not to use an LZ77 window size | |||
| greater than the LZ77 window size of the server. | greater than the LZ77 window size of the server. | |||
| skipping to change at page 8, line 29 ¶ | skipping to change at page 8, line 29 ¶ | |||
| need to be exactly the same as those of the received extension | need to be exactly the same as those of the received extension | |||
| negotiation offers. For example, suppose that a server received a | negotiation offers. For example, suppose that a server received a | |||
| PMCE extension negotiation offer with an extension parameter "X" | PMCE extension negotiation offer with an extension parameter "X" | |||
| indicating that the client can enable an optional feature named X. | indicating that the client can enable an optional feature named X. | |||
| The server may accept the PMCE offer with an element without the | The server may accept the PMCE offer with an element without the | |||
| extension parameter "X" meaning that the server chose not to enable | extension parameter "X" meaning that the server chose not to enable | |||
| the feature X. In this case, the offer contains the extension | the feature X. In this case, the offer contains the extension | |||
| parameter "X" but the "agreed parameters" don't contain the extension | parameter "X" but the "agreed parameters" don't contain the extension | |||
| parameter "X". | parameter "X". | |||
| "Agreed parameters" MUST represent how the requests and hints in the | "Agreed parameters" must represent how the requests and hints in the | |||
| client's extension negotiation offer have been handled in addition to | client's extension negotiation offer have been handled in addition to | |||
| the server's requests and hints on the client's behavior, so that the | the server's requests and hints on the client's behavior, so that the | |||
| client can configure its behavior without identifying exactly which | client can configure its behavior without identifying exactly which | |||
| PMCE extension negotiation offer has been accepted. | PMCE extension negotiation offer has been accepted. | |||
| For example, if a client sends an extension negotiation offer that | For example, if a client sends an extension negotiation offer that | |||
| includes a parameter "enable_compression" and another without this | includes a parameter "enable_compression" and another without this | |||
| parameter, the server accepts the former and informs the client by | parameter, the server accepts the former and informs the client by | |||
| sending back an element that includes parameter(s) acknowledging | sending back an element that includes parameter(s) acknowledging | |||
| "enable_compression". The name of the acknowledging parameter | "enable_compression". The name of the acknowledging parameter | |||
| skipping to change at page 10, line 40 ¶ | skipping to change at page 10, line 40 ¶ | |||
| algorithm foo and bar. | algorithm foo and bar. | |||
| o Offer the permessage-foo. | o Offer the permessage-foo. | |||
| permessage-foo | permessage-foo | |||
| o Offer the permessage-foo with a parameter x with a value of 10. | o Offer the permessage-foo with a parameter x with a value of 10. | |||
| permessage-foo; x=10 | permessage-foo; x=10 | |||
| The value MAY be quoted. | The value may be quoted. | |||
| permessage-foo; x="10" | permessage-foo; x="10" | |||
| o Offer the permessage-foo as first choice and the permessage-bar as | o Offer the permessage-foo as first choice and the permessage-bar as | |||
| a fallback plan. | a fallback plan. | |||
| permessage-foo, permessage-bar | permessage-foo, permessage-bar | |||
| o Offer the permessage-foo with a parameter use_y which enables a | o Offer the permessage-foo with a parameter use_y which enables a | |||
| feature y as first choice, and the permessage-foo without the | feature y as first choice, and the permessage-foo without the | |||
| skipping to change at page 12, line 43 ¶ | skipping to change at page 12, line 43 ¶ | |||
| An endpoint MUST use the following algorithm to send a message in the | An endpoint MUST use the following algorithm to send a message in the | |||
| form of a compressed message. | form of a compressed message. | |||
| 1. Compress the message payload of the original message by following | 1. Compress the message payload of the original message by following | |||
| the compression procedure of the PMCE. The original message may | the compression procedure of the PMCE. The original message may | |||
| be input from the application layer or output of another | be input from the application layer or output of another | |||
| WebSocket extension depending on which extensions were | WebSocket extension depending on which extensions were | |||
| negotiated. | negotiated. | |||
| 2. If this PMCE is the last extension to process of outgoing | 2. Process the compressed data as follows: | |||
| messages, build frame(s) by using the compressed data instead of | ||||
| the original data for the message payload, and set the | * If this PMCE is the last extension to process of outgoing | |||
| "Per-message Compressed" bit of the first frame, then send the | messages, build frame(s) by using the compressed data instead | |||
| frame(s) as described in Section 6.1 of RFC6455. Otherwise, pass | of the original data for the message payload, and set the | |||
| the transformed message payload and modified header values | "Per-message Compressed" bit of the first frame, then send the | |||
| including the "Per-message Compressed" bit value set to 1 to the | frame(s) as described in Section 6.1 of RFC6455. | |||
| extension next to the PMCE. If the extension expects frames for | ||||
| input, build a frame for the message and pass it. | * Otherwise, pass the transformed message payload and modified | |||
| header values including the "Per-message Compressed" bit value | ||||
| set to 1 to the next extension after the PMCE. If the | ||||
| extension expects frames for input, build a frame for the | ||||
| message and pass it. | ||||
| An endpoint MUST use the following algorithm to send a message in the | An endpoint MUST use the following algorithm to send a message in the | |||
| form of an uncompressed message. | form of an uncompressed message. | |||
| 1. If this PMCE is the last extension to process of outgoing | 1. Process the original data as follows: | |||
| messages, build frame(s) by using the original data for the | ||||
| payload data portion as-is and unset the "Per-message Compressed" | * If this PMCE is the last extension to process of outgoing | |||
| bit of the first frame, then send the frame(s) as described in | messages, build frame(s) by using the original data for the | |||
| Section 6.1 of RFC6455. Otherwise, pass the message payload and | payload data portion as-is and unset the "Per-message | |||
| header values to the extension next to the PMCE as-is. If the | Compressed" bit of the first frame, then send the frame(s) as | |||
| extension expects frames for input, build a frame for the message | described in Section 6.1 of RFC6455. | |||
| and pass it. | ||||
| * Otherwise, pass the message payload and header values to the | ||||
| next extension after the PMCE as-is. If the extension expects | ||||
| frames for input, build a frame for the message and pass it. | ||||
| An endpoint MUST NOT set the "Per-message Compressed" bit of control | An endpoint MUST NOT set the "Per-message Compressed" bit of control | |||
| frames and non-first fragments of a data message. An endpoint | frames and non-first fragments of a data message. An endpoint | |||
| receiving such a frame MUST _Fail the WebSocket Connection_. | receiving such a frame MUST _Fail the WebSocket Connection_. | |||
| PMCEs do not change the opcode field. The opcode of the first frame | PMCEs do not change the opcode field. The opcode of the first frame | |||
| of a compressed message indicates the opcode of the original message. | of a compressed message indicates the opcode of the original message. | |||
| The payload data portion in frames generated by a PMCE is not subject | The payload data portion in frames generated by a PMCE is not subject | |||
| to the constraints for the original data type. For example, the | to the constraints for the original data type. For example, the | |||
| skipping to change at page 13, line 45 ¶ | skipping to change at page 14, line 5 ¶ | |||
| the form of a compressed message. | the form of a compressed message. | |||
| 1. Concatenate the payload data portion of the received frames of | 1. Concatenate the payload data portion of the received frames of | |||
| the compressed message. The received frames may be direct input | the compressed message. The received frames may be direct input | |||
| from the underlying transport or output of another WebSocket | from the underlying transport or output of another WebSocket | |||
| extension depending on which extensions were negotiated. | extension depending on which extensions were negotiated. | |||
| 2. Decompress the concatenation by following the decompression | 2. Decompress the concatenation by following the decompression | |||
| procedure of the PMCE. | procedure of the PMCE. | |||
| 3. If this is the last extension to process incoming messages, | 3. Process the decompressed message as follows: | |||
| deliver the _A WebSocket Message Has Been Received_ event to the | ||||
| application layer with the decompressed message payload and | ||||
| header values including the "Per-message Compressed" bit unset to | ||||
| 0. Otherwise, pass the decompressed message payload and header | ||||
| values including the "Per-message Compressed" bit unset to 0 to | ||||
| the extension preceding the PMCE. If the extension expects | ||||
| frames for input, build a frame for the message and pass it. | ||||
| An endpoint MUST use the following algorithm to receive a message in | ||||
| the form of an uncompressed message. | ||||
| 1. If this PMCE is the last extension to process incoming messages, | ||||
| deliver the _A WebSocket Message Has Been Received_ event to the | ||||
| application layer with the received message payload and header | ||||
| values as-is. Otherwise, pass the message payload and header | ||||
| values to the extension preceding the PMCE as-is. If the | ||||
| extension expects frames for input, build a frame for the message | ||||
| and pass it. | ||||
| 7. Intermediaries | * If this is the last extension to process incoming messages, | |||
| deliver the _A WebSocket Message Has Been Received_ event to | ||||
| the application layer with the decompressed message payload | ||||
| and header values including the "Per-message Compressed" bit | ||||
| unset to 0. | ||||
| When an intermediary proxies a WebSocket connection, the intermediary | * Otherwise, pass the decompressed message payload and header | |||
| MAY add, change or remove Per-message Compression of proxied messages | values including the "Per-message Compressed" bit unset to 0 | |||
| if the intermediary meets all of the following requirements: | to the extension preceding the PMCE. If the extension expects | |||
| frames for input, build a frame for the message and pass it. | ||||
| o The intermediary understands the PMCE. | An endpoint MUST use the following algorithm to receive a message in | |||
| the form of an uncompressed message. | ||||
| o The intermediary can read all data of the proxied WebSocket | 1. Process the received message as follows: | |||
| connection including the opening handshake request, opening | ||||
| handshake response, and messages. | ||||
| o The intermediary can alter the proxied data before forwarding them | * If this PMCE is the last extension to process incoming | |||
| in accordance with to the constraints of the new combination of | messages, deliver the _A WebSocket Message Has Been Received_ | |||
| extensions. For example, if Per-message Compression is removed | event to the application layer with the received message | |||
| from messages, the corresponding element in the | payload and header values as-is. | |||
| "Sec-WebSocket-Extensions" header in the opening handshake | ||||
| response which enabled the Per-message Compression must also be | ||||
| removed. | ||||
| Otherwise, the intermediary MUST NOT add, change or remove Per- | * Otherwise, pass the message payload and header values to the | |||
| message Compression of proxied messages. | extension preceding the PMCE as-is. If the extension expects | |||
| frames for input, build a frame for the message and pass it. | ||||
| 8. permessage-deflate extension | 7. The permessage-deflate extension | |||
| This section defines a specific PMCE called "permessage-deflate". It | This section defines a specific PMCE called "permessage-deflate". It | |||
| compresses the payload of a message using the DEFLATE algorithm | compresses the payload of a message using the DEFLATE algorithm | |||
| [RFC1951] and uses the byte boundary alignment method introduced in | [RFC1951] and uses the byte boundary alignment method introduced in | |||
| [RFC1979]. | [RFC1979]. | |||
| This section uses the term "byte" with the same meaning as RFC1951, | This section uses the term "byte" with the same meaning as RFC1951, | |||
| i.e. 8 bits stored or transmitted as a unit (same as an octet). | i.e. 8 bits stored or transmitted as a unit (same as an octet). | |||
| The registered extension name for this extension is | The registered extension name for this extension is | |||
| skipping to change at page 17, line 24 ¶ | skipping to change at page 16, line 24 ¶ | |||
| o The negotiation response contains an extension parameter with an | o The negotiation response contains an extension parameter with an | |||
| invalid value. | invalid value. | |||
| o The negotiation response contains multiple extension parameters | o The negotiation response contains multiple extension parameters | |||
| with the same name. | with the same name. | |||
| o The client does not support the configuration that the response | o The client does not support the configuration that the response | |||
| represents. | represents. | |||
| The term "LZ77 sliding window" used in this section means the buffer | The term "LZ77 sliding window" [LZ77] used in this section means the | |||
| used by the DEFLATE algorithm to store recently processed input. The | buffer used by the DEFLATE algorithm to store recently processed | |||
| DEFLATE compression algorithm searches the buffer for a match with | input. The DEFLATE compression algorithm searches the buffer for a | |||
| the following input. | match with the following input. | |||
| The term "use context take over" used in this section means that the | The term "use context take over" used in this section means that the | |||
| same LZ77 sliding window used by the endpoint to build frames of the | same LZ77 sliding window used by the endpoint to build frames of the | |||
| previous sent message is reused to build frames of the next message | previous sent message is reused to build frames of the next message | |||
| to be sent. | to be sent. | |||
| 8.1. Method Parameters | 7.1. Extension Parameters | |||
| 8.1.1. Context Takeover Control | 7.1.1. Context Takeover Control | |||
| 8.1.1.1. server_no_context_takeover | 7.1.1.1. The server_no_context_takeover extension parameter | |||
| A client MAY include the "server_no_context_takeover" extension | A client MAY include the "server_no_context_takeover" extension | |||
| parameter in an extension negotiation offer. This extension | parameter in an extension negotiation offer. This extension | |||
| parameter has no value. By including this extension parameter in an | parameter has no value. By including this extension parameter in an | |||
| extension negotiation offer, a client prevents the peer server from | extension negotiation offer, a client prevents the peer server from | |||
| using context take over. If the peer server doesn't use context take | using context take over. If the peer server doesn't use context take | |||
| over, the client doesn't need to reserve memory to retain the LZ77 | over, the client doesn't need to reserve memory to retain the LZ77 | |||
| sliding window between messages. | sliding window between messages. | |||
| Absence of this extension parameter in an extension negotiation offer | Absence of this extension parameter in an extension negotiation offer | |||
| skipping to change at page 18, line 20 ¶ | skipping to change at page 17, line 20 ¶ | |||
| It is RECOMMENDED that a server supports the | It is RECOMMENDED that a server supports the | |||
| "server_no_context_takeover" extension parameter in an extension | "server_no_context_takeover" extension parameter in an extension | |||
| negotiation offer. | negotiation offer. | |||
| A server MAY include the "server_no_context_takeover" extension | A server MAY include the "server_no_context_takeover" extension | |||
| parameter in an extension negotiation response even if the extension | parameter in an extension negotiation response even if the extension | |||
| negotiation offer being accepted by the extension negotiation | negotiation offer being accepted by the extension negotiation | |||
| response didn't include the "server_no_context_takeover" extension | response didn't include the "server_no_context_takeover" extension | |||
| parameter. | parameter. | |||
| 8.1.1.2. client_no_context_takeover | 7.1.1.2. The client_no_context_takeover extension parameter | |||
| A client MAY include the "client_no_context_takeover" extension | A client MAY include the "client_no_context_takeover" extension | |||
| parameter in an extension negotiation offer. This extension | parameter in an extension negotiation offer. This extension | |||
| parameter has no value. By including this extension parameter in an | parameter has no value. By including this extension parameter in an | |||
| extension negotiation offer, a client informs the peer server of a | extension negotiation offer, a client informs the peer server of a | |||
| hint that even if the server doesn't include the | hint that even if the server doesn't include the | |||
| "client_no_context_takeover" extension parameter in the corresponding | "client_no_context_takeover" extension parameter in the corresponding | |||
| extension negotiation response to the offer, the client is not going | extension negotiation response to the offer, the client is not going | |||
| to use context take over. | to use context take over. | |||
| skipping to change at page 19, line 5 ¶ | skipping to change at page 18, line 5 ¶ | |||
| context take over. This reduces the amount of memory that the server | context take over. This reduces the amount of memory that the server | |||
| has to reserve for the connection. | has to reserve for the connection. | |||
| Absence of this extension parameter in an extension negotiation | Absence of this extension parameter in an extension negotiation | |||
| response indicates that the server can decompress messages built by | response indicates that the server can decompress messages built by | |||
| the client using context take over. | the client using context take over. | |||
| A client MUST support the "client_no_context_takeover" extension | A client MUST support the "client_no_context_takeover" extension | |||
| parameter in an extension negotiation response. | parameter in an extension negotiation response. | |||
| 8.1.2. Limiting the LZ77 sliding window size | 7.1.2. Limiting the LZ77 sliding window size | |||
| 8.1.2.1. server_max_window_bits | 7.1.2.1. The server_max_window_bits extension parameter | |||
| A client MAY include the "server_max_window_bits" extension parameter | A client MAY include the "server_max_window_bits" extension parameter | |||
| in an extension negotiation offer. This parameter has a decimal | in an extension negotiation offer. This parameter has a decimal | |||
| integer value without leading zeroes between 8 to 15 inclusive | integer value without leading zeroes between 8 to 15 inclusive | |||
| indicating the base-2 logarithm of the LZ77 sliding window size and | indicating the base-2 logarithm of the LZ77 sliding window size and | |||
| MUST conform to the ABNF below. | MUST conform to the ABNF below. | |||
| server_max_window_bits = 1*DIGIT | server_max_window_bits = 1*DIGIT | |||
| By including this parameter in an extension negotiation offer, a | By including this parameter in an extension negotiation offer, a | |||
| skipping to change at page 19, line 46 ¶ | skipping to change at page 18, line 46 ¶ | |||
| inclusive indicating the base-2 logarithm of the LZ77 sliding window | inclusive indicating the base-2 logarithm of the LZ77 sliding window | |||
| size and MUST conform to the ABNF below. | size and MUST conform to the ABNF below. | |||
| server_max_window_bits = 1*DIGIT | server_max_window_bits = 1*DIGIT | |||
| A server MAY include the "server_max_window_bits" extension parameter | A server MAY include the "server_max_window_bits" extension parameter | |||
| in an extension negotiation response even if the extension | in an extension negotiation response even if the extension | |||
| negotiation offer being accepted by the response didn't include the | negotiation offer being accepted by the response didn't include the | |||
| "server_max_window_bits" extension parameter. | "server_max_window_bits" extension parameter. | |||
| 8.1.2.2. client_max_window_bits | 7.1.2.2. The client_max_window_bits extension parameter | |||
| A client MAY include the "client_max_window_bits" extension parameter | A client MAY include the "client_max_window_bits" extension parameter | |||
| in an extension negotiation offer. This parameter has no value or a | in an extension negotiation offer. This parameter has no value or a | |||
| decimal integer value without leading zeroes between 8 to 15 | decimal integer value without leading zeroes between 8 to 15 | |||
| inclusive indicating the base-2 logarithm of the LZ77 sliding window | inclusive indicating the base-2 logarithm of the LZ77 sliding window | |||
| size. If a value is specified for this parameter, the value MUST | size. If a value is specified for this parameter, the value MUST | |||
| conform to the ABNF below. | conform to the ABNF below. | |||
| client_max_window_bits = 1*DIGIT | client_max_window_bits = 1*DIGIT | |||
| skipping to change at page 21, line 6 ¶ | skipping to change at page 20, line 6 ¶ | |||
| If a received extension negotiation offer doesn't have the | If a received extension negotiation offer doesn't have the | |||
| "client_max_window_bits" extension parameter, the corresponding | "client_max_window_bits" extension parameter, the corresponding | |||
| extension negotiation response to the offer MUST NOT include the | extension negotiation response to the offer MUST NOT include the | |||
| "client_max_window_bits" extension parameter. | "client_max_window_bits" extension parameter. | |||
| Absence of this extension parameter in an extension negotiation | Absence of this extension parameter in an extension negotiation | |||
| response indicates that the server can receive messages compressed | response indicates that the server can receive messages compressed | |||
| using an LZ77 sliding window of up to 32,768 bytes. | using an LZ77 sliding window of up to 32,768 bytes. | |||
| 8.1.3. Examples | 7.1.3. Examples | |||
| The simplest "Sec-WebSocket-Extensions" header in a client's opening | The simplest "Sec-WebSocket-Extensions" header in a client's opening | |||
| handshake to offer use of the permessage-deflate extension looks like | handshake to offer use of the permessage-deflate extension looks like | |||
| this: | this: | |||
| Sec-WebSocket-Extensions: permessage-deflate | Sec-WebSocket-Extensions: permessage-deflate | |||
| Since the "client_max_window_bits" extension parameter is not | Since the "client_max_window_bits" extension parameter is not | |||
| included in this extension negotiation offer, the server must not | included in this extension negotiation offer, the server must not | |||
| accept the offer with an extension negotiation response that includes | accept the offer with an extension negotiation response that includes | |||
| skipping to change at page 22, line 13 ¶ | skipping to change at page 21, line 13 ¶ | |||
| server may send back a response as follows: | server may send back a response as follows: | |||
| Sec-WebSocket-Extensions: | Sec-WebSocket-Extensions: | |||
| permessage-deflate; server_max_window_bits=10 | permessage-deflate; server_max_window_bits=10 | |||
| To accept the second option, for example, the server may send back a | To accept the second option, for example, the server may send back a | |||
| response as follows: | response as follows: | |||
| Sec-WebSocket-Extensions: permessage-deflate | Sec-WebSocket-Extensions: permessage-deflate | |||
| 8.2. Message Payload Transformation | 7.2. Message Payload Transformation | |||
| 8.2.1. Compression | 7.2.1. Compression | |||
| An endpoint uses the following algorithm to compress a message. | An endpoint uses the following algorithm to compress a message. | |||
| 1. Compress all the octets of the payload of the message using | 1. Compress all the octets of the payload of the message using | |||
| DEFLATE. | DEFLATE. | |||
| 2. If the resulting data does not end with an empty DEFLATE block | 2. If the resulting data does not end with an empty DEFLATE block | |||
| with no compression (the "BTYPE" bits are set to 00), append an | with no compression (the "BTYPE" bits are set to 00), append an | |||
| empty DEFLATE block with no compression to the tail end. | empty DEFLATE block with no compression to the tail end. | |||
| skipping to change at page 22, line 51 ¶ | skipping to change at page 21, line 51 ¶ | |||
| o When any DEFLATE block with the "BFINAL" bit set to 1 doesn't end | o When any DEFLATE block with the "BFINAL" bit set to 1 doesn't end | |||
| at a byte boundary, an endpoint MUST add minimal padding bits of 0 | at a byte boundary, an endpoint MUST add minimal padding bits of 0 | |||
| to make it end at a byte boundary. The next DEFLATE block follows | to make it end at a byte boundary. The next DEFLATE block follows | |||
| the padded data if any. | the padded data if any. | |||
| An endpoint fragments a compressed message by splitting the result of | An endpoint fragments a compressed message by splitting the result of | |||
| running this algorithm. Even when only part of the payload is | running this algorithm. Even when only part of the payload is | |||
| available, a fragment can be built by compressing the available data | available, a fragment can be built by compressing the available data | |||
| and choosing the block type appropriately so that the end of the | and choosing the block type appropriately so that the end of the | |||
| resulting compressed data is aligned at a byte boundary. Note that | resulting compressed data is aligned at a byte boundary. Note that | |||
| for non-final fragments, the removal of 0x00 0x00 0xff 0xff must not | for non-final fragments, the removal of 0x00 0x00 0xff 0xff MUST NOT | |||
| be done. | be done. | |||
| An endpoint MUST NOT use an LZ77 sliding window longer than 32,768 | An endpoint MUST NOT use an LZ77 sliding window longer than 32,768 | |||
| bytes to compress messages to send. | bytes to compress messages to send. | |||
| If the "agreed parameters" contain the "client_no_context_takeover" | If the "agreed parameters" contain the "client_no_context_takeover" | |||
| extension parameter, the client MUST start compressing each new | extension parameter, the client MUST start compressing each new | |||
| message with an empty LZ77 sliding window. Otherwise, the client MAY | message with an empty LZ77 sliding window. Otherwise, the client MAY | |||
| take over the LZ77 sliding window used to build the last compressed | take over the LZ77 sliding window used to build the last compressed | |||
| message. Note that even if the client has included the | message. Note that even if the client has included the | |||
| skipping to change at page 23, line 42 ¶ | skipping to change at page 22, line 42 ¶ | |||
| LZ77 sliding window with any size to compress messages to send as | LZ77 sliding window with any size to compress messages to send as | |||
| long as the size conforms to the "agreed parameters". The client-to- | long as the size conforms to the "agreed parameters". The client-to- | |||
| server "client_max_window_bits" extension parameter is just a hint | server "client_max_window_bits" extension parameter is just a hint | |||
| for the server to build an extension negotiation response. | for the server to build an extension negotiation response. | |||
| If the "agreed parameters" contain the "server_max_window_bits" | If the "agreed parameters" contain the "server_max_window_bits" | |||
| extension parameter with a value of w, the server MUST NOT use an | extension parameter with a value of w, the server MUST NOT use an | |||
| LZ77 sliding window longer than the w-th power of 2 bytes to compress | LZ77 sliding window longer than the w-th power of 2 bytes to compress | |||
| messages to send. | messages to send. | |||
| 8.2.2. Decompression | 7.2.2. Decompression | |||
| An endpoint uses the following algorithm to decompress a message. | An endpoint uses the following algorithm to decompress a message. | |||
| 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the | 1. Append 4 octets of 0x00 0x00 0xff 0xff to the tail end of the | |||
| payload of the message. | payload of the message. | |||
| 2. Decompress the resulting data using DEFLATE. | 2. Decompress the resulting data using DEFLATE. | |||
| If the "agreed parameters" contain the "server_no_context_takeover" | If the "agreed parameters" contain the "server_no_context_takeover" | |||
| extension parameter, the client MAY decompress each new message with | extension parameter, the client MAY decompress each new message with | |||
| skipping to change at page 24, line 40 ¶ | skipping to change at page 23, line 40 ¶ | |||
| the w-th power of 2 bytes. Otherwise, the server MUST use a 32,768 | the w-th power of 2 bytes. Otherwise, the server MUST use a 32,768 | |||
| byte LZ77 sliding window to decompress received messages. Note that | byte LZ77 sliding window to decompress received messages. Note that | |||
| even if the client has included in its offer the | even if the client has included in its offer the | |||
| "client_max_window_bits" extension parameter with a value smaller | "client_max_window_bits" extension parameter with a value smaller | |||
| than one in the "agreed parameters", the client MUST use an LZ77 | than one in the "agreed parameters", the client MUST use an LZ77 | |||
| sliding window of a size that conforms the "agreed parameters" to | sliding window of a size that conforms the "agreed parameters" to | |||
| compress messages to send. The client-to-server | compress messages to send. The client-to-server | |||
| "client_max_window_bits" extension parameter is just a hint for the | "client_max_window_bits" extension parameter is just a hint for the | |||
| server to build an extension negotiation response. | server to build an extension negotiation response. | |||
| 8.2.3. Examples | 7.2.3. Examples | |||
| This section introduces examples of how the permessage-deflate | This section introduces examples of how the permessage-deflate | |||
| extension transforms messages. | extension transforms messages. | |||
| 8.2.3.1. A message compressed using 1 compressed DEFLATE block | 7.2.3.1. A message compressed using 1 compressed DEFLATE block | |||
| Suppose that an endpoint sends a text message "Hello". If the | Suppose that an endpoint sends a text message "Hello". If the | |||
| endpoint uses 1 compressed DEFLATE block (compressed with fixed | endpoint uses 1 compressed DEFLATE block (compressed with fixed | |||
| Huffman code and the "BFINAL" bit not set) to compress the message, | Huffman code and the "BFINAL" bit not set) to compress the message, | |||
| the endpoint obtains the compressed data to use for the message | the endpoint obtains the compressed data to use for the message | |||
| payload as follows. | payload as follows. | |||
| The endpoint compresses "Hello" into 1 compressed DEFLATE block and | The endpoint compresses "Hello" into 1 compressed DEFLATE block and | |||
| flushes the resulting data into a byte array using an empty DEFLATE | flushes the resulting data into a byte array using an empty DEFLATE | |||
| block with no compression: | block with no compression: | |||
| skipping to change at page 26, line 5 ¶ | skipping to change at page 25, line 5 ¶ | |||
| fragments are 3 and 4 octet, the first frame is: | fragments are 3 and 4 octet, the first frame is: | |||
| 0x41 0x03 0xf2 0x48 0xcd | 0x41 0x03 0xf2 0x48 0xcd | |||
| and the second frame is: | and the second frame is: | |||
| 0x80 0x04 0xc9 0xc9 0x07 0x00 | 0x80 0x04 0xc9 0xc9 0x07 0x00 | |||
| Note that the RSV1 bit is set only on the first frame. | Note that the RSV1 bit is set only on the first frame. | |||
| 8.2.3.2. Sharing LZ77 Sliding Window | 7.2.3.2. Sharing LZ77 Sliding Window | |||
| Suppose that a client has sent a message "Hello" as a compressed | Suppose that a client has sent a message "Hello" as a compressed | |||
| message and will send the same message "Hello" again as a compressed | message and will send the same message "Hello" again as a compressed | |||
| message. | message. | |||
| 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 | 0xf2 0x48 0xcd 0xc9 0xc9 0x07 0x00 | |||
| The above is the payload of the first message that the client has | The above is the payload of the first message that the client has | |||
| sent. If the "agreed parameters" contain the | sent. If the "agreed parameters" contain the | |||
| "client_no_context_takeover" extension parameter, the client | "client_no_context_takeover" extension parameter, the client | |||
| skipping to change at page 26, line 36 ¶ | skipping to change at page 25, line 36 ¶ | |||
| of the second message will be: | of the second message will be: | |||
| 0xf2 0x00 0x11 0x00 0x00 | 0xf2 0x00 0x11 0x00 0x00 | |||
| So, 2 bytes are saved in total. | So, 2 bytes are saved in total. | |||
| Note that even if some uncompressed messages (with the RSV1 bit | Note that even if some uncompressed messages (with the RSV1 bit | |||
| unset) are inserted between the two "Hello" messages, they don't | unset) are inserted between the two "Hello" messages, they don't | |||
| affect the LZ77 sliding window. | affect the LZ77 sliding window. | |||
| 8.2.3.3. Using a DEFLATE Block with No Compression | 7.2.3.3. Using a DEFLATE Block with No Compression | |||
| 0xc1 0x0b 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 | 0xc1 0x0b 0x00 0x05 0x00 0xfa 0xff 0x48 0x65 0x6c 0x6c 0x6f 0x00 | |||
| This is a frame constituting a text message "Hello" built using a | This is a frame constituting a text message "Hello" built using a | |||
| DEFLATE block with no compression. The first 2 octets (0xc1 0x0b) | DEFLATE block with no compression. The first 2 octets (0xc1 0x0b) | |||
| are the WebSocket frame header (FIN=1, RSV1=1, RSV2=0, RSV3=0, | are the WebSocket frame header (FIN=1, RSV1=1, RSV2=0, RSV3=0, | |||
| opcode=text, MASK=0, Payload length=7). Note that the RSV1 bit is | opcode=text, MASK=0, Payload length=7). Note that the RSV1 bit is | |||
| set for this message (only on the first fragment if the message is | set for this message (only on the first fragment if the message is | |||
| fragmented) because the RSV1 bit is set when DEFLATE is applied to | fragmented) because the RSV1 bit is set when DEFLATE is applied to | |||
| the message, including the case when only DEFLATE blocks with no | the message, including the case when only DEFLATE blocks with no | |||
| compression are used. The 3rd to 13th octets consist the payload | compression are used. The 3rd to 13th octets consist the payload | |||
| data containing "Hello" compressed using a DEFLATE block with no | data containing "Hello" compressed using a DEFLATE block with no | |||
| compression. | compression. | |||
| 8.2.3.4. Using a DEFLATE Block with BFINAL Set to 1 | 7.2.3.4. Using a DEFLATE Block with BFINAL Set to 1 | |||
| On platforms on which the flush method using an empty DEFLATE block | On platforms on which the flush method using an empty DEFLATE block | |||
| with no compression is not available, implementors can choose to | with no compression is not available, implementors can choose to | |||
| flush data using DEFLATE blocks with "BFINAL" set to 1. | flush data using DEFLATE blocks with "BFINAL" set to 1. | |||
| 0xf3 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 | 0xf3 0x48 0xcd 0xc9 0xc9 0x07 0x00 0x00 | |||
| This is the payload of a message containing "Hello" compressed using | This is the payload of a message containing "Hello" compressed using | |||
| a DEFLATE block with "BFINAL" set to 1. The first 7 octets | a DEFLATE block with "BFINAL" set to 1. The first 7 octets | |||
| constitute a DEFLATE block with "BFINAL" set to 1 and "BTYPE" set to | constitute a DEFLATE block with "BFINAL" set to 1 and "BTYPE" set to | |||
| 01 containing "Hello". The last 1 octet (0x00) contains the header | 01 containing "Hello". The last 1 octet (0x00) contains the header | |||
| bits with "BFINAL" set to 0 and "BTYPE" set to 00, and 5 padding bits | bits with "BFINAL" set to 0 and "BTYPE" set to 00, and 5 padding bits | |||
| of 0. This octet is necessary to allow the payload to be | of 0. This octet is necessary to allow the payload to be | |||
| decompressed in the same manner as messages flushed using DEFLATE | decompressed in the same manner as messages flushed using DEFLATE | |||
| blocks with BFINAL unset. | blocks with BFINAL unset. | |||
| 8.2.3.5. Two DEFLATE Blocks in 1 Message | 7.2.3.5. Two DEFLATE Blocks in 1 Message | |||
| Two or more DEFLATE blocks may be used in 1 message. | Two or more DEFLATE blocks may be used in 1 message. | |||
| 0xf2 0x48 0x05 0x00 0x00 0x00 0xff 0xff 0xca 0xc9 0xc9 0x07 0x00 | 0xf2 0x48 0x05 0x00 0x00 0x00 0xff 0xff 0xca 0xc9 0xc9 0x07 0x00 | |||
| The first 3 octets (0xf2 0x48 0x05) and the least significant two | The first 3 octets (0xf2 0x48 0x05) and the least significant two | |||
| bits of the 4th octet (0x00) constitute one DEFLATE block with | bits of the 4th octet (0x00) constitute one DEFLATE block with | |||
| "BFINAL" set to 0 and "BTYPE" set to 01 containing "He". The rest of | "BFINAL" set to 0 and "BTYPE" set to 01 containing "He". The rest of | |||
| the 4th octet contains the header bits with "BFINAL" set to 0 and | the 4th octet contains the header bits with "BFINAL" set to 0 and | |||
| "BTYPE" set to 00, and the 3 padding bits of 0. Together with the | "BTYPE" set to 00, and the 3 padding bits of 0. Together with the | |||
| following 4 octets (0x00 0x00 0xff 0xff), the header bits constitute | following 4 octets (0x00 0x00 0xff 0xff), the header bits constitute | |||
| an empty DEFLATE block with no compression. A DEFLATE block | an empty DEFLATE block with no compression. A DEFLATE block | |||
| containing "llo" follows the empty DEFLATE block. | containing "llo" follows the empty DEFLATE block. | |||
| 8.2.3.6. Generating an Empty Fragment Manually | 7.2.3.6. Generating an Empty Fragment | |||
| Suppose that an endpoint is sending data of unknown size. The | Suppose that an endpoint is sending data of unknown size. The | |||
| endpoint may encounter the end of data signal from the data source | endpoint may encounter the end of data signal from the data source | |||
| when its buffer for uncompressed data is empty. In such a case, the | when its buffer for uncompressed data is empty. In such a case, the | |||
| endpoint just needs to send the last fragment with FIN bit set to 1 | endpoint just needs to send the last fragment with FIN bit set to 1 | |||
| and payload set to DEFLATE block(s) which contains 0 bytes of data. | and payload set to DEFLATE block(s) which contains 0 bytes of data. | |||
| If the compression library being used doesn't generate any data when | If the compression library being used doesn't generate any data when | |||
| its buffer is empty, an empty uncompressed DEFLATE block can be built | its buffer is empty, an empty uncompressed DEFLATE block can be built | |||
| manually and used for this purpose as follows: | and used for this purpose as follows: | |||
| 0x00 | 0x00 | |||
| The only octet 0x00 contains the header bits with "BFINAL" set to 0 | The only octet 0x00 contains the header bits with "BFINAL" set to 0 | |||
| and "BTYPE" set to 00, and 5 padding bits of 0. | and "BTYPE" set to 00, and 5 padding bits of 0. | |||
| 8.3. Implementation Notes | 7.3. Implementation Notes | |||
| On most common software development platforms, the DEFLATE | On most common software development platforms, the DEFLATE | |||
| compression library provides a method for aligning compressed data to | compression library provides a method for aligning compressed data to | |||
| byte boundaries using an empty DEFLATE block with no compression. | byte boundaries using an empty DEFLATE block with no compression. | |||
| For example, Zlib [Zlib] does this when "Z_SYNC_FLUSH" is passed to | For example, Zlib [Zlib] does this when "Z_SYNC_FLUSH" is passed to | |||
| the deflate function. | the deflate function. | |||
| Some platforms may provide only methods to output and process | Some platforms may provide only methods to output and process | |||
| compressed data with a ZLIB header and an Adler-32 checksum. On such | compressed data with a ZLIB header and an Adler-32 checksum. On such | |||
| platforms, developers need to write stub code to remove and | platforms, developers need to write stub code to remove and | |||
| complement them manually. | complement them by themselves. | |||
| To obtain a useful compression ratio, an LZ77 sliding window size of | To obtain a useful compression ratio, an LZ77 sliding window size of | |||
| 1,024 or more is RECOMMENDED. | 1,024 or more is RECOMMENDED. | |||
| If a side disallows context takeover, its endpoint can easily figure | If a side disallows context takeover, its endpoint can easily figure | |||
| out whether a certain message will be shorter if compressed or not. | out whether a certain message will be shorter if compressed or not. | |||
| Otherwise, it's not easy to know whether future messages will benefit | Otherwise, it's not easy to know whether future messages will benefit | |||
| from having a certain message compressed. Implementors may employ | from having a certain message compressed. Implementors may employ | |||
| some heuristics to determine this. | some heuristics to determine this. | |||
| 8.4. Intermediaries | 8. Security Considerations | |||
| When an intermediary forwards a message, the intermediary MAY change | ||||
| the compression of messages provided that the resulting sequence of | ||||
| messages conforms to the constraints based on the "agreed | ||||
| parameters". For example, an intermediary may decompress a received | ||||
| message, unset the "Per-message Compressed" bit and forward it to the | ||||
| other peer. Since such a compression change may affect the LZ77 | ||||
| sliding window, the intermediary may need to parse and transform the | ||||
| following messages, too. | ||||
| 9. Security Considerations | ||||
| There is a known exploit when history-based compression is combined | There is a known exploit when history-based compression is combined | |||
| with a secure transport [CRIME]. Implementors should pay attention | with a secure transport [CRIME]. Implementors should pay attention | |||
| to this point when integrating this extension with other extensions | to this point when integrating this extension with other extensions | |||
| or protocols. | or protocols. | |||
| 10. IANA Considerations | 9. IANA Considerations | |||
| 10.1. Registration of the "permessage-deflate" WebSocket Extension Name | 9.1. Registration of the "permessage-deflate" WebSocket Extension Name | |||
| This section describes a WebSocket extension name registration in the | This section describes a WebSocket extension name registration in the | |||
| WebSocket Extension Name Registry [RFC6455]. | WebSocket Extension Name Registry [RFC6455]. | |||
| Extension Identifier | Extension Identifier | |||
| permessage-deflate | permessage-deflate | |||
| Extension Common Name | Extension Common Name | |||
| WebSocket Per-message Deflate | WebSocket Per-message Deflate | |||
| Extension Definition | Extension Definition | |||
| This document. | This document. | |||
| Known Incompatible Extensions | Known Incompatible Extensions | |||
| None | None | |||
| The "permessage-deflate" extension name is used in the | The "permessage-deflate" extension name is used in the | |||
| "Sec-WebSocket-Extensions" header in the WebSocket opening handshake | "Sec-WebSocket-Extensions" header in the WebSocket opening handshake | |||
| to negotiate use of the permessage-deflate extension. | to negotiate use of the permessage-deflate extension. | |||
| 10.2. Registration of the "Per-message Compressed" WebSocket Framing | 9.2. Registration of the "Per-message Compressed" WebSocket Framing | |||
| Header Bit | Header Bit | |||
| This section describes a WebSocket framing header bit registration in | This section describes a WebSocket framing header bit registration in | |||
| the WebSocket Framing Header Bits Registry [RFC6455]. | the WebSocket Framing Header Bits Registry [RFC6455]. | |||
| Header Bit | Value | |||
| RSV1 | RSV1 | |||
| Common Name | Description | |||
| Per-message Compressed | The message is compressed or not. RSV1 is set for compressed | |||
| messages and unset for uncompressed messages. | ||||
| Meaning | ||||
| The message is compressed or not. | ||||
| Reference | Reference | |||
| Section 6 of this document. | Section 6 of this document. | |||
| The "Per-message Compressed" framing header bit is used on the first | The "Per-message Compressed" framing header bit is used on the first | |||
| fragment of data messages to indicate whether the payload of the | fragment of data messages to indicate whether the payload of the | |||
| message is compressed by the PMCE or not. | message is compressed by the PMCE or not. | |||
| 11. Acknowledgements | 10. Acknowledgements | |||
| Special thanks to Patrick McManus who wrote up the initial | Special thanks to Patrick McManus who wrote up the initial | |||
| specification of a DEFLATE-based compression extension for the | specification of a DEFLATE-based compression extension for the | |||
| WebSocket Protocol to which I referred to write this specification. | WebSocket Protocol to which I referred to write this specification. | |||
| Thank you to the following people who participated in discussions on | Thanks to the following people who participated in discussions on the | |||
| the HyBi WG and contributed ideas and/or provided detailed reviews | HyBi WG and contributed ideas and/or provided detailed reviews (the | |||
| (the list is likely to be incomplete): Adam Rice, Alexander | list is likely to be incomplete): Adam Rice, Alexander Philippou, | |||
| Philippou, Alexey Melnikov, Arman Djusupov, Bjoern Hoehrmann, Brian | Alexey Melnikov, Arman Djusupov, Bjoern Hoehrmann, Brian McKelvey, | |||
| McKelvey, Dario Crivelli, Greg Wilkins, Inaki Baz Castillo, Jamie | Dario Crivelli, Greg Wilkins, Inaki Baz Castillo, Jamie Lokier, | |||
| Lokier, Joakim Erdfelt, John A. Tamplin, Julian Reschke, Kenichi | Joakim Erdfelt, John A. Tamplin, Julian Reschke, Kenichi Ishibashi, | |||
| Ishibashi, Mark Nottingham, Peter Thorson, Roberto Peon, Salvatore | Mark Nottingham, Peter Thorson, Roberto Peon, Salvatore Loreto, | |||
| Loreto, Simone Bordet, Tobias Oberstein and Yutaka Hirano. Note that | Simone Bordet, Tobias Oberstein and Yutaka Hirano. Note that people | |||
| people listed above didn't necessarily endorse the end result of this | listed above didn't necessarily endorse the end result of this work. | |||
| work. | ||||
| 12. References | 11. References | |||
| 12.1. Normative References | 11.1. Normative References | |||
| [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification | [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification | |||
| version 1.3", RFC 1951, May 1996. | version 1.3", RFC 1951, May 1996. | |||
| [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax | [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax | |||
| Specifications: ABNF", STD 68, RFC 5234, January 2008. | Specifications: ABNF", STD 68, RFC 5234, January 2008. | |||
| [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", | [RFC6455] Fette, I. and A. Melnikov, "The WebSocket Protocol", | |||
| RFC 6455, December 2011. | RFC 6455, December 2011. | |||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, March 1997. | Requirement Levels", BCP 14, RFC 2119, March 1997. | |||
| [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for | [LZ77] Ziv, J. and A. Lempel, "A Universal Algorithm for | |||
| Sequential Data Compression", IEEE Transactions on | Sequential Data Compression", IEEE Transactions on | |||
| Information Theory, Vol. 23, No. 3, pp. 337-343. | Information Theory, Vol. 23, No. 3, pp. 337-343. | |||
| 12.2. Informative References | [CRIME] Rizzo, J. and T. Duong, "The CRIME attack", Ekoparty 2012, | |||
| September 2012. | ||||
| 11.2. Informative References | ||||
| [RFC1979] Woods, J., "PPP Deflate Protocol", RFC 1979, August 1996. | [RFC1979] Woods, J., "PPP Deflate Protocol", RFC 1979, August 1996. | |||
| [Zlib] Gailly, J. and M. Adler, "Zlib", <http://zlib.net/>. | [Zlib] Gailly, J. and M. Adler, "Zlib", <http://zlib.net/>. | |||
| [CRIME] Rizzo, J. and T. Duong, "The CRIME attack", Ekoparty 2012, | ||||
| September 2012. | ||||
| Author's Address | Author's Address | |||
| Takeshi Yoshino | Takeshi Yoshino | |||
| Google, Inc. | Google, Inc. | |||
| Email: tyoshino@google.com | Email: tyoshino@google.com | |||
| End of changes. 55 change blocks. | ||||
| 160 lines changed or deleted | 134 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||