| draft-ietf-quic-qpack-08.txt | draft-ietf-quic-qpack-09.txt | |||
|---|---|---|---|---|
| QUIC C. Krasic | QUIC C. Krasic | |||
| Internet-Draft Netflix | Internet-Draft Netflix | |||
| Intended status: Standards Track M. Bishop | Intended status: Standards Track M. Bishop | |||
| Expires: October 25, 2019 Akamai Technologies | Expires: January 9, 2020 Akamai Technologies | |||
| A. Frindell, Ed. | A. Frindell, Ed. | |||
| April 23, 2019 | July 08, 2019 | |||
| QPACK: Header Compression for HTTP/3 | QPACK: Header Compression for HTTP/3 | |||
| draft-ietf-quic-qpack-08 | draft-ietf-quic-qpack-09 | |||
| Abstract | Abstract | |||
| This specification defines QPACK, a compression format for | This specification defines QPACK, a compression format for | |||
| efficiently representing HTTP header fields, to be used in HTTP/3. | efficiently representing HTTP header fields, to be used in HTTP/3. | |||
| This is a variation of HPACK header compression that seeks to reduce | This is a variation of HPACK header compression that seeks to reduce | |||
| head-of-line blocking. | head-of-line blocking. | |||
| Note to Readers | Note to Readers | |||
| skipping to change at page 1, line 46 ¶ | skipping to change at page 1, line 46 ¶ | |||
| 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 https://datatracker.ietf.org/drafts/current/. | Drafts is at https://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 October 25, 2019. | This Internet-Draft will expire on January 9, 2020. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2019 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 | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://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 | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.1. Conventions and Definitions . . . . . . . . . . . . . . . 4 | 1.1. Conventions and Definitions . . . . . . . . . . . . . . . 4 | |||
| 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 | 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 | |||
| 2. Compression Process Overview . . . . . . . . . . . . . . . . 5 | 2. Compression Process Overview . . . . . . . . . . . . . . . . 5 | |||
| 2.1. Encoder . . . . . . . . . . . . . . . . . . . . . . . . . 5 | 2.1. Encoder . . . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
| 2.1.1. Reference Tracking . . . . . . . . . . . . . . . . . 6 | 2.1.1. Reference Tracking . . . . . . . . . . . . . . . . . 5 | |||
| 2.1.2. Blocked Dynamic Table Insertions . . . . . . . . . . 6 | 2.1.2. Blocked Dynamic Table Insertions . . . . . . . . . . 6 | |||
| 2.1.3. Avoiding Head-of-Line Blocking . . . . . . . . . . . 7 | 2.1.3. Blocked Streams . . . . . . . . . . . . . . . . . . . 7 | |||
| 2.1.4. Known Received Count . . . . . . . . . . . . . . . . 8 | 2.1.4. Known Received Count . . . . . . . . . . . . . . . . 8 | |||
| 2.2. Decoder . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 2.2. Decoder . . . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 2.2.1. State Synchronization . . . . . . . . . . . . . . . . 9 | 2.2.1. Blocked Decoding . . . . . . . . . . . . . . . . . . 8 | |||
| 2.2.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 9 | 2.2.2. State Synchronization . . . . . . . . . . . . . . . . 9 | |||
| 3. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 9 | 2.2.3. Invalid References . . . . . . . . . . . . . . . . . 10 | |||
| 3.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 9 | 3. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 10 | 3.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.2.1. Dynamic Table Size . . . . . . . . . . . . . . . . . 10 | 3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 3.2.2. Dynamic Table Capacity and Eviction . . . . . . . . . 10 | 3.2.1. Dynamic Table Size . . . . . . . . . . . . . . . . . 11 | |||
| 3.2.3. Maximum Dynamic Table Capacity . . . . . . . . . . . 11 | 3.2.2. Dynamic Table Capacity and Eviction . . . . . . . . . 11 | |||
| 3.2.3. Maximum Dynamic Table Capacity . . . . . . . . . . . 12 | ||||
| 3.2.4. Absolute Indexing . . . . . . . . . . . . . . . . . . 12 | 3.2.4. Absolute Indexing . . . . . . . . . . . . . . . . . . 12 | |||
| 3.2.5. Relative Indexing . . . . . . . . . . . . . . . . . . 12 | 3.2.5. Relative Indexing . . . . . . . . . . . . . . . . . . 12 | |||
| 3.2.6. Post-Base Indexing . . . . . . . . . . . . . . . . . 13 | 3.2.6. Post-Base Indexing . . . . . . . . . . . . . . . . . 14 | |||
| 3.2.7. Invalid References . . . . . . . . . . . . . . . . . 13 | ||||
| 4. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 14 | 4. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
| 4.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 14 | 4.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
| 4.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 14 | 4.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 14 | |||
| 4.1.2. String Literals . . . . . . . . . . . . . . . . . . . 14 | 4.1.2. String Literals . . . . . . . . . . . . . . . . . . . 14 | |||
| 4.2. Instructions . . . . . . . . . . . . . . . . . . . . . . 14 | 4.2. Encoder and Decoder Streams . . . . . . . . . . . . . . . 15 | |||
| 4.2.1. Encoder and Decoder Streams . . . . . . . . . . . . . 15 | ||||
| 4.3. Encoder Instructions . . . . . . . . . . . . . . . . . . 15 | 4.3. Encoder Instructions . . . . . . . . . . . . . . . . . . 15 | |||
| 4.3.1. Insert With Name Reference . . . . . . . . . . . . . 15 | 4.3.1. Set Dynamic Table Capacity . . . . . . . . . . . . . 16 | |||
| 4.3.2. Insert Without Name Reference . . . . . . . . . . . . 16 | 4.3.2. Insert With Name Reference . . . . . . . . . . . . . 16 | |||
| 4.3.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 16 | 4.3.3. Insert Without Name Reference . . . . . . . . . . . . 17 | |||
| 4.3.4. Set Dynamic Table Capacity . . . . . . . . . . . . . 17 | 4.3.4. Duplicate . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| 4.4. Decoder Instructions . . . . . . . . . . . . . . . . . . 17 | 4.4. Decoder Instructions . . . . . . . . . . . . . . . . . . 18 | |||
| 4.4.1. Insert Count Increment . . . . . . . . . . . . . . . 17 | 4.4.1. Header Acknowledgement . . . . . . . . . . . . . . . 18 | |||
| 4.4.2. Header Acknowledgement . . . . . . . . . . . . . . . 18 | 4.4.2. Stream Cancellation . . . . . . . . . . . . . . . . . 18 | |||
| 4.4.3. Stream Cancellation . . . . . . . . . . . . . . . . . 19 | 4.4.3. Insert Count Increment . . . . . . . . . . . . . . . 19 | |||
| 4.5. Header Block Instructions . . . . . . . . . . . . . . . . 19 | 4.5. Header Block Representations . . . . . . . . . . . . . . 19 | |||
| 4.5.1. Header Block Prefix . . . . . . . . . . . . . . . . . 20 | 4.5.1. Header Block Prefix . . . . . . . . . . . . . . . . . 19 | |||
| 4.5.2. Indexed Header Field . . . . . . . . . . . . . . . . 22 | 4.5.2. Indexed Header Field . . . . . . . . . . . . . . . . 22 | |||
| 4.5.3. Indexed Header Field With Post-Base Index . . . . . . 23 | 4.5.3. Indexed Header Field With Post-Base Index . . . . . . 22 | |||
| 4.5.4. Literal Header Field With Name Reference . . . . . . 23 | 4.5.4. Literal Header Field With Name Reference . . . . . . 23 | |||
| 4.5.5. Literal Header Field With Post-Base Name Reference . 24 | 4.5.5. Literal Header Field With Post-Base Name Reference . 24 | |||
| 4.5.6. Literal Header Field Without Name Reference . . . . . 24 | 4.5.6. Literal Header Field Without Name Reference . . . . . 24 | |||
| 5. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 25 | 5. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 25 | |||
| 6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 25 | 6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 25 | |||
| 7. Security Considerations . . . . . . . . . . . . . . . . . . . 26 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 25 | |||
| 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 | 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 | |||
| 8.1. Settings Registration . . . . . . . . . . . . . . . . . . 26 | 8.1. Settings Registration . . . . . . . . . . . . . . . . . . 26 | |||
| 8.2. Stream Type Registration . . . . . . . . . . . . . . . . 26 | 8.2. Stream Type Registration . . . . . . . . . . . . . . . . 26 | |||
| 8.3. Error Code Registration . . . . . . . . . . . . . . . . . 26 | 8.3. Error Code Registration . . . . . . . . . . . . . . . . . 26 | |||
| 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 9.1. Normative References . . . . . . . . . . . . . . . . . . 27 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 27 | |||
| 9.2. Informative References . . . . . . . . . . . . . . . . . 28 | 9.2. Informative References . . . . . . . . . . . . . . . . . 28 | |||
| 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28 | 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28 | |||
| Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 28 | Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 28 | |||
| Appendix B. Sample One Pass Encoding Algorithm . . . . . . . . . 33 | Appendix B. Sample One Pass Encoding Algorithm . . . . . . . . . 33 | |||
| Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 35 | Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 35 | |||
| C.1. Since draft-ietf-quic-qpack-06 . . . . . . . . . . . . . 35 | C.1. Since draft-ietf-quic-qpack-08 . . . . . . . . . . . . . 35 | |||
| C.2. Since draft-ietf-quic-qpack-05 . . . . . . . . . . . . . 35 | C.2. Since draft-ietf-quic-qpack-06 . . . . . . . . . . . . . 35 | |||
| C.3. Since draft-ietf-quic-qpack-04 . . . . . . . . . . . . . 35 | C.3. Since draft-ietf-quic-qpack-05 . . . . . . . . . . . . . 35 | |||
| C.4. Since draft-ietf-quic-qpack-03 . . . . . . . . . . . . . 35 | C.4. Since draft-ietf-quic-qpack-04 . . . . . . . . . . . . . 35 | |||
| C.5. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 35 | C.5. Since draft-ietf-quic-qpack-03 . . . . . . . . . . . . . 35 | |||
| C.6. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 36 | C.6. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 35 | |||
| C.7. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 36 | C.7. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 36 | |||
| C.8. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 36 | C.8. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 36 | |||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 36 | C.9. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 36 | |||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 37 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37 | |||
| 1. Introduction | 1. Introduction | |||
| The QUIC transport protocol was designed from the outset to support | The QUIC transport protocol [QUIC-TRANSPORT] is designed to support | |||
| HTTP semantics, and its design subsumes many of the features of | HTTP semantics, and its design subsumes many of the features of | |||
| HTTP/2. HTTP/2 uses HPACK ([RFC7541]) for header compression, but | HTTP/2 [RFC7540]. HTTP/2 uses HPACK ([RFC7541]) for header | |||
| QUIC's stream multiplexing comes into some conflict with HPACK. A | compression. If HPACK were used for HTTP/3 [HTTP3], it would induce | |||
| key goal of the design of QUIC is to improve stream multiplexing | head-of-line blocking due to built-in assumptions of a total ordering | |||
| relative to HTTP/2 by reducing head-of-line blocking. If HPACK were | across frames on all streams. | |||
| used for HTTP/3, it would induce head-of-line blocking due to built- | ||||
| in assumptions of a total ordering across frames on all streams. | ||||
| QUIC is described in [QUIC-TRANSPORT]. The HTTP/3 mapping is | ||||
| described in [HTTP3]. For a full description of HTTP/2, see | ||||
| [RFC7540]. The description of HPACK is [RFC7541]. | ||||
| QPACK reuses core concepts from HPACK, but is redesigned to allow | QPACK reuses core concepts from HPACK, but is redesigned to allow | |||
| correctness in the presence of out-of-order delivery, with | correctness in the presence of out-of-order delivery, with | |||
| flexibility for implementations to balance between resilience against | flexibility for implementations to balance between resilience against | |||
| head-of-line blocking and optimal compression ratio. The design | head-of-line blocking and optimal compression ratio. The design | |||
| goals are to closely approach the compression ratio of HPACK with | goals are to closely approach the compression ratio of HPACK with | |||
| substantially less head-of-line blocking under the same loss | substantially less head-of-line blocking under the same loss | |||
| conditions. | conditions. | |||
| 1.1. Conventions and Definitions | 1.1. Conventions and Definitions | |||
| skipping to change at page 4, line 43 ¶ | skipping to change at page 4, line 39 ¶ | |||
| Header block: The compressed representation of a header list. | Header block: The compressed representation of a header list. | |||
| Encoder: An implementation which transforms a header list into a | Encoder: An implementation which transforms a header list into a | |||
| header block. | header block. | |||
| Decoder: An implementation which transforms a header block into a | Decoder: An implementation which transforms a header block into a | |||
| header list. | header list. | |||
| Absolute Index: A unique index for each entry in the dynamic table. | Absolute Index: A unique index for each entry in the dynamic table. | |||
| Base: A reference point for relative indicies. Dynamic references | Base: A reference point for relative indices. Dynamic references | |||
| are made relative to a Base in header blocks. | are made relative to a Base in header blocks. | |||
| Insert Count: The total number of entries inserted in the dynamic | Insert Count: The total number of entries inserted in the dynamic | |||
| table. | table. | |||
| QPACK is a name, not an acronym. | QPACK is a name, not an acronym. | |||
| 1.2. Notational Conventions | 1.2. Notational Conventions | |||
| Diagrams use the format described in Section 3.1 of [RFC2360], with | Diagrams use the format described in Section 3.1 of [RFC2360], with | |||
| skipping to change at page 5, line 11 ¶ | skipping to change at page 5, line 4 ¶ | |||
| table. | table. | |||
| QPACK is a name, not an acronym. | QPACK is a name, not an acronym. | |||
| 1.2. Notational Conventions | 1.2. Notational Conventions | |||
| Diagrams use the format described in Section 3.1 of [RFC2360], with | Diagrams use the format described in Section 3.1 of [RFC2360], with | |||
| the following additional conventions: | the following additional conventions: | |||
| x (A) Indicates that x is A bits long | x (A) Indicates that x is A bits long | |||
| x (A+) Indicates that x uses the prefixed integer encoding defined | x (A+) Indicates that x uses the prefixed integer encoding defined | |||
| in Section 5.1 of [RFC7541], beginning with an A-bit prefix. | in Section 5.1 of [RFC7541], beginning with an A-bit prefix. | |||
| x ... Indicates that x is variable-length and extends to the end of | x ... Indicates that x is variable-length and extends to the end of | |||
| the region. | the region. | |||
| 2. Compression Process Overview | 2. Compression Process Overview | |||
| Like HPACK, QPACK uses two tables for associating header fields to | Like HPACK, QPACK uses two tables for associating header fields to | |||
| indices. The static table (see Section 3.1) is predefined and | indices. The static table (see Section 3.1) is predefined and | |||
| contains common header fields (some of them with an empty value). | contains common header fields (some of them with an empty value). | |||
| The dynamic table (see Section 3.2) is built up over the course of | The dynamic table (see Section 3.2) is built up over the course of | |||
| the connection and can be used by the encoder to index header fields | the connection and can be used by the encoder to index header fields | |||
| in the encoded header lists. | in the encoded header lists. | |||
| QPACK instructions appear in three different types of streams: | QPACK defines unidirectional streams for sending instructions from | |||
| encoder to decoder and vice versa. | ||||
| o The encoder uses a unidirectional stream to modify the state of | ||||
| the dynamic table without emitting header fields associated with | ||||
| any particular request. | ||||
| o HEADERS and PUSH_PROMISE frames on request and push streams | ||||
| reference the table state without modifying it. | ||||
| o The decoder sends feedback to the encoder on a unidirectional | ||||
| stream. This feedback enables the encoder to manage dynamic table | ||||
| state. | ||||
| 2.1. Encoder | 2.1. Encoder | |||
| An encoder compresses a header list by emitting either an indexed or | An encoder converts a header list into a header block by emitting | |||
| a literal representation for each header field in the list. | either an indexed or a literal representation for each header field | |||
| References to the static table and literal representations do not | in the list (see Section 4.5). Indexed representations achieve high | |||
| require any dynamic state and never risk head-of-line blocking. | compression by replacing the literal name and possibly the value with | |||
| References to the dynamic table risk head-of-line blocking if the | an index to either the static or dynamic table. References to the | |||
| encoder has not received an acknowledgement indicating the entry is | static table and literal representations do not require any dynamic | |||
| available at the decoder. | state and never risk head-of-line blocking. References to the | |||
| dynamic table risk head-of-line blocking if the encoder has not | ||||
| received an acknowledgement indicating the entry is available at the | ||||
| decoder. | ||||
| An encoder MAY insert any entry in the dynamic table it chooses; it | An encoder MAY insert any entry in the dynamic table it chooses; it | |||
| is not limited to header fields it is compressing. | is not limited to header fields it is compressing. | |||
| QPACK preserves the ordering of header fields within each header | QPACK preserves the ordering of header fields within each header | |||
| list. An encoder MUST emit header field representations in the order | list. An encoder MUST emit header field representations in the order | |||
| they appear in the input header list. | they appear in the input header list. | |||
| QPACK is designed to contain the more complex state tracking to the | QPACK is designed to contain the more complex state tracking to the | |||
| encoder, while the decoder is relatively simple. | encoder, while the decoder is relatively simple. | |||
| 2.1.1. Reference Tracking | 2.1.1. Reference Tracking | |||
| An encoder MUST ensure that a header block which references a dynamic | An encoder MUST ensure that a header block which references a dynamic | |||
| table entry is not received by the decoder after the referenced entry | table entry is not processed by the decoder after the referenced | |||
| has been evicted. Hence the encoder needs to track information about | entry has been evicted. Hence the encoder needs to track information | |||
| each compressed header block that references the dynamic table until | about each compressed header block that references the dynamic table | |||
| that header block is acknowledged by the decoder. | until that header block is acknowledged by the decoder (see | |||
| Section 4.4.1). | ||||
| 2.1.2. Blocked Dynamic Table Insertions | 2.1.2. Blocked Dynamic Table Insertions | |||
| A dynamic table entry is considered blocking and cannot be evicted | A dynamic table entry is considered blocking and cannot be evicted | |||
| until its insertion has been acknowledged and there are no | until its insertion has been acknowledged and there are no | |||
| outstanding unacknowledged references to the entry. In particular, a | outstanding unacknowledged references to the entry. In particular, a | |||
| dynamic table entry that has never been referenced can still be | dynamic table entry that has never been referenced can still be | |||
| blocking. | blocking. | |||
| Note: A blocking entry is unrelated to a blocked stream, which is a | Note: A blocking entry is unrelated to a blocked stream, which is a | |||
| stream that a decoder cannot decode as a result of references to | stream that a decoder cannot decode as a result of references to | |||
| entries that are not yet available. Any encoder that uses the | entries that are not yet available. An encoder that uses the | |||
| dynamic table has to keep track of blocked entries, whereas | dynamic table has to keep track of blocked entries. | |||
| blocked streams are optional. | ||||
| An encoder MUST NOT insert an entry into the dynamic table (or | An encoder MUST NOT insert an entry into the dynamic table (or | |||
| duplicate an existing entry) if doing so would evict a blocking | duplicate an existing entry) if doing so would evict a blocking | |||
| entry. In this case, the encoder can send literal representations of | entry. | |||
| header fields. | ||||
| 2.1.2.1. Avoiding Blocked Insertions | ||||
| To ensure that the encoder is not prevented from adding new entries, | To ensure that the encoder is not prevented from adding new entries, | |||
| the encoder can avoid referencing entries that are close to eviction. | the encoder can avoid referencing entries that are close to eviction. | |||
| Rather than reference such an entry, the encoder can emit a Duplicate | Rather than reference such an entry, the encoder can emit a Duplicate | |||
| instruction (see Section 4.3.3), and reference the duplicate instead. | instruction (see Section 4.3.4), and reference the duplicate instead. | |||
| Determining which entries are too close to eviction to reference is | Determining which entries are too close to eviction to reference is | |||
| an encoder preference. One heuristic is to target a fixed amount of | an encoder preference. One heuristic is to target a fixed amount of | |||
| available space in the dynamic table: either unused space or space | available space in the dynamic table: either unused space or space | |||
| that can be reclaimed by evicting non-blocking entries. To achieve | that can be reclaimed by evicting non-blocking entries. To achieve | |||
| this, the encoder can maintain a draining index, which is the | this, the encoder can maintain a draining index, which is the | |||
| smallest absolute index in the dynamic table that it will emit a | smallest absolute index (see Section 3.2.4) in the dynamic table that | |||
| reference for. As new entries are inserted, the encoder increases | it will emit a reference for. As new entries are inserted, the | |||
| the draining index to maintain the section of the table that it will | encoder increases the draining index to maintain the section of the | |||
| not reference. If the encoder does not create new references to | table that it will not reference. If the encoder does not create new | |||
| entries with an absolute index lower than the draining index, the | references to entries with an absolute index lower than the draining | |||
| number of unacknowledged references to those entries will eventually | index, the number of unacknowledged references to those entries will | |||
| become zero, allowing them to be evicted. | eventually become zero, allowing them to be evicted. | |||
| +----------+---------------------------------+--------+ | +----------+---------------------------------+--------+ | |||
| | Draining | Referenceable | Unused | | | Draining | Referenceable | Unused | | |||
| | Entries | Entries | Space | | | Entries | Entries | Space | | |||
| +----------+---------------------------------+--------+ | +----------+---------------------------------+--------+ | |||
| ^ ^ ^ | ^ ^ ^ | |||
| | | | | | | | | |||
| Dropping Draining Index Insertion Point | Dropping Draining Index Insertion Point | |||
| Point | Point | |||
| Figure 1: Draining Dynamic Table Entries | Figure 1: Draining Dynamic Table Entries | |||
| 2.1.3. Avoiding Head-of-Line Blocking | 2.1.3. Blocked Streams | |||
| Because QUIC does not guarantee order between data on different | Because QUIC does not guarantee order between data on different | |||
| streams, a header block might reference an entry in the dynamic table | streams, a decoder might encounter a header block that references a | |||
| that has not yet been received. | dynamic table entry that it has not yet received. | |||
| Each header block contains a Required Insert Count, the lowest | ||||
| possible value for the Insert Count with which the header block can | ||||
| be decoded. For a header block with references to the dynamic table, | ||||
| the Required Insert Count is one larger than the largest Absolute | ||||
| Index of all referenced dynamic table entries. For a header block | ||||
| with no references to the dynamic table, the Required Insert Count is | ||||
| zero. | ||||
| If the decoder encounters a header block with a Required Insert Count | ||||
| value larger than defined above, it MAY treat this as a stream error | ||||
| of type HTTP_QPACK_DECOMPRESSION_FAILED. If the decoder encounters a | ||||
| header block with a Required Insert Count value smaller than defined | ||||
| above, it MUST treat this as a stream error of type | ||||
| HTTP_QPACK_DECOMPRESSION_FAILED as prescribed in Section 3.2.7. | ||||
| When the Required Insert Count is zero, the frame contains no | Each header block contains a Required Insert Count (see | |||
| references to the dynamic table and can always be processed | Section 4.5.1), the lowest possible value for the Insert Count with | |||
| immediately. | which the header block can be decoded. For a header block with | |||
| references to the dynamic table, the Required Insert Count is one | ||||
| larger than the largest absolute index of all referenced dynamic | ||||
| table entries. For a header block with no references to the dynamic | ||||
| table, the Required Insert Count is zero. | ||||
| If the Required Insert Count is greater than the number of dynamic | When the decoder receives a header block with a Required Insert Count | |||
| table entries received, the stream is considered "blocked." While | greater than its own Insert Count, the stream cannot be processed | |||
| blocked, header field data SHOULD remain in the blocked stream's flow | immediately, and is considered "blocked" (see {blocked-decoding}). | |||
| control window. A stream becomes unblocked when the Insert Count | ||||
| becomes greater than or equal to the Required Insert Count for all | ||||
| header blocks the decoder has started reading from the stream. | ||||
| The SETTINGS_QPACK_BLOCKED_STREAMS setting (see Section 5) specifies | The SETTINGS_QPACK_BLOCKED_STREAMS setting (see Section 5) specifies | |||
| an upper bound on the number of streams which can be blocked. An | an upper bound on the number of streams which can be blocked. An | |||
| encoder MUST limit the number of streams which could become blocked | encoder MUST limit the number of streams which could become blocked | |||
| to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. Note | to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. Note | |||
| that the decoder might not actually become blocked on every stream | that the decoder might not become blocked on every stream which risks | |||
| which risks becoming blocked. If the decoder encounters more blocked | becoming blocked. | |||
| streams than it promised to support, it MUST treat this as a stream | ||||
| error of type HTTP_QPACK_DECOMPRESSION_FAILED. | ||||
| An encoder can decide whether to risk having a stream become blocked. | An encoder can decide whether to risk having a stream become blocked. | |||
| If permitted by the value of SETTINGS_QPACK_BLOCKED_STREAMS, | If permitted by the value of SETTINGS_QPACK_BLOCKED_STREAMS, | |||
| compression efficiency can often be improved by referencing dynamic | compression efficiency can often be improved by referencing dynamic | |||
| table entries that are still in transit, but if there is loss or | table entries that are still in transit, but if there is loss or | |||
| reordering the stream can become blocked at the decoder. An encoder | reordering the stream can become blocked at the decoder. An encoder | |||
| avoids the risk of blocking by only referencing dynamic table entries | avoids the risk of blocking by only referencing dynamic table entries | |||
| which have been acknowledged, but this could mean using literals. | which have been acknowledged, but this could mean using literals. | |||
| Since literals make the header block larger, this can result in the | Since literals make the header block larger, this can result in the | |||
| encoder becoming blocked on congestion or flow control limits. | encoder becoming blocked on congestion or flow control limits. | |||
| 2.1.4. Known Received Count | 2.1.4. Known Received Count | |||
| In order to identify which dynamic table entries can be safely used | In order to identify which dynamic table entries can be safely used | |||
| without a stream becoming blocked, the encoder tracks the number of | without a stream becoming blocked, the encoder tracks the number of | |||
| entries received by the decoder. The Known Received Count tracks the | entries received by the decoder. The Known Received Count tracks the | |||
| total number of acknowledged insertions. | total number of acknowledged insertions. | |||
| When blocking references are permitted, the encoder uses header block | When blocking references are permitted, the encoder uses Header | |||
| acknowledgement to maintain the Known Received Count, as described in | Acknowledgement instructions (Section 4.4.1) to maintain the Known | |||
| Section 4.4.2. | Received Count. If a header block was potentially blocking, the | |||
| acknowledgement implies that the decoder has received all dynamic | ||||
| table state necessary to process the header block. If the Required | ||||
| Insert Count of an acknowledged header block was greater than the | ||||
| encoder's current Known Received Count, the block's Required Insert | ||||
| Count becomes the new Known Received Count. | ||||
| To acknowledge dynamic table entries which are not referenced by | To acknowledge dynamic table entries which are not referenced by | |||
| header blocks, for example because the encoder or the decoder have | header blocks, for example because the encoder or the decoder have | |||
| chosen not to risk blocked streams, the decoder sends an Insert Count | chosen not to risk blocked streams, the decoder sends an Insert Count | |||
| Increment instruction (see Section 4.4.1). | Increment instruction (see Section 4.4.3). | |||
| 2.2. Decoder | 2.2. Decoder | |||
| As in HPACK, the decoder processes header blocks and emits the | As in HPACK, the decoder processes header blocks and emits the | |||
| corresponding header lists. It also processes dynamic table | corresponding header lists. It also processes dynamic table | |||
| modifications from encoder instructions received on the encoder | modifications from encoder instructions received on the encoder | |||
| stream. | stream. | |||
| The decoder MUST emit header fields in the order their | The decoder MUST emit header fields in the order their | |||
| representations appear in the input header block. | representations appear in the input header block. | |||
| 2.2.1. State Synchronization | 2.2.1. Blocked Decoding | |||
| The decoder instructions (Section 4.4) signal key events at the | Upon receipt of a header block, the decoder examines the Required | |||
| decoder that permit the encoder to track the decoder's state. These | Insert Count. When the Required Insert Count is less than or equal | |||
| events are: | to the decoder's Insert Count, the header block can be processed | |||
| immediately. Otherwise, the stream on which the header block was | ||||
| received becomes blocked. | ||||
| o Complete processing of a header block | While blocked, header block data SHOULD remain in the blocked | |||
| stream's flow control window. A stream becomes unblocked when the | ||||
| Insert Count becomes greater than or equal to the Required Insert | ||||
| Count for all header blocks the decoder has started reading from the | ||||
| stream. | ||||
| o Abandonment of a stream which might have remaining header blocks | When processing header blocks, the decoder expects the Required | |||
| Insert Count to exactly match the value defined in {{blocked- | ||||
| streams}. If it encounters a smaller value than expected, it MUST | ||||
| treat this as a connection error of type | ||||
| HTTP_QPACK_DECOMPRESSION_FAILED (see Section 2.2.3). If it | ||||
| encounters a larger value than expected, it MAY treat this as a | ||||
| connection error of type HTTP_QPACK_DECOMPRESSION_FAILED. | ||||
| o Receipt of new dynamic table entries | If the decoder encounters more blocked streams than it promised to | |||
| support, it MUST treat this as a connection error of type | ||||
| HTTP_QPACK_DECOMPRESSION_FAILED. | ||||
| Knowledge that a header block with references to the dynamic table | 2.2.2. State Synchronization | |||
| has been processed permits the encoder to evict entries to which no | ||||
| unacknowledged references remain (see Section 2.1.2). When a stream | ||||
| is reset or abandoned, the indication that these header blocks will | ||||
| never be processed serves a similar function (see Section 4.4.3). | ||||
| The decoder chooses when to emit Insert Count Increment instructions | The decoder signals the following events by emitting decoder | |||
| (see Section 4.4.1). Emitting an instruction after adding each new | instructions (Section 4.4) on the decoder stream. | |||
| dynamic table entry will provide the most timely feedback to the | ||||
| 2.2.2.1. Completed Processing of a Header Block | ||||
| When the decoder finishes decoding a header block containing dynamic | ||||
| table references, it emits a Header Acknowledgement instruction | ||||
| (Section 4.4.1). A stream may carry multiple header blocks in the | ||||
| case of intermediate responses, trailers, and pushed requests. The | ||||
| encoder interprets each Header Acknowledgement instruction as | ||||
| acknowledging the earliest unacknowledged header block containing | ||||
| dynamic table references sent on the given stream. | ||||
| 2.2.2.2. Abandonment of a Stream | ||||
| When an endpoint receives a stream reset before the end of a stream | ||||
| or before all header blocks are processed on that stream, or when it | ||||
| abandons reading of a stream, it generates a Stream Cancellation | ||||
| instruction (see Section 4.4.2). This signals to the encoder that | ||||
| all references to the dynamic table on that stream are no longer | ||||
| outstanding. A decoder with a maximum dynamic table capacity equal | ||||
| to zero (see Section 3.2.3) MAY omit sending Stream Cancellations, | ||||
| because the encoder cannot have any dynamic table references. An | ||||
| encoder cannot infer from this instruction that any updates to the | ||||
| dynamic table have been received. | ||||
| The Header Acknowledgement and Stream Cancellation instructions | ||||
| permit the encoder to remove references to entries in the dynamic | ||||
| table. When entries have zero references they are no longer | ||||
| considered blocking (see Section 2.1.2). | ||||
| 2.2.2.3. New Table Entries | ||||
| After receiving new table entries on the encoder stream, the decoder | ||||
| chooses when to emit Insert Count Increment instructions (see | ||||
| Section 4.4.3). Emitting this instruction after adding each new | ||||
| dynamic table entry will provide the timeliest feedback to the | ||||
| encoder, but could be redundant with other decoder feedback. By | encoder, but could be redundant with other decoder feedback. By | |||
| delaying an Insert Count Increment instruction, the decoder might be | delaying an Insert Count Increment instruction, the decoder might be | |||
| able to coalesce multiple Insert Count Increment instructions, or | able to coalesce multiple Insert Count Increment instructions, or | |||
| replace them entirely with Header Acknowledgements (see | replace them entirely with Header Acknowledgements (see | |||
| Section 4.4.2). However, delaying too long may lead to compression | Section 4.4.1). However, delaying too long may lead to compression | |||
| inefficiencies if the encoder waits for an entry to be acknowledged | inefficiencies if the encoder waits for an entry to be acknowledged | |||
| before using it. | before using it. | |||
| 2.2.2. Blocked Decoding | 2.2.3. Invalid References | |||
| To track blocked streams, the Required Insert Count value for each | If the decoder encounters a reference in a header block | |||
| stream can be used. Whenever the decoder processes a table update, | representation to a dynamic table entry which has already been | |||
| it can begin decoding any blocked streams that now have their | evicted or which has an absolute index greater than or equal to the | |||
| dependencies satisfied. | declared Required Insert Count (see Section 4.5.1), it MUST treat | |||
| this as a connection error of type "HTTP_QPACK_DECOMPRESSION_FAILED". | ||||
| If the decoder encounters a reference in an encoder instruction to a | ||||
| dynamic table entry which has already been evicted, it MUST treat | ||||
| this as a connection error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| 3. Header Tables | 3. Header Tables | |||
| Unlike in HPACK, entries in the QPACK static and dynamic tables are | Unlike in HPACK, entries in the QPACK static and dynamic tables are | |||
| addressed separately. The following sections describe how entries in | addressed separately. The following sections describe how entries in | |||
| each table are addressed. | each table are addressed. | |||
| 3.1. Static Table | 3.1. Static Table | |||
| The static table consists of a predefined static list of header | The static table consists of a predefined static list of header | |||
| fields, each of which has a fixed index over time. Its entries are | fields, each of which has a fixed index over time. Its entries are | |||
| defined in Appendix A. | defined in Appendix A. | |||
| All entries in the static table have a name and a value. However, | All entries in the static table have a name and a value. However, | |||
| values can be empty (that is, have a length of 0). | values can be empty (that is, have a length of 0). Each entry is | |||
| identified by a unique index. | ||||
| Note the QPACK static table is indexed from 0, whereas the HPACK | Note the QPACK static table is indexed from 0, whereas the HPACK | |||
| static table is indexed from 1. | static table is indexed from 1. | |||
| When the decoder encounters an invalid static table index in a header | When the decoder encounters an invalid static table index in a header | |||
| block instruction it MUST treat this as a stream error of type | block representation it MUST treat this as a connection error of type | |||
| "HTTP_QPACK_DECOMPRESSION_FAILED". If this index is received on the | "HTTP_QPACK_DECOMPRESSION_FAILED". If this index is received on the | |||
| encoder stream, this MUST be treated as a connection error of type | encoder stream, this MUST be treated as a connection error of type | |||
| "HTTP_QPACK_ENCODER_STREAM_ERROR". | "HTTP_QPACK_ENCODER_STREAM_ERROR". | |||
| 3.2. Dynamic Table | 3.2. Dynamic Table | |||
| The dynamic table consists of a list of header fields maintained in | The dynamic table consists of a list of header fields maintained in | |||
| first-in, first-out order. Each HTTP/3 endpoint holds a dynamic | first-in, first-out order. Each HTTP/3 endpoint holds a dynamic | |||
| table that is initially empty. Entries are added by encoder | table that is initially empty. Entries are added by encoder | |||
| instructions received on the encoder stream (see Section 4.3). | instructions received on the encoder stream (see Section 4.3). | |||
| The dynamic table can contain duplicate entries (i.e., entries with | The dynamic table can contain duplicate entries (i.e., entries with | |||
| the same name and same value). Therefore, duplicate entries MUST NOT | the same name and same value). Therefore, duplicate entries MUST NOT | |||
| be treated as an error by the decoder. | be treated as an error by the decoder. | |||
| Dynamic table entries can have empty values. | ||||
| 3.2.1. Dynamic Table Size | 3.2.1. Dynamic Table Size | |||
| The size of the dynamic table is the sum of the size of its entries. | The size of the dynamic table is the sum of the size of its entries. | |||
| The size of an entry is the sum of its name's length in bytes (as | The size of an entry is the sum of its name's length in bytes (as | |||
| defined in Section 4.1.2), its value's length in bytes, and 32. | defined in Section 4.1.2), its value's length in bytes, and 32. | |||
| The size of an entry is calculated using the length of its name and | The size of an entry is calculated using the length of its name and | |||
| value without Huffman encoding applied. | value without Huffman encoding applied. | |||
| 3.2.2. Dynamic Table Capacity and Eviction | 3.2.2. Dynamic Table Capacity and Eviction | |||
| The encoder sets the capacity of the dynamic table, which serves as | The encoder sets the capacity of the dynamic table, which serves as | |||
| the upper limit on its size. The initial capcity of the dynamic | the upper limit on its size. The initial capacity of the dynamic | |||
| table is zero. | table is zero. The encoder sends a Set Dynamic Table Capacity | |||
| instruction (Section 4.3.1) with a non-zero capacity to begin using | ||||
| the dynamic table. | ||||
| Before a new entry is added to the dynamic table, entries are evicted | Before a new entry is added to the dynamic table, entries are evicted | |||
| from the end of the dynamic table until the size of the dynamic table | from the end of the dynamic table until the size of the dynamic table | |||
| is less than or equal to (table capacity - size of new entry) or | is less than or equal to (table capacity - size of new entry). The | |||
| until the table is empty. The encoder MUST NOT evict a blocking | encoder MUST NOT evict a blocking dynamic table entry (see | |||
| dynamic table entry (see Section 2.1.2). | Section 2.1.2). The entry is then added to the table. It is an | |||
| If the size of the new entry is less than or equal to the dynamic | ||||
| table capacity, then that entry is added to the table. It is an | ||||
| error if the encoder attempts to add an entry that is larger than the | error if the encoder attempts to add an entry that is larger than the | |||
| dynamic table capacity; the decoder MUST treat this as a connection | dynamic table capacity; the decoder MUST treat this as a connection | |||
| error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". | error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". | |||
| A new entry can reference an entry in the dynamic table that will be | A new entry can reference an entry in the dynamic table that will be | |||
| evicted when adding this new entry into the dynamic table. | evicted when adding this new entry into the dynamic table. | |||
| Implementations are cautioned to avoid deleting the referenced name | Implementations are cautioned to avoid deleting the referenced name | |||
| or value if the referenced entry is evicted from the dynamic table | or value if the referenced entry is evicted from the dynamic table | |||
| prior to inserting the new entry. | prior to inserting the new entry. | |||
| Whenever the dynamic table capacity is reduced by the encoder, | Whenever the dynamic table capacity is reduced by the encoder (see | |||
| entries are evicted from the end of the dynamic table until the size | Section 4.3.1), entries are evicted from the end of the dynamic table | |||
| of the dynamic table is less than or equal to the new table capacity. | until the size of the dynamic table is less than or equal to the new | |||
| This mechanism can be used to completely clear entries from the | table capacity. This mechanism can be used to completely clear | |||
| dynamic table by setting a capacity of 0, which can subsequently be | entries from the dynamic table by setting a capacity of 0, which can | |||
| restored. | subsequently be restored. | |||
| 3.2.3. Maximum Dynamic Table Capacity | 3.2.3. Maximum Dynamic Table Capacity | |||
| To bound the memory requirements of the decoder, the decoder limits | To bound the memory requirements of the decoder, the decoder limits | |||
| the maximum value the encoder is permitted to set for the dynamic | the maximum value the encoder is permitted to set for the dynamic | |||
| table capacity. In HTTP/3, this limit is determined by the value of | table capacity. In HTTP/3, this limit is determined by the value of | |||
| SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder (see | SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder (see | |||
| Section 5). The encoder MUST not set a dynamic table capacity that | Section 5). The encoder MUST not set a dynamic table capacity that | |||
| exceeds this maximum, but it can choose to use a lower dynamic table | exceeds this maximum, but it can choose to use a lower dynamic table | |||
| capacity (see Section 4.3.4). | capacity (see Section 4.3.1). | |||
| For clients using 0-RTT data in HTTP/3, the server's maximum table | For clients using 0-RTT data in HTTP/3, the server's maximum table | |||
| capacity is the remembered value of the setting, or zero if the value | capacity is the remembered value of the setting, or zero if the value | |||
| was not previously sent. When the client's 0-RTT value of the | was not previously sent. When the client's 0-RTT value of the | |||
| SETTING is 0, the server MAY set it to a non-zero value in its | SETTING is 0, the server MAY set it to a non-zero value in its | |||
| SETTINGS frame. If the remembered value is non-zero, the server MUST | SETTINGS frame. If the remembered value is non-zero, the server MUST | |||
| send the same non-zero value in its SETTINGS frame. If it specifies | send the same non-zero value in its SETTINGS frame. If it specifies | |||
| any other value, or omits SETTINGS_QPACK_MAX_TABLE_CAPACITY from | any other value, or omits SETTINGS_QPACK_MAX_TABLE_CAPACITY from | |||
| SETTINGS, the encoder must treat this as a connection error of type | SETTINGS, the encoder must treat this as a connection error of type | |||
| "HTTP_QPACK_DECODER_STREAM_ERROR". | "HTTP_QPACK_DECODER_STREAM_ERROR". | |||
| skipping to change at page 12, line 14 ¶ | skipping to change at page 12, line 47 ¶ | |||
| 3.2.4. Absolute Indexing | 3.2.4. Absolute Indexing | |||
| Each entry possesses both an absolute index which is fixed for the | Each entry possesses both an absolute index which is fixed for the | |||
| lifetime of that entry and a relative index which changes based on | lifetime of that entry and a relative index which changes based on | |||
| the context of the reference. The first entry inserted has an | the context of the reference. The first entry inserted has an | |||
| absolute index of "0"; indices increase by one with each insertion. | absolute index of "0"; indices increase by one with each insertion. | |||
| 3.2.5. Relative Indexing | 3.2.5. Relative Indexing | |||
| The relative index begins at zero and increases in the opposite | Relative indices begin at zero and increase in the opposite direction | |||
| direction from the absolute index. Determining which entry has a | from the absolute index. Determining which entry has a relative | |||
| relative index of "0" depends on the context of the reference. | index of "0" depends on the context of the reference. | |||
| In encoder instructions, a relative index of "0" always refers to the | In encoder instructions, a relative index of "0" always refers to the | |||
| most recently inserted value in the dynamic table. Note that this | most recently inserted value in the dynamic table. Note that this | |||
| means the entry referenced by a given relative index will change | means the entry referenced by a given relative index will change | |||
| while interpreting instructions on the encoder stream. | while interpreting instructions on the encoder stream. | |||
| +-----+---------------+-------+ | +-----+---------------+-------+ | |||
| | n-1 | ... | d | Absolute Index | | n-1 | ... | d | Absolute Index | |||
| + - - +---------------+ - - - + | + - - +---------------+ - - - + | |||
| | 0 | ... | n-d-1 | Relative Index | | 0 | ... | n-d-1 | Relative Index | |||
| +-----+---------------+-------+ | +-----+---------------+-------+ | |||
| ^ | | ^ | | |||
| | V | | V | |||
| Insertion Point Dropping Point | Insertion Point Dropping Point | |||
| n = count of entries inserted | n = count of entries inserted | |||
| d = count of entries dropped | d = count of entries dropped | |||
| Example Dynamic Table Indexing - Control Stream | Example Dynamic Table Indexing - Encoder Stream | |||
| Unlike encoder instructions, relative indices in header block | Unlike encoder instructions, relative indices in header block | |||
| instructions are relative to the Base at the beginning of the header | representations are relative to the Base at the beginning of the | |||
| block (see Section 4.5.1). This ensures that references are stable | header block (see Section 4.5.1). This ensures that references are | |||
| even if the dynamic table is updated while decoding a header block. | stable even if header blocks and dynamic table updates are processed | |||
| out of order. | ||||
| The Base is encoded as a value relative to the Required Insert Count. | ||||
| The Base identifies which dynamic table entries can be referenced | ||||
| using relative indexing, starting with 0 at the last entry added. | ||||
| Post-Base references are used for entries inserted after base, | In a header block a relative index of "0" refers to the entry with | |||
| starting at 0 for the first entry added after the Base, see | absolute index equal to Base - 1. | |||
| Section 3.2.6. | ||||
| Required | Required | |||
| Insert | Insert | |||
| Count Base | Count Base | |||
| | | | | | | |||
| V V | V V | |||
| +-----+-----+-----+-----+-------+ | +-----+-----+-----+-----+-------+ | |||
| | n-1 | n-2 | n-3 | ... | d | Absolute Index | | n-1 | n-2 | n-3 | ... | d | Absolute Index | |||
| +-----+-----+ - +-----+ - + | +-----+-----+ - +-----+ - + | |||
| | 0 | ... | n-d-3 | Relative Index | | 0 | ... | n-d-3 | Relative Index | |||
| +-----+-----+-------+ | +-----+-----+-------+ | |||
| n = count of entries inserted | n = count of entries inserted | |||
| d = count of entries dropped | d = count of entries dropped | |||
| Example Dynamic Table Indexing - Relative Index in Header Block | Example Dynamic Table Indexing - Relative Index in Header Block | |||
| 3.2.6. Post-Base Indexing | 3.2.6. Post-Base Indexing | |||
| A header block can reference entries added after the entry identified | Post-Base indices are used for entries with absolute indexes greater | |||
| by the Base. This allows an encoder to process a header block in a | than or equal to Base, starting at 0 for the entry with absolute | |||
| index equal to Base, and increasing in the same direction as the | ||||
| absolute index. | ||||
| Post-Base indices allow an encoder to process a header block in a | ||||
| single pass and include references to entries added while processing | single pass and include references to entries added while processing | |||
| this (or other) header blocks. Newly added entries are referenced | this (or other) header blocks. | |||
| using Post-Base instructions. Indices for Post-Base instructions | ||||
| increase in the same direction as absolute indices, with the zero | ||||
| value being the first entry inserted after the Base. | ||||
| Base | Base | |||
| | | | | |||
| V | V | |||
| +-----+-----+-----+-----+-----+ | +-----+-----+-----+-----+-----+ | |||
| | n-1 | n-2 | n-3 | ... | d | Absolute Index | | n-1 | n-2 | n-3 | ... | d | Absolute Index | |||
| +-----+-----+-----+-----+-----+ | +-----+-----+-----+-----+-----+ | |||
| | 1 | 0 | Post-Base Index | | 1 | 0 | Post-Base Index | |||
| +-----+-----+ | +-----+-----+ | |||
| n = count of entries inserted | n = count of entries inserted | |||
| d = count of entries dropped | d = count of entries dropped | |||
| Example Dynamic Table Indexing - Post-Base Index in Header Block | Example Dynamic Table Indexing - Post-Base Index in Header Block | |||
| 3.2.7. Invalid References | ||||
| If the decoder encounters a reference in a header block instruction | ||||
| to a dynamic table entry which has already been evicted or which has | ||||
| an absolute index greater than or equal to the declared Required | ||||
| Insert Count (see Section 4.5.1), it MUST treat this as a stream | ||||
| error of type "HTTP_QPACK_DECOMPRESSION_FAILED". | ||||
| If the decoder encounters a reference in an encoder instruction to a | ||||
| dynamic table entry which has already been dropped, it MUST treat | ||||
| this as a connection error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| 4. Wire Format | 4. Wire Format | |||
| 4.1. Primitives | 4.1. Primitives | |||
| 4.1.1. Prefixed Integers | 4.1.1. Prefixed Integers | |||
| The prefixed integer from Section 5.1 of [RFC7541] is used heavily | The prefixed integer from Section 5.1 of [RFC7541] is used heavily | |||
| throughout this document. The format from [RFC7541] is used | throughout this document. The format from [RFC7541] is used | |||
| unmodified. QPACK implementations MUST be able to decode integers up | unmodified. QPACK implementations MUST be able to decode integers up | |||
| to 62 bits long. | to 62 bits long. | |||
| skipping to change at page 14, line 42 ¶ | skipping to change at page 15, line 15 ¶ | |||
| This document expands the definition of string literals and permits | This document expands the definition of string literals and permits | |||
| them to begin other than on a byte boundary. An "N-bit prefix string | them to begin other than on a byte boundary. An "N-bit prefix string | |||
| literal" begins with the same Huffman flag, followed by the length | literal" begins with the same Huffman flag, followed by the length | |||
| encoded as an (N-1)-bit prefix integer. The remainder of the string | encoded as an (N-1)-bit prefix integer. The remainder of the string | |||
| literal is unmodified. | literal is unmodified. | |||
| A string literal without a prefix length noted is an 8-bit prefix | A string literal without a prefix length noted is an 8-bit prefix | |||
| string literal and follows the definitions in [RFC7541] without | string literal and follows the definitions in [RFC7541] without | |||
| modification. | modification. | |||
| 4.2. Instructions | 4.2. Encoder and Decoder Streams | |||
| There are three separate QPACK instruction spaces. Encoder | ||||
| instructions (Section 4.3) carry table updates, decoder instructions | ||||
| (Section 4.4) carry acknowledgments of table modifications and header | ||||
| processing, and header block instructions (Section 4.5) convey an | ||||
| encoded representation of a header list by referring to the QPACK | ||||
| table state. | ||||
| Encoder and decoder instructions appear on the unidirectional stream | ||||
| types described in this section. Header block instructions are | ||||
| contained in HEADERS and PUSH_PROMISE frames, which are conveyed on | ||||
| request or push streams as described in [HTTP3]. | ||||
| 4.2.1. Encoder and Decoder Streams | ||||
| QPACK defines two unidirectional stream types: | QPACK defines two unidirectional stream types: | |||
| o An encoder stream is a unidirectional stream of type "0x02". It | o An encoder stream is a unidirectional stream of type "0x02". It | |||
| carries an unframed sequence of encoder instructions from encoder | carries an unframed sequence of encoder instructions from encoder | |||
| to decoder. | to decoder. | |||
| o A decoder stream is a unidirectional stream of type "0x03". It | o A decoder stream is a unidirectional stream of type "0x03". It | |||
| carries an unframed sequence of decoder instructions from decoder | carries an unframed sequence of decoder instructions from decoder | |||
| to encoder. | to encoder. | |||
| HTTP/3 endpoints contain a QPACK encoder and decoder. Each endpoint | HTTP/3 endpoints contain a QPACK encoder and decoder. Each endpoint | |||
| MUST initiate a single encoder stream and decoder stream. Receipt of | MUST initiate at most one encoder stream and at most one decoder | |||
| a second instance of either stream type be MUST treated as a | stream. Receipt of a second instance of either stream type MUST be | |||
| connection error of type HTTP_WRONG_STREAM_COUNT. These streams MUST | treated as a connection error of type HTTP_WRONG_STREAM_COUNT. These | |||
| NOT be closed. Closure of either unidirectional stream type MUST be | streams MUST NOT be closed. Closure of either unidirectional stream | |||
| treated as a connection error of type HTTP_CLOSED_CRITICAL_STREAM. | type MUST be treated as a connection error of type | |||
| HTTP_CLOSED_CRITICAL_STREAM. | ||||
| An endpoint MAY avoid creating its own encoder stream if it's not | ||||
| going to be used (for example if the endpoint doesn't wish to use the | ||||
| dynamic table, or if the maximum size of the dynamic table permitted | ||||
| by the peer is zero). | ||||
| An endpoint MAY avoid creating its own decoder stream if the maximum | ||||
| size of its own dynamic table is zero. | ||||
| An endpoint MUST allow its peer to create both encoder and decoder | ||||
| streams even if the connection's settings prevent their use. | ||||
| 4.3. Encoder Instructions | 4.3. Encoder Instructions | |||
| Table updates can add a table entry, possibly using existing entries | An encoder sends encoder instructions on the encoder stream to set | |||
| to avoid transmitting redundant information. The name can be | the capacity of the dynamic table and add dynamic table entries. | |||
| transmitted as a reference to an existing entry in the static or the | Instructions adding table entries can use existing entries to avoid | |||
| dynamic table or as a string literal. For entries which already | transmitting redundant information. The name can be transmitted as a | |||
| exist in the dynamic table, the full entry can also be used by | reference to an existing entry in the static or the dynamic table or | |||
| reference, creating a duplicate entry. | as a string literal. For entries which already exist in the dynamic | |||
| table, the full entry can also be used by reference, creating a | ||||
| duplicate entry. | ||||
| This section specifies the following encoder instructions. | This section specifies the following encoder instructions. | |||
| 4.3.1. Insert With Name Reference | 4.3.1. Set Dynamic Table Capacity | |||
| An addition to the header table where the header field name matches | An encoder informs the decoder of a change to the dynamic table | |||
| the header field name of an entry stored in the static table or the | capacity using an instruction which begins with the '001' three-bit | |||
| dynamic table starts with the '1' one-bit pattern. The "S" bit | pattern. The new dynamic table capacity is represented as an integer | |||
| indicates whether the reference is to the static (S=1) or dynamic | with a 5-bit prefix (see Section 5.1 of [RFC7541]). | |||
| (S=0) table. The 6-bit prefix integer (see Section 5.1 of [RFC7541]) | ||||
| that follows is used to locate the table entry for the header name. | 0 1 2 3 4 5 6 7 | |||
| When S=1, the number represents the static table index; when S=0, the | +---+---+---+---+---+---+---+---+ | |||
| number is the relative index of the entry in the dynamic table. | | 0 | 0 | 1 | Capacity (5+) | | |||
| +---+---+---+-------------------+ | ||||
| Figure 2: Set Dynamic Table Capacity | ||||
| The new capacity MUST be lower than or equal to the limit described | ||||
| in Section 3.2.3. In HTTP/3, this limit is the value of the | ||||
| SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter (see Section 5) received | ||||
| from the decoder. The decoder MUST treat a new dynamic table | ||||
| capacity value that exceeds this limit as a connection error of type | ||||
| "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| Reducing the dynamic table capacity can cause entries to be evicted | ||||
| (see Section 3.2.2). This MUST NOT cause the eviction of blocking | ||||
| entries (see Section 2.1.2). Changing the capacity of the dynamic | ||||
| table is not acknowledged as this instruction does not insert an | ||||
| entry. | ||||
| 4.3.2. Insert With Name Reference | ||||
| An encoder adds an entry to the dynamic table where the header field | ||||
| name matches the header field name of an entry stored in the static | ||||
| or the dynamic table using an instruction that starts with the '1' | ||||
| one-bit pattern. The second ("S") bit indicates whether the | ||||
| reference is to the static or dynamic table. The 6-bit prefix | ||||
| integer (see Section 5.1 of [RFC7541]) that follows is used to locate | ||||
| the table entry for the header name. When S=1, the number represents | ||||
| the static table index; when S=0, the number is the relative index of | ||||
| the entry in the dynamic table. | ||||
| The header name reference is followed by the header field value | The header name reference is followed by the header field value | |||
| represented as a string literal (see Section 5.2 of [RFC7541]). | represented as a string literal (see Section 5.2 of [RFC7541]). | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | S | Name Index (6+) | | | 1 | S | Name Index (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length bytes) | | | Value String (Length bytes) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Insert Header Field -- Indexed Name | Insert Header Field -- Indexed Name | |||
| 4.3.2. Insert Without Name Reference | 4.3.3. Insert Without Name Reference | |||
| An addition to the header table where both the header field name and | An encoder adds an entry to the dynamic table where both the header | |||
| the header field value are represented as string literals (see | field name and the header field value are represented as string | |||
| Section 4.1) starts with the '01' two-bit pattern. | literals (see Section 4.1) using an instruction that starts with the | |||
| '01' two-bit pattern. | ||||
| The name is represented as a 6-bit prefix string literal, while the | The name is represented as a 6-bit prefix string literal, while the | |||
| value is represented as an 8-bit prefix string literal. | value is represented as an 8-bit prefix string literal. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | H | Name Length (5+) | | | 0 | 1 | H | Name Length (5+) | | |||
| +---+---+---+-------------------+ | +---+---+---+-------------------+ | |||
| | Name String (Length bytes) | | | Name String (Length bytes) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length bytes) | | | Value String (Length bytes) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Insert Header Field -- New Name | Insert Header Field -- New Name | |||
| 4.3.3. Duplicate | 4.3.4. Duplicate | |||
| Duplication of an existing entry in the dynamic table starts with the | An encoder duplicates an existing entry in the dynamic table using an | |||
| '000' three-bit pattern. The relative index of the existing entry is | instruction that starts with the '000' three-bit pattern. The | |||
| represented as an integer with a 5-bit prefix. | relative index of the existing entry is represented as an integer | |||
| with a 5-bit prefix. | ||||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 0 | 0 | Index (5+) | | | 0 | 0 | 0 | Index (5+) | | |||
| +---+---+---+-------------------+ | +---+---+---+-------------------+ | |||
| Figure 2: Duplicate | Figure 3: Duplicate | |||
| The existing entry is re-inserted into the dynamic table without | The existing entry is re-inserted into the dynamic table without | |||
| resending either the name or the value. This is useful to mitigate | resending either the name or the value. This is useful to mitigate | |||
| the eviction of older entries which are frequently referenced, both | the eviction of older entries which are frequently referenced, both | |||
| to avoid the need to resend the header and to avoid the entry in the | to avoid the need to resend the header and to avoid the entry in the | |||
| table blocking the ability to insert new headers. | table blocking the ability to insert new headers. | |||
| 4.3.4. Set Dynamic Table Capacity | ||||
| An encoder informs the decoder of a change to the dynamic table | ||||
| capacity using an instruction which begins with the '001' three-bit | ||||
| pattern. The new dynamic table capacity is represented as an integer | ||||
| with a 5-bit prefix (see Section 5.1 of [RFC7541]). | ||||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 0 | 1 | Capacity (5+) | | ||||
| +---+---+---+-------------------+ | ||||
| Figure 3: Set Dynamic Table Capacity | ||||
| The new capacity MUST be lower than or equal to the limit described | ||||
| in Section 3.2.3. In HTTP/3, this limit is the value of the | ||||
| SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter (see Section 5) received | ||||
| from the decoder. The decoder MUST treat a new dynamic table | ||||
| capacity value that exceeds this limit as a connection error of type | ||||
| "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| Reducing the dynamic table capacity can cause entries to be evicted | ||||
| (see Section 3.2.2). This MUST NOT cause the eviction of blocking | ||||
| entries (see Section 2.1.2). Changing the capacity of the dynamic | ||||
| table is not acknowledged as this instruction does not insert an | ||||
| entry. | ||||
| 4.4. Decoder Instructions | 4.4. Decoder Instructions | |||
| Decoder instructions provide information used to ensure consistency | Decoder instructions provide information used to ensure consistency | |||
| of the dynamic table. They are sent from the decoder to the encoder | of the dynamic table. They are sent from the decoder to the encoder | |||
| on a decoder stream; that is, the server informs the client about the | on a decoder stream; that is, the server informs the client about the | |||
| processing of the client's header blocks and table updates, and the | processing of the client's header blocks and table updates, and the | |||
| client informs the server about the processing of the server's header | client informs the server about the processing of the server's header | |||
| blocks and table updates. | blocks and table updates. | |||
| This section specifies the following decoder instructions. | This section specifies the following decoder instructions. | |||
| 4.4.1. Insert Count Increment | 4.4.1. Header Acknowledgement | |||
| The Insert Count Increment instruction begins with the '00' two-bit | ||||
| pattern. The instruction specifies the total number of dynamic table | ||||
| inserts and duplications since the last Insert Count Increment or | ||||
| Header Acknowledgement that increased the Known Received Count for | ||||
| the dynamic table (see Section 2.1.4). The Increment field is | ||||
| encoded as a 6-bit prefix integer. The encoder uses this value to | ||||
| determine which table entries might cause a stream to become blocked, | ||||
| as described in Section 2.2.1. | ||||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 0 | Increment (6+) | | ||||
| +---+---+-----------------------+ | ||||
| Figure 4: Insert Count Increment | ||||
| An encoder that receives an Increment field equal to zero or one that | ||||
| increases the Known Received Count beyond what the encoder has sent | ||||
| MUST treat this as a connection error of type | ||||
| "HTTP_QPACK_DECODER_STREAM_ERROR". | ||||
| 4.4.2. Header Acknowledgement | ||||
| After processing a header block whose declared Required Insert Count | After processing a header block whose declared Required Insert Count | |||
| is not zero, the decoder emits a Header Acknowledgement instruction | is not zero, the decoder emits a Header Acknowledgement instruction. | |||
| on the decoder stream. The instruction begins with the '1' one-bit | The instruction begins with the '1' one-bit pattern and includes the | |||
| pattern and includes the header block's associated stream ID, encoded | header block's associated stream ID, encoded as a 7-bit prefix | |||
| as a 7-bit prefix integer. It is used by the peer's encoder to know | integer. It is used by the peer's encoder to know when it is safe to | |||
| when it is safe to evict an entry, and possibly update the Known | evict an entry (Section 2.1.2), and possibly update the Known | |||
| Received Count. | Received Count (Section 2.1.4). | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | Stream ID (7+) | | | 1 | Stream ID (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| Figure 5: Header Acknowledgement | Figure 4: Header Acknowledgement | |||
| The same Stream ID can be identified multiple times, as multiple | ||||
| header blocks can be sent on a single stream in the case of | ||||
| intermediate responses, trailers, and pushed requests. Since HEADERS | ||||
| and PUSH_PROMISE frames on each stream are received and processed in | ||||
| order, this gives the encoder precise feedback on which header blocks | ||||
| within a stream have been fully processed. | ||||
| If an encoder receives a Header Acknowledgement instruction referring | If an encoder receives a Header Acknowledgement instruction referring | |||
| to a stream on which every header block with a non-zero Required | to a stream on which every header block with a non-zero Required | |||
| Insert Count has already been acknowledged, that MUST be treated as a | Insert Count has already been acknowledged, that MUST be treated as a | |||
| connection error of type "HTTP_QPACK_DECODER_STREAM_ERROR". | connection error of type "HTTP_QPACK_DECODER_STREAM_ERROR". | |||
| When blocking references are permitted, the encoder uses | 4.4.2. Stream Cancellation | |||
| acknowledgement of header blocks to update the Known Received Count. | ||||
| If a header block was potentially blocking, the acknowledgement | ||||
| implies that the decoder has received all dynamic table state | ||||
| necessary to process the header block. If the Required Insert Count | ||||
| of an acknowledged header block was greater than the encoder's | ||||
| current Known Received Count, the block's Required Insert Count | ||||
| becomes the new Known Received Count. | ||||
| 4.4.3. Stream Cancellation | ||||
| The instruction begins with the '01' two-bit pattern. The | When a stream is reset or reading is abandoned, the decoder emits a | |||
| instruction includes the stream ID of the affected stream - a request | Stream Cancellation instruction. The instruction begins with the | |||
| or push stream - encoded as a 6-bit prefix integer. | '01' two-bit pattern. The instruction includes the stream ID of the | |||
| affected stream encoded as a 6-bit prefix integer. See | ||||
| Section 2.2.2. | ||||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | Stream ID (6+) | | | 0 | 1 | Stream ID (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| Figure 6: Stream Cancellation | Figure 5: Stream Cancellation | |||
| A stream that is reset might have multiple outstanding header blocks | 4.4.3. Insert Count Increment | |||
| with dynamic table references. When an endpoint receives a stream | ||||
| reset before the end of a stream, it generates a Stream Cancellation | ||||
| instruction on the decoder stream. Similarly, when an endpoint | ||||
| abandons reading of a stream it needs to signal this using the Stream | ||||
| Cancellation instruction. This signals to the encoder that all | ||||
| references to the dynamic table on that stream are no longer | ||||
| outstanding. A decoder with a maximum dynamic table capacity equal | ||||
| to zero (see Section 3.2.3) MAY omit sending Stream Cancellations, | ||||
| because the encoder cannot have any dynamic table references. | ||||
| An encoder cannot infer from this instruction that any updates to the | The Insert Count Increment instruction begins with the '00' two-bit | |||
| dynamic table have been received. | pattern. The instruction specifies the total number of dynamic table | |||
| inserts and duplications since the last Insert Count Increment or | ||||
| Header Acknowledgement that increased the Known Received Count for | ||||
| the dynamic table (see Section 2.1.4). The Increment field is | ||||
| encoded as a 6-bit prefix integer. The encoder uses this value to | ||||
| determine which table entries might cause a stream to become blocked, | ||||
| as described in Section 2.2.2. | ||||
| 4.5. Header Block Instructions | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 0 | Increment (6+) | | ||||
| +---+---+-----------------------+ | ||||
| HTTP/3 endpoints convert header lists to headers blocks and exchange | Figure 6: Insert Count Increment | |||
| them inside HEADERS and PUSH_PROMISE frames. A decoder interprets | ||||
| header block instructions in order to construct a header list. These | ||||
| instructions reference the static table, or dynamic table in a | ||||
| particular state without modifying it. | ||||
| This section specifies the following header block instructions. | An encoder that receives an Increment field equal to zero or one that | |||
| increases the Known Received Count beyond what the encoder has sent | ||||
| MUST treat this as a connection error of type | ||||
| "HTTP_QPACK_DECODER_STREAM_ERROR". | ||||
| 4.5. Header Block Representations | ||||
| Header blocks contain compressed representations of header lists and | ||||
| are carried in frames on streams defined by the enclosing protocol. | ||||
| These representations reference the static table, or dynamic table in | ||||
| a particular state without modifying it. | ||||
| 4.5.1. Header Block Prefix | 4.5.1. Header Block Prefix | |||
| Each header block is prefixed with two integers. The Required Insert | Each header block is prefixed with two integers. The Required Insert | |||
| Count is encoded as an integer with an 8-bit prefix after the | Count is encoded as an integer with an 8-bit prefix after the | |||
| encoding described in Section 4.5.1.1). The Base is encoded as sign- | encoding described in Section 4.5.1.1). The Base is encoded as sign- | |||
| and-modulus integer, using a single sign bit and a value with a 7-bit | and-modulus integer, using a single sign bit and a value with a 7-bit | |||
| prefix (see Section 4.5.1.2). | prefix (see Section 4.5.1.2). | |||
| These two values are followed by instructions for compressed headers. | These two values are followed by representations for compressed | |||
| The entire block is expected to be framed by the using protocol. | headers. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | Required Insert Count (8+) | | | Required Insert Count (8+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | S | Delta Base (7+) | | | S | Delta Base (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Compressed Headers ... | | Compressed Headers ... | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Figure 7: Frame Payload | Figure 7: Header Block | |||
| 4.5.1.1. Required Insert Count | 4.5.1.1. Required Insert Count | |||
| Required Insert Count identifies the state of the dynamic table | Required Insert Count identifies the state of the dynamic table | |||
| needed to process the header block. Blocking decoders use the | needed to process the header block. Blocking decoders use the | |||
| Required Insert Count to determine when it is safe to process the | Required Insert Count to determine when it is safe to process the | |||
| rest of the block. | rest of the block. | |||
| The encoder transforms the Required Insert Count as follows before | The encoder transforms the Required Insert Count as follows before | |||
| encoding: | encoding: | |||
| skipping to change at page 21, line 8 ¶ | skipping to change at page 20, line 46 ¶ | |||
| "MaxTableCapacity" is the maximum capacity of the dynamic table as | "MaxTableCapacity" is the maximum capacity of the dynamic table as | |||
| specified by the decoder (see Section 3.2.3). | specified by the decoder (see Section 3.2.3). | |||
| This encoding limits the length of the prefix on long-lived | This encoding limits the length of the prefix on long-lived | |||
| connections. | connections. | |||
| The decoder can reconstruct the Required Insert Count using an | The decoder can reconstruct the Required Insert Count using an | |||
| algorithm such as the following. If the decoder encounters a value | algorithm such as the following. If the decoder encounters a value | |||
| of EncodedInsertCount that could not have been produced by a | of EncodedInsertCount that could not have been produced by a | |||
| conformant encoder, it MUST treat this as a stream error of type | conformant encoder, it MUST treat this as a connection error of type | |||
| "HTTP_QPACK_DECOMPRESSION_FAILED". | "HTTP_QPACK_DECOMPRESSION_FAILED". | |||
| TotalNumberOfInserts is the total number of inserts into the | TotalNumberOfInserts is the total number of inserts into the | |||
| decoder's dynamic table. | decoder's dynamic table. | |||
| FullRange = 2 * MaxEntries | FullRange = 2 * MaxEntries | |||
| if EncodedInsertCount == 0: | if EncodedInsertCount == 0: | |||
| ReqInsertCount = 0 | ReqInsertCount = 0 | |||
| else: | else: | |||
| if EncodedInsertCount > FullRange: | if EncodedInsertCount > FullRange: | |||
| skipping to change at page 22, line 27 ¶ | skipping to change at page 22, line 15 ¶ | |||
| positive and the sign bit is set to 0. | positive and the sign bit is set to 0. | |||
| An encoder that produces table updates before encoding a header block | An encoder that produces table updates before encoding a header block | |||
| might set Required Insert Count and the Base to the same value. In | might set Required Insert Count and the Base to the same value. In | |||
| such case, both the sign bit and the Delta Base will be set to zero. | such case, both the sign bit and the Delta Base will be set to zero. | |||
| A header block that does not reference the dynamic table can use any | A header block that does not reference the dynamic table can use any | |||
| value for the Base; setting Delta Base to zero is the most efficient | value for the Base; setting Delta Base to zero is the most efficient | |||
| encoding. | encoding. | |||
| For example, with an Required Insert Count of 9, a decoder receives a | For example, with a Required Insert Count of 9, a decoder receives a | |||
| S bit of 1 and a Delta Base of 2. This sets the Base to 6 and | S bit of 1 and a Delta Base of 2. This sets the Base to 6 and | |||
| enables post-base indexing for three entries. In this example, a | enables post-base indexing for three entries. In this example, a | |||
| regular index of 1 refers to the 5th entry that was added to the | regular index of 1 refers to the 5th entry that was added to the | |||
| table; a post-base index of 1 refers to the 8th entry. | table; a post-base index of 1 refers to the 8th entry. | |||
| 4.5.2. Indexed Header Field | 4.5.2. Indexed Header Field | |||
| An indexed header field representation identifies an entry in either | An indexed header field representation identifies an entry in either | |||
| the static table or the dynamic table and causes that header field to | the static table or the dynamic table and causes that header field to | |||
| be added to the decoded header list, as described in Section 3.2 of | be added to the decoded header list, as described in Section 3.2 of | |||
| skipping to change at page 22, line 50 ¶ | skipping to change at page 22, line 38 ¶ | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | S | Index (6+) | | | 1 | S | Index (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| Indexed Header Field | Indexed Header Field | |||
| If the entry is in the static table, or in the dynamic table with an | If the entry is in the static table, or in the dynamic table with an | |||
| absolute index less than the Base, this representation starts with | absolute index less than the Base, this representation starts with | |||
| the '1' 1-bit pattern, followed by the "S" bit indicating whether the | the '1' 1-bit pattern, followed by the "S" bit indicating whether the | |||
| reference is into the static (S=1) or dynamic (S=0) table. Finally, | reference is into the static or dynamic table. The 6-bit prefix | |||
| the relative index of the matching header field is represented as an | integer (see Section 5.1 of [RFC7541]) that follows is used to locate | |||
| integer with a 6-bit prefix (see Section 5.1 of [RFC7541]). | the table entry for the header name. When S=1, the number represents | |||
| the static table index; when S=0, the number is the relative index of | ||||
| the entry in the dynamic table. | ||||
| 4.5.3. Indexed Header Field With Post-Base Index | 4.5.3. Indexed Header Field With Post-Base Index | |||
| If the entry is in the dynamic table with an absolute index greater | If the entry is in the dynamic table with an absolute index greater | |||
| than or equal to the Base, the representation starts with the '0001' | than or equal to the Base, the representation starts with the '0001' | |||
| 4-bit pattern, followed by the post-base index (see Section 3.2.6) of | 4-bit pattern, followed by the post-base index (see Section 3.2.6) of | |||
| the matching header field, represented as an integer with a 4-bit | the matching header field, represented as an integer with a 4-bit | |||
| prefix (see Section 5.1 of [RFC7541]). | prefix (see Section 5.1 of [RFC7541]). | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| skipping to change at page 23, line 28 ¶ | skipping to change at page 23, line 20 ¶ | |||
| Indexed Header Field with Post-Base Index | Indexed Header Field with Post-Base Index | |||
| 4.5.4. Literal Header Field With Name Reference | 4.5.4. Literal Header Field With Name Reference | |||
| A literal header field with a name reference represents a header | A literal header field with a name reference represents a header | |||
| where the header field name matches the header field name of an entry | where the header field name matches the header field name of an entry | |||
| stored in the static table or the dynamic table. | stored in the static table or the dynamic table. | |||
| If the entry is in the static table, or in the dynamic table with an | If the entry is in the static table, or in the dynamic table with an | |||
| absolute index less than the Base, this representation starts with | absolute index less than the Base, this representation starts with | |||
| the '01' two-bit pattern. If the entry is in the dynamic table with | the '01' two-bit pattern. | |||
| an absolute index greater than or equal to the Base, the | ||||
| representation starts with the '0000' four-bit pattern. | ||||
| Only the header field name stored in the static or dynamic table is | Only the header field name stored in the static or dynamic table is | |||
| used. Any header field value MUST be ignored. | used. Any header field value MUST be ignored. | |||
| The following bit, 'N', indicates whether an intermediary is | The following bit, 'N', indicates whether an intermediary is | |||
| permitted to add this header to the dynamic header table on | permitted to add this header to the dynamic header table on | |||
| subsequent hops. When the 'N' bit is set, the encoded header MUST | subsequent hops. When the 'N' bit is set, the encoded header MUST | |||
| always be encoded with a literal representation. In particular, when | always be encoded with a literal representation. In particular, when | |||
| a peer sends a header field that it received represented as a literal | a peer sends a header field that it received represented as a literal | |||
| header field with the 'N' bit set, it MUST use a literal | header field with the 'N' bit set, it MUST use a literal | |||
| skipping to change at page 24, line 16 ¶ | skipping to change at page 23, line 46 ¶ | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | N | S |Name Index (4+)| | | 0 | 1 | N | S |Name Index (4+)| | |||
| +---+---+---+---+---------------+ | +---+---+---+---+---------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length bytes) | | | Value String (Length bytes) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Literal Header Field With Name Reference | Literal Header Field With Name Reference | |||
| For entries in the static table or in the dynamic table with an | The fourth ("S") bit indicates whether the reference is to the static | |||
| absolute index less than the Base, the header field name is | or dynamic table. The 4-bit prefix integer (see Section 5.1 of | |||
| represented using the relative index of that entry, which is | [RFC7541]) that follows is used to locate the table entry for the | |||
| represented as an integer with a 4-bit prefix (see Section 5.1 of | header name. When S=1, the number represents the static table index; | |||
| [RFC7541]). The "S" bit indicates whether the reference is to the | when S=0, the number is the relative index of the entry in the | |||
| static (S=1) or dynamic (S=0) table. | dynamic table. | |||
| 4.5.5. Literal Header Field With Post-Base Name Reference | 4.5.5. Literal Header Field With Post-Base Name Reference | |||
| For entries in the dynamic table with an absolute index greater than | If the name entry is in the dynamic table with an absolute index | |||
| or equal to the Base, the header field name is represented using the | greater than or equal to the Base, the representation starts with the | |||
| post-base index of that entry (see Section 3.2.6) encoded as an | '0000' four-bit pattern. The fifth bit is the 'N' bit as described | |||
| integer with a 3-bit prefix. | in Section 4.5.4. Finally, the header field name is represented | |||
| using the post-base index of that entry (see Section 3.2.6) encoded | ||||
| as an integer with a 3-bit prefix. | ||||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 0 | 0 | 0 | N |NameIdx(3+)| | | 0 | 0 | 0 | 0 | N |NameIdx(3+)| | |||
| +---+---+---+---+---+-----------+ | +---+---+---+---+---+-----------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length bytes) | | | Value String (Length bytes) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| skipping to change at page 25, line 29 ¶ | skipping to change at page 25, line 23 ¶ | |||
| | Value String (Length bytes) | | | Value String (Length bytes) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Literal Header Field Without Name Reference | Literal Header Field Without Name Reference | |||
| 5. Configuration | 5. Configuration | |||
| QPACK defines two settings which are included in the HTTP/3 SETTINGS | QPACK defines two settings which are included in the HTTP/3 SETTINGS | |||
| frame. | frame. | |||
| SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x1): An integer with a maximum | SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x1): The default value is zero. | |||
| value of 2^30 - 1. The default value is zero bytes. See | See Section 3.2 for usage. This is the equivalent of the | |||
| Section 3.2 for usage. This is the equivalent of the | ||||
| SETTINGS_HEADER_TABLE_SIZE from HTTP/2. | SETTINGS_HEADER_TABLE_SIZE from HTTP/2. | |||
| SETTINGS_QPACK_BLOCKED_STREAMS (0x7): An integer with a maximum | SETTINGS_QPACK_BLOCKED_STREAMS (0x7): The default value is zero. | |||
| value of 2^16 - 1. The default value is zero. See Section 2.1.3. | See Section 2.1.3. | |||
| 6. Error Handling | 6. Error Handling | |||
| The following error codes are defined for HTTP/3 to indicate failures | The following error codes are defined for HTTP/3 to indicate failures | |||
| of QPACK which prevent the stream or connection from continuing: | of QPACK which prevent the connection from continuing: | |||
| HTTP_QPACK_DECOMPRESSION_FAILED (0x200): The decoder failed to | HTTP_QPACK_DECOMPRESSION_FAILED (0x200): The decoder failed to | |||
| interpret a header block instruction and is not able to continue | interpret a header block and is not able to continue decoding that | |||
| decoding that header block. | header block. | |||
| HTTP_QPACK_ENCODER_STREAM_ERROR (0x201): The decoder failed to | HTTP_QPACK_ENCODER_STREAM_ERROR (0x201): The decoder failed to | |||
| interpret an encoder instruction received on the encoder stream. | interpret an encoder instruction received on the encoder stream. | |||
| HTTP_QPACK_DECODER_STREAM_ERROR (0x202): The encoder failed to | HTTP_QPACK_DECODER_STREAM_ERROR (0x202): The encoder failed to | |||
| interpret a decoder instruction received on the decoder stream. | interpret a decoder instruction received on the decoder stream. | |||
| Upon encountering an error, an implementation MAY elect to treat it | ||||
| as a connection error even if this document prescribes that it MUST | ||||
| be treated as a stream error. | ||||
| 7. Security Considerations | 7. Security Considerations | |||
| TBD. | TBD. | |||
| 8. IANA Considerations | 8. IANA Considerations | |||
| 8.1. Settings Registration | 8.1. Settings Registration | |||
| This document specifies two settings. The entries in the following | This document specifies two settings. The entries in the following | |||
| table are registered in the "HTTP/3 Settings" registry established in | table are registered in the "HTTP/3 Settings" registry established in | |||
| skipping to change at page 26, line 38 ¶ | skipping to change at page 26, line 30 ¶ | |||
| 8.2. Stream Type Registration | 8.2. Stream Type Registration | |||
| This document specifies two stream types. The entries in the | This document specifies two stream types. The entries in the | |||
| following table are registered in the "HTTP/3 Stream Type" registry | following table are registered in the "HTTP/3 Stream Type" registry | |||
| established in [HTTP3]. | established in [HTTP3]. | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| | Stream Type | Code | Specification | Sender | | | Stream Type | Code | Specification | Sender | | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| | QPACK Encoder Stream | 0x02 | Section 4.2.1 | Both | | | QPACK Encoder Stream | 0x02 | Section 4.2 | Both | | |||
| | | | | | | | | | | | | |||
| | QPACK Decoder Stream | 0x03 | Section 4.2.1 | Both | | | QPACK Decoder Stream | 0x03 | Section 4.2 | Both | | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| 8.3. Error Code Registration | 8.3. Error Code Registration | |||
| This document specifies three error codes. The entries in the | This document specifies three error codes. The entries in the | |||
| following table are registered in the "HTTP/3 Error Code" registry | following table are registered in the "HTTP/3 Error Code" registry | |||
| established in [HTTP3]. | established in [HTTP3]. | |||
| +-----------------------------+-------+--------------+--------------+ | +-----------------------------+-------+--------------+--------------+ | |||
| | Name | Code | Description | Specificatio | | | Name | Code | Description | Specificatio | | |||
| skipping to change at page 27, line 28 ¶ | skipping to change at page 27, line 28 ¶ | |||
| | HTTP_QPACK_DECODER_STREAM_E | 0x202 | Error on the | Section 6 | | | HTTP_QPACK_DECODER_STREAM_E | 0x202 | Error on the | Section 6 | | |||
| | RROR | | decoder | | | | RROR | | decoder | | | |||
| | | | stream | | | | | | stream | | | |||
| +-----------------------------+-------+--------------+--------------+ | +-----------------------------+-------+--------------+--------------+ | |||
| 9. References | 9. References | |||
| 9.1. Normative References | 9.1. Normative References | |||
| [HTTP3] Bishop, M., Ed., "Hypertext Transfer Protocol Version 3 | [HTTP3] Bishop, M., Ed., "Hypertext Transfer Protocol Version 3 | |||
| (HTTP/3)", draft-ietf-quic-http-20 (work in progress), | (HTTP/3)", draft-ietf-quic-http-21 (work in progress), | |||
| April 2019. | July 2019. | |||
| [QUIC-TRANSPORT] | [QUIC-TRANSPORT] | |||
| Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based | Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based | |||
| Multiplexed and Secure Transport", draft-ietf-quic- | Multiplexed and Secure Transport", draft-ietf-quic- | |||
| transport-18 (work in progress), April 2019. | transport-20 (work in progress), July 2019. | |||
| [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, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | |||
| HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | |||
| <https://www.rfc-editor.org/info/rfc7541>. | <https://www.rfc-editor.org/info/rfc7541>. | |||
| skipping to change at page 35, line 10 ¶ | skipping to change at page 35, line 10 ¶ | |||
| encodeInteger(prefixBuffer, 0x80, | encodeInteger(prefixBuffer, 0x80, | |||
| largestReference - baseIndex, 7) | largestReference - baseIndex, 7) | |||
| return controlBuffer, prefixBuffer + streamBuffer | return controlBuffer, prefixBuffer + streamBuffer | |||
| Appendix C. Change Log | Appendix C. Change Log | |||
| *RFC Editor's Note:* Please remove this section prior to | *RFC Editor's Note:* Please remove this section prior to | |||
| publication of a final version of this document. | publication of a final version of this document. | |||
| C.1. Since draft-ietf-quic-qpack-06 | C.1. Since draft-ietf-quic-qpack-08 | |||
| o Endpoints are permitted to create encoder and decoder streams even | ||||
| if they can't use them (#2100, #2529) | ||||
| o Maximum values for settings removed (#2766, #2767) | ||||
| C.2. Since draft-ietf-quic-qpack-06 | ||||
| o Clarify initial dynamic table capacity maximums (#2276, #2330, | o Clarify initial dynamic table capacity maximums (#2276, #2330, | |||
| #2330) | #2330) | |||
| C.2. Since draft-ietf-quic-qpack-05 | C.3. Since draft-ietf-quic-qpack-05 | |||
| o Introduced the terms dynamic table capacity and maximum dynamic | o Introduced the terms dynamic table capacity and maximum dynamic | |||
| table capacity. | table capacity. | |||
| o Renamed SETTINGS_HEADER_TABLE_SIZE to | o Renamed SETTINGS_HEADER_TABLE_SIZE to | |||
| SETTINGS_QPACK_MAX_TABLE_CAPACITY. | SETTINGS_QPACK_MAX_TABLE_CAPACITY. | |||
| C.3. Since draft-ietf-quic-qpack-04 | C.4. Since draft-ietf-quic-qpack-04 | |||
| o Changed calculation of Delta Base Index to avoid an illegal value | o Changed calculation of Delta Base Index to avoid an illegal value | |||
| (#2002, #2005) | (#2002, #2005) | |||
| C.4. Since draft-ietf-quic-qpack-03 | C.5. Since draft-ietf-quic-qpack-03 | |||
| o Change HTTP settings defaults (#2038) | o Change HTTP settings defaults (#2038) | |||
| o Substantial editorial reorganization | o Substantial editorial reorganization | |||
| C.5. Since draft-ietf-quic-qpack-02 | C.6. Since draft-ietf-quic-qpack-02 | |||
| o Largest Reference encoded modulo MaxEntries (#1763) | o Largest Reference encoded modulo MaxEntries (#1763) | |||
| o New Static Table (#1355) | o New Static Table (#1355) | |||
| o Table Size Update with Insert Count=0 is a connection error | o Table Size Update with Insert Count=0 is a connection error | |||
| (#1762) | (#1762) | |||
| o Stream Cancellations are optional when | o Stream Cancellations are optional when | |||
| SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | |||
| skipping to change at page 36, line 4 ¶ | skipping to change at page 36, line 11 ¶ | |||
| o Stream Cancellations are optional when | o Stream Cancellations are optional when | |||
| SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | |||
| o Implementations must handle 62 bit integers (#1760) | o Implementations must handle 62 bit integers (#1760) | |||
| o Different error types for each QPACK stream, other changes to | o Different error types for each QPACK stream, other changes to | |||
| error handling (#1726) | error handling (#1726) | |||
| o Preserve header field order (#1725) | o Preserve header field order (#1725) | |||
| o Initial table size is the maximum permitted when table is first | o Initial table size is the maximum permitted when table is first | |||
| usable (#1642) | usable (#1642) | |||
| C.6. Since draft-ietf-quic-qpack-01 | C.7. Since draft-ietf-quic-qpack-01 | |||
| o Only header blocks that reference the dynamic table are | o Only header blocks that reference the dynamic table are | |||
| acknowledged (#1603, #1605) | acknowledged (#1603, #1605) | |||
| C.7. Since draft-ietf-quic-qpack-00 | C.8. Since draft-ietf-quic-qpack-00 | |||
| o Renumbered instructions for consistency (#1471, #1472) | o Renumbered instructions for consistency (#1471, #1472) | |||
| o Decoder is allowed to validate largest reference (#1404, #1469) | o Decoder is allowed to validate largest reference (#1404, #1469) | |||
| o Header block acknowledgments also acknowledge the associated | o Header block acknowledgments also acknowledge the associated | |||
| largest reference (#1370, #1400) | largest reference (#1370, #1400) | |||
| o Added an acknowledgment for unread streams (#1371, #1400) | o Added an acknowledgment for unread streams (#1371, #1400) | |||
| o Removed framing from encoder stream (#1361,#1467) | o Removed framing from encoder stream (#1361,#1467) | |||
| o Control streams use typed unidirectional streams rather than fixed | o Control streams use typed unidirectional streams rather than fixed | |||
| stream IDs (#910,#1359) | stream IDs (#910,#1359) | |||
| C.8. Since draft-ietf-quic-qcram-00 | C.9. Since draft-ietf-quic-qcram-00 | |||
| o Separate instruction sets for table updates and header blocks | o Separate instruction sets for table updates and header blocks | |||
| (#1235, #1142, #1141) | (#1235, #1142, #1141) | |||
| o Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125, | o Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125, | |||
| #1314) | #1314) | |||
| o Added mechanisms that support one-pass encoding (#1138, #1320) | o Added mechanisms that support one-pass encoding (#1138, #1320) | |||
| o Added a setting to control the number of blocked decoders (#238, | o Added a setting to control the number of blocked decoders (#238, | |||
| End of changes. 104 change blocks. | ||||
| 383 lines changed or deleted | 371 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||