rfc9204.original | rfc9204.txt | |||
---|---|---|---|---|
QUIC C. Krasic | Internet Engineering Task Force (IETF) C. Krasic | |||
Internet-Draft Netflix | Request for Comments: 9204 | |||
Intended status: Standards Track M. Bishop | Category: Standards Track M. Bishop | |||
Expires: 6 August 2021 Akamai Technologies | ISSN: 2070-1721 Akamai Technologies | |||
A. Frindell, Ed. | A. Frindell, Ed. | |||
2 February 2021 | June 2022 | |||
QPACK: Header Compression for HTTP/3 | QPACK: Field Compression for HTTP/3 | |||
draft-ietf-quic-qpack-21 | ||||
Abstract | Abstract | |||
This specification defines QPACK, a compression format for | This specification defines QPACK: a compression format for | |||
efficiently representing HTTP fields, to be used in HTTP/3. This is | efficiently representing HTTP fields that is to be used in HTTP/3. | |||
a variation of HPACK compression that seeks to reduce head-of-line | This is a variation of HPACK compression that seeks to reduce head- | |||
blocking. | of-line blocking. | |||
Note to Readers | ||||
Discussion of this draft takes place on the QUIC working group | ||||
mailing list (quic@ietf.org (mailto:quic@ietf.org)), which is | ||||
archived at https://mailarchive.ietf.org/arch/ | ||||
search/?email_list=quic. | ||||
Working Group information can be found at https://github.com/quicwg; | ||||
source code and issues list for this draft can be found at | ||||
https://github.com/quicwg/base-drafts/labels/-qpack. | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This is an Internet Standards Track document. | |||
provisions of BCP 78 and BCP 79. | ||||
Internet-Drafts are working documents of the Internet Engineering | ||||
Task Force (IETF). Note that other groups may also distribute | ||||
working documents as Internet-Drafts. The list of current Internet- | ||||
Drafts is at https://datatracker.ietf.org/drafts/current/. | ||||
Internet-Drafts are draft documents valid for a maximum of six months | This document is a product of the Internet Engineering Task Force | |||
and may be updated, replaced, or obsoleted by other documents at any | (IETF). It represents the consensus of the IETF community. It has | |||
time. It is inappropriate to use Internet-Drafts as reference | received public review and has been approved for publication by the | |||
material or to cite them other than as "work in progress." | Internet Engineering Steering Group (IESG). Further information on | |||
Internet Standards is available in Section 2 of RFC 7841. | ||||
This Internet-Draft will expire on 6 August 2021. | Information about the current status of this document, any errata, | |||
and how to provide feedback on it may be obtained at | ||||
https://www.rfc-editor.org/info/rfc9204. | ||||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2021 IETF Trust and the persons identified as the | Copyright (c) 2022 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 (https://trustee.ietf.org/ | Provisions Relating to IETF Documents | |||
license-info) in effect on the date of publication of this document. | (https://trustee.ietf.org/license-info) in effect on the date of | |||
Please review these documents carefully, as they describe your rights | publication of this document. Please review these documents | |||
and restrictions with respect to this document. Code Components | carefully, as they describe your rights and restrictions with respect | |||
extracted from this document must include Simplified BSD License text | to this document. Code Components extracted from this document must | |||
as described in Section 4.e of the Trust Legal Provisions and are | include Revised BSD License text as described in Section 4.e of the | |||
provided without warranty as described in the Simplified BSD License. | Trust Legal Provisions and are provided without warranty as described | |||
in the Revised BSD License. | ||||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction | |||
1.1. Conventions and Definitions . . . . . . . . . . . . . . . 4 | 1.1. Conventions and Definitions | |||
1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 | 1.2. Notational Conventions | |||
2. Compression Process Overview . . . . . . . . . . . . . . . . 6 | 2. Compression Process Overview | |||
2.1. Encoder . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 2.1. Encoder | |||
2.1.1. Limits on Dynamic Table Insertions . . . . . . . . . 6 | 2.1.1. Limits on Dynamic Table Insertions | |||
2.1.2. Blocked Streams . . . . . . . . . . . . . . . . . . . 7 | 2.1.2. Blocked Streams | |||
2.1.3. Avoiding Flow Control Deadlocks . . . . . . . . . . . 8 | 2.1.3. Avoiding Flow-Control Deadlocks | |||
2.1.4. Known Received Count . . . . . . . . . . . . . . . . 9 | 2.1.4. Known Received Count | |||
2.2. Decoder . . . . . . . . . . . . . . . . . . . . . . . . . 9 | 2.2. Decoder | |||
2.2.1. Blocked Decoding . . . . . . . . . . . . . . . . . . 9 | 2.2.1. Blocked Decoding | |||
2.2.2. State Synchronization . . . . . . . . . . . . . . . . 10 | 2.2.2. State Synchronization | |||
2.2.3. Invalid References . . . . . . . . . . . . . . . . . 11 | 2.2.3. Invalid References | |||
3. Reference Tables . . . . . . . . . . . . . . . . . . . . . . 11 | 3. Reference Tables | |||
3.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 11 | 3.1. Static Table | |||
3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 12 | 3.2. Dynamic Table | |||
3.2.1. Dynamic Table Size . . . . . . . . . . . . . . . . . 12 | 3.2.1. Dynamic Table Size | |||
3.2.2. Dynamic Table Capacity and Eviction . . . . . . . . . 12 | 3.2.2. Dynamic Table Capacity and Eviction | |||
3.2.3. Maximum Dynamic Table Capacity . . . . . . . . . . . 13 | 3.2.3. Maximum Dynamic Table Capacity | |||
3.2.4. Absolute Indexing . . . . . . . . . . . . . . . . . . 14 | 3.2.4. Absolute Indexing | |||
3.2.5. Relative Indexing . . . . . . . . . . . . . . . . . . 14 | 3.2.5. Relative Indexing | |||
3.2.6. Post-Base Indexing . . . . . . . . . . . . . . . . . 15 | 3.2.6. Post-Base Indexing | |||
4. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 16 | 4. Wire Format | |||
4.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 16 | 4.1. Primitives | |||
4.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 16 | 4.1.1. Prefixed Integers | |||
4.1.2. String Literals . . . . . . . . . . . . . . . . . . . 16 | 4.1.2. String Literals | |||
4.2. Encoder and Decoder Streams . . . . . . . . . . . . . . . 16 | 4.2. Encoder and Decoder Streams | |||
4.3. Encoder Instructions . . . . . . . . . . . . . . . . . . 17 | 4.3. Encoder Instructions | |||
4.3.1. Set Dynamic Table Capacity . . . . . . . . . . . . . 17 | 4.3.1. Set Dynamic Table Capacity | |||
4.3.2. Insert With Name Reference . . . . . . . . . . . . . 18 | 4.3.2. Insert with Name Reference | |||
4.3.3. Insert With Literal Name . . . . . . . . . . . . . . 18 | 4.3.3. Insert with Literal Name | |||
4.3.4. Duplicate . . . . . . . . . . . . . . . . . . . . . . 19 | 4.3.4. Duplicate | |||
4.4. Decoder Instructions | ||||
4.4. Decoder Instructions . . . . . . . . . . . . . . . . . . 19 | 4.4.1. Section Acknowledgment | |||
4.4.1. Section Acknowledgment . . . . . . . . . . . . . . . 19 | 4.4.2. Stream Cancellation | |||
4.4.2. Stream Cancellation . . . . . . . . . . . . . . . . . 20 | 4.4.3. Insert Count Increment | |||
4.4.3. Insert Count Increment . . . . . . . . . . . . . . . 20 | 4.5. Field Line Representations | |||
4.5. Field Line Representations . . . . . . . . . . . . . . . 21 | 4.5.1. Encoded Field Section Prefix | |||
4.5.1. Encoded Field Section Prefix . . . . . . . . . . . . 21 | 4.5.2. Indexed Field Line | |||
4.5.2. Indexed Field Line . . . . . . . . . . . . . . . . . 24 | 4.5.3. Indexed Field Line with Post-Base Index | |||
4.5.3. Indexed Field Line With Post-Base Index . . . . . . . 25 | 4.5.4. Literal Field Line with Name Reference | |||
4.5.4. Literal Field Line With Name Reference . . . . . . . 25 | 4.5.5. Literal Field Line with Post-Base Name Reference | |||
4.5.5. Literal Field Line With Post-Base Name Reference . . 26 | 4.5.6. Literal Field Line with Literal Name | |||
4.5.6. Literal Field Line With Literal Name . . . . . . . . 26 | 5. Configuration | |||
5. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 27 | 6. Error Handling | |||
6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 27 | 7. Security Considerations | |||
7. Security Considerations . . . . . . . . . . . . . . . . . . . 27 | 7.1. Probing Dynamic Table State | |||
7.1. Probing Dynamic Table State . . . . . . . . . . . . . . . 28 | 7.1.1. Applicability to QPACK and HTTP | |||
7.1.1. Applicability to QPACK and HTTP . . . . . . . . . . . 28 | 7.1.2. Mitigation | |||
7.1.2. Mitigation . . . . . . . . . . . . . . . . . . . . . 29 | 7.1.3. Never-Indexed Literals | |||
7.1.3. Never-Indexed Literals . . . . . . . . . . . . . . . 30 | 7.2. Static Huffman Encoding | |||
7.2. Static Huffman Encoding . . . . . . . . . . . . . . . . . 31 | 7.3. Memory Consumption | |||
7.3. Memory Consumption . . . . . . . . . . . . . . . . . . . 31 | 7.4. Implementation Limits | |||
7.4. Implementation Limits . . . . . . . . . . . . . . . . . . 32 | 8. IANA Considerations | |||
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33 | 8.1. Settings Registration | |||
8.1. Settings Registration . . . . . . . . . . . . . . . . . . 33 | 8.2. Stream Type Registration | |||
8.2. Stream Type Registration . . . . . . . . . . . . . . . . 33 | 8.3. Error Code Registration | |||
8.3. Error Code Registration . . . . . . . . . . . . . . . . . 34 | 9. References | |||
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 34 | 9.1. Normative References | |||
9.1. Normative References . . . . . . . . . . . . . . . . . . 34 | 9.2. Informative References | |||
9.2. Informative References . . . . . . . . . . . . . . . . . 35 | Appendix A. Static Table | |||
Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 36 | Appendix B. Encoding and Decoding Examples | |||
Appendix B. Encoding and Decoding Examples . . . . . . . . . . . 40 | B.1. Literal Field Line with Name Reference | |||
B.1. Literal Field Line With Name Reference . . . . . . . . . 41 | B.2. Dynamic Table | |||
B.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 41 | B.3. Speculative Insert | |||
B.3. Speculative Insert . . . . . . . . . . . . . . . . . . . 42 | B.4. Duplicate Instruction, Stream Cancellation | |||
B.4. Duplicate Instruction, Stream Cancellation . . . . . . . 43 | B.5. Dynamic Table Insert, Eviction | |||
B.5. Dynamic Table Insert, Eviction . . . . . . . . . . . . . 44 | Appendix C. Sample Single-Pass Encoding Algorithm | |||
Appendix C. Sample One Pass Encoding Algorithm . . . . . . . . . 45 | Acknowledgments | |||
Appendix D. Change Log . . . . . . . . . . . . . . . . . . . . . 47 | Authors' Addresses | |||
D.1. Since draft-ietf-quic-qpack-19 . . . . . . . . . . . . . 47 | ||||
D.2. Since draft-ietf-quic-qpack-18 . . . . . . . . . . . . . 47 | ||||
D.3. Since draft-ietf-quic-qpack-17 . . . . . . . . . . . . . 47 | ||||
D.4. Since draft-ietf-quic-qpack-16 . . . . . . . . . . . . . 47 | ||||
D.5. Since draft-ietf-quic-qpack-15 . . . . . . . . . . . . . 47 | ||||
D.6. Since draft-ietf-quic-qpack-14 . . . . . . . . . . . . . 47 | ||||
D.7. Since draft-ietf-quic-qpack-13 . . . . . . . . . . . . . 47 | ||||
D.8. Since draft-ietf-quic-qpack-12 . . . . . . . . . . . . . 47 | ||||
D.9. Since draft-ietf-quic-qpack-11 . . . . . . . . . . . . . 47 | ||||
D.10. Since draft-ietf-quic-qpack-10 . . . . . . . . . . . . . 48 | ||||
D.11. Since draft-ietf-quic-qpack-09 . . . . . . . . . . . . . 48 | ||||
D.12. Since draft-ietf-quic-qpack-08 . . . . . . . . . . . . . 48 | ||||
D.13. Since draft-ietf-quic-qpack-06 . . . . . . . . . . . . . 48 | ||||
D.14. Since draft-ietf-quic-qpack-05 . . . . . . . . . . . . . 48 | ||||
D.15. Since draft-ietf-quic-qpack-04 . . . . . . . . . . . . . 48 | ||||
D.16. Since draft-ietf-quic-qpack-03 . . . . . . . . . . . . . 48 | ||||
D.17. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 48 | ||||
D.18. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 49 | ||||
D.19. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 49 | ||||
D.20. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 49 | ||||
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 50 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 50 | ||||
1. Introduction | 1. Introduction | |||
The QUIC transport protocol ([QUIC-TRANSPORT]) is designed 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 ([RFC7540]). HTTP/2 uses HPACK ([RFC7541]) for compression of | HTTP/2 ([HTTP/2]). HTTP/2 uses HPACK ([RFC7541]) for compression of | |||
the header and trailer sections. If HPACK were used for HTTP/3 | the header and trailer sections. If HPACK were used for HTTP/3 | |||
([HTTP3]), it would induce head-of-line blocking for field sections | ([HTTP/3]), it would induce head-of-line blocking for field sections | |||
due to built-in assumptions of a total ordering across frames on all | due to built-in assumptions of a total ordering across frames on all | |||
streams. | streams. | |||
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 | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in | "OPTIONAL" in this document are to be interpreted as described in | |||
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
Definitions of terms that are used in this document: | The following terms are used in this document: | |||
HTTP fields: Metadata sent as part of an HTTP message. The term | HTTP fields: Metadata sent as part of an HTTP message. The term | |||
encompasses both header and trailer fields. Colloquially, the | encompasses both header and trailer fields. Colloquially, the | |||
term "headers" has often been used to refer to HTTP header fields | term "headers" has often been used to refer to HTTP header fields | |||
and trailer fields; this document uses "fields" for generality. | and trailer fields; this document uses "fields" for generality. | |||
HTTP field line: A name-value pair sent as part of an HTTP field | HTTP field line: A name-value pair sent as part of an HTTP field | |||
section. See Sections 6.3 and 6.5 of [SEMANTICS]. | section. See Sections 6.3 and 6.5 of [HTTP]. | |||
HTTP field value: Data associated with a field name, composed from | HTTP field value: Data associated with a field name, composed from | |||
all field line values with that field name in that section, | all field line values with that field name in that section, | |||
concatenated together with comma separators. | concatenated together with comma separators. | |||
Field section: An ordered collection of HTTP field lines associated | Field section: An ordered collection of HTTP field lines associated | |||
with an HTTP message. A field section can contain multiple field | with an HTTP message. A field section can contain multiple field | |||
lines with the same name. It can also contain duplicate field | lines with the same name. It can also contain duplicate field | |||
lines. An HTTP message can include both header and trailer | lines. An HTTP message can include both header and trailer | |||
sections. | sections. | |||
Representation: An instruction that represents a field line, | Representation: An instruction that represents a field line, | |||
possibly by reference to the dynamic and static tables. | possibly by reference to the dynamic and static tables. | |||
Encoder: An implementation that encodes field sections. | Encoder: An implementation that encodes field sections. | |||
Decoder: An implementation that decodes encoded field sections. | Decoder: An implementation that decodes encoded field sections. | |||
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 and post-base indices. | Base: A reference point for relative and post-Base indices. | |||
Representations that reference dynamic table entries are relative | Representations that reference dynamic table entries are relative | |||
to a Base. | to a Base. | |||
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. | Note that QPACK is a name, not an abbreviation. | |||
1.2. Notational Conventions | 1.2. Notational Conventions | |||
Diagrams use the format described in Section 3.1 of [RFC2360], with | Diagrams in this document use the format described in Section 3.1 of | |||
the following additional conventions: | [RFC2360], with 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 4.1.1, beginning with an A-bit prefix. | in Section 4.1.1, 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 field lines | Like HPACK, QPACK uses two tables for associating field lines | |||
("headers") to indices. The static table (Section 3.1) is predefined | ("headers") to indices. The static table (Section 3.1) is predefined | |||
and contains common header field lines (some of them with an empty | and contains common header field lines (some of them with an empty | |||
value). The dynamic table (Section 3.2) is built up over the course | value). The dynamic table (Section 3.2) is built up over the course | |||
of the connection and can be used by the encoder to index both header | of the connection and can be used by the encoder to index both header | |||
and trailer field lines in the encoded field sections. | and trailer field lines in the encoded field sections. | |||
skipping to change at page 6, line 37 ¶ | skipping to change at line 230 ¶ | |||
blocking if the encoder has not received an acknowledgment indicating | blocking if the encoder has not received an acknowledgment indicating | |||
the entry is available at the decoder. | 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 field lines it is compressing. | is not limited to field lines it is compressing. | |||
QPACK preserves the ordering of field lines within each field | QPACK preserves the ordering of field lines within each field | |||
section. An encoder MUST emit field representations in the order | section. An encoder MUST emit field representations in the order | |||
they appear in the input field section. | they appear in the input field section. | |||
QPACK is designed to contain the more complex state tracking to the | QPACK is designed to place the burden of optional state tracking on | |||
encoder, while the decoder is relatively simple. | the encoder, resulting in relatively simple decoders. | |||
2.1.1. Limits on Dynamic Table Insertions | 2.1.1. Limits on Dynamic Table Insertions | |||
Inserting entries into the dynamic table might not be possible if the | Inserting entries into the dynamic table might not be possible if the | |||
table contains entries that cannot be evicted. | table contains entries that cannot be evicted. | |||
A dynamic table entry cannot be evicted immediately after insertion, | A dynamic table entry cannot be evicted immediately after insertion, | |||
even if it has never been referenced. Once the insertion of a | even if it has never been referenced. Once the insertion of a | |||
dynamic table entry has been acknowledged and there are no | dynamic table entry has been acknowledged and there are no | |||
outstanding references to the entry in unacknowledged | outstanding references to the entry in unacknowledged | |||
skipping to change at page 7, line 19 ¶ | skipping to change at line 261 ¶ | |||
to avoid this, an encoder that uses the dynamic table has to keep | to avoid this, an encoder that uses the dynamic table has to keep | |||
track of each dynamic table entry referenced by each field section | track of each dynamic table entry referenced by each field section | |||
until those representations are acknowledged by the decoder; see | until those representations are acknowledged by the decoder; see | |||
Section 4.4.1. | Section 4.4.1. | |||
2.1.1.1. Avoiding Prohibited Insertions | 2.1.1.1. Avoiding Prohibited 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 (Section 4.3.4), and reference the duplicate instead. | instruction (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 (Section 3.2.4) in the dynamic table that it | smallest absolute index (Section 3.2.4) in the dynamic table that it | |||
will emit a reference for. As new entries are inserted, the encoder | will emit a reference for. As new entries are inserted, the encoder | |||
increases the draining index to maintain the section of the table | increases the draining index to maintain the section of the table | |||
that it will not reference. If the encoder does not create new | that it will not reference. If the encoder does not create new | |||
references to entries with an absolute index lower than the draining | references to entries with an absolute index lower than the draining | |||
index, the number of unacknowledged references to those entries will | index, the number of unacknowledged references to those entries will | |||
eventually become zero, allowing them to be evicted. | eventually become zero, allowing them to be evicted. | |||
<-- Newer Entries Older Entries --> | <-- Newer Entries Older Entries --> | |||
(Larger Indicies) (Smaller Indicies) | (Larger Indices) (Smaller Indices) | |||
+--------+---------------------------------+----------+ | +--------+---------------------------------+----------+ | |||
| Unused | Referenceable | Draining | | | Unused | Referenceable | Draining | | |||
| Space | Entries | Entries | | | Space | Entries | Entries | | |||
+--------+---------------------------------+----------+ | +--------+---------------------------------+----------+ | |||
^ ^ ^ | ^ ^ ^ | |||
| | | | | | | | |||
Insertion Point Draining Index Dropping | Insertion Point Draining Index Dropping | |||
Point | Point | |||
Figure 1: Draining Dynamic Table Entries | Figure 1: Draining Dynamic Table Entries | |||
skipping to change at page 8, line 15 ¶ | skipping to change at line 305 ¶ | |||
Each encoded field section contains a Required Insert Count | Each encoded field section contains a Required Insert Count | |||
(Section 4.5.1), the lowest possible value for the Insert Count with | (Section 4.5.1), the lowest possible value for the Insert Count with | |||
which the field section can be decoded. For a field section encoded | which the field section can be decoded. For a field section encoded | |||
using references to the dynamic table, the Required Insert Count is | using references to the dynamic table, the Required Insert Count is | |||
one larger than the largest absolute index of all referenced dynamic | one larger than the largest absolute index of all referenced dynamic | |||
table entries. For a field section encoded with no references to the | table entries. For a field section encoded with no references to the | |||
dynamic table, the Required Insert Count is zero. | dynamic table, the Required Insert Count is zero. | |||
When the decoder receives an encoded field section with a Required | When the decoder receives an encoded field section with a Required | |||
Insert Count greater than its own Insert Count, the stream cannot be | Insert Count greater than its own Insert Count, the stream cannot be | |||
processed immediately, and is considered "blocked"; see | processed immediately and is considered "blocked"; see Section 2.2.1. | |||
Section 2.2.1. | ||||
The decoder specifies an upper bound on the number of streams that | The decoder specifies an upper bound on the number of streams that | |||
can be blocked using the SETTINGS_QPACK_BLOCKED_STREAMS setting; see | can be blocked using the SETTINGS_QPACK_BLOCKED_STREAMS setting; see | |||
Section 5. An encoder MUST limit the number of streams that could | Section 5. An encoder MUST limit the number of streams that could | |||
become blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all | become blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all | |||
times. If a decoder encounters more blocked streams than it promised | times. If a decoder encounters more blocked streams than it promised | |||
to support, it MUST treat this as a connection error of type | to support, it MUST treat this as a connection error of type | |||
QPACK_DECOMPRESSION_FAILED. | QPACK_DECOMPRESSION_FAILED. | |||
Note that the decoder might not become blocked on every stream that | Note that the decoder might not become blocked on every stream that | |||
risks becoming blocked. | risks becoming blocked. | |||
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 | |||
can avoid the risk of blocking by only referencing dynamic table | can avoid the risk of blocking by only referencing dynamic table | |||
entries that have been acknowledged, but this could mean using | entries that have been acknowledged, but this could mean using | |||
literals. Since literals make the encoded field section larger, this | literals. Since literals make the encoded field section larger, this | |||
can result in the encoder becoming blocked on congestion or flow | can result in the encoder becoming blocked on congestion or flow- | |||
control limits. | control limits. | |||
2.1.3. Avoiding Flow Control Deadlocks | 2.1.3. Avoiding Flow-Control Deadlocks | |||
Writing instructions on streams that are limited by flow control can | Writing instructions on streams that are limited by flow control can | |||
produce deadlocks. | produce deadlocks. | |||
A decoder might stop issuing flow control credit on the stream that | A decoder might stop issuing flow-control credit on the stream that | |||
carries an encoded field section until the necessary updates are | carries an encoded field section until the necessary updates are | |||
received on the encoder stream. If the granting of flow control | received on the encoder stream. If the granting of flow-control | |||
credit on the encoder stream (or the connection as a whole) depends | credit on the encoder stream (or the connection as a whole) depends | |||
on the consumption and release of data on the stream carrying the | on the consumption and release of data on the stream carrying the | |||
encoded field section, a deadlock might result. | encoded field section, a deadlock might result. | |||
More generally, a stream containing a large instruction can become | More generally, a stream containing a large instruction can become | |||
deadlocked if the decoder withholds flow control credit until the | deadlocked if the decoder withholds flow-control credit until the | |||
instruction is completely received. | instruction is completely received. | |||
To avoid these deadlocks, an encoder SHOULD NOT write an instruction | To avoid these deadlocks, an encoder SHOULD NOT write an instruction | |||
unless sufficient stream and connection flow control credit is | unless sufficient stream and connection flow-control credit is | |||
available for the entire instruction. | available for the entire instruction. | |||
2.1.4. Known Received Count | 2.1.4. Known Received Count | |||
The Known Received Count is the total number of dynamic table | The Known Received Count is the total number of dynamic table | |||
insertions and duplications acknowledged by the decoder. The encoder | insertions and duplications acknowledged by the decoder. The encoder | |||
tracks the Known Received Count in order to identify which dynamic | tracks the Known Received Count in order to identify which dynamic | |||
table entries can be referenced without potentially blocking a | table entries can be referenced without potentially blocking a | |||
stream. The decoder tracks the Known Received Count in order to be | stream. The decoder tracks the Known Received Count in order to be | |||
able to send Insert Count Increment instructions. | able to send Insert Count Increment instructions. | |||
A Section Acknowledgment instruction (Section 4.4.1) implies that the | A Section Acknowledgment instruction (Section 4.4.1) implies that the | |||
decoder has received all dynamic table state necessary to decode the | decoder has received all dynamic table state necessary to decode the | |||
field section. If the Required Insert Count of the acknowledged | field section. If the Required Insert Count of the acknowledged | |||
field section is greater than the current Known Received Count, Known | field section is greater than the current Known Received Count, the | |||
Received Count is updated to that Required Insert Count value. | Known Received Count is updated to that Required Insert Count value. | |||
An Insert Count Increment instruction (Section 4.4.3) increases the | An Insert Count Increment instruction (Section 4.4.3) increases the | |||
Known Received Count by its Increment parameter. See Section 2.2.2.3 | Known Received Count by its Increment parameter. See Section 2.2.2.3 | |||
for guidance. | for guidance. | |||
2.2. Decoder | 2.2. Decoder | |||
As in HPACK, the decoder processes a series of representations and | As in HPACK, the decoder processes a series of representations and | |||
emits the corresponding field sections. It also processes | emits the corresponding field sections. It also processes | |||
instructions received on the encoder stream that modify the dynamic | instructions received on the encoder stream that modify the dynamic | |||
skipping to change at page 10, line 6 ¶ | skipping to change at line 391 ¶ | |||
2.2.1. Blocked Decoding | 2.2.1. Blocked Decoding | |||
Upon receipt of an encoded field section, the decoder examines the | Upon receipt of an encoded field section, the decoder examines the | |||
Required Insert Count. When the Required Insert Count is less than | Required Insert Count. When the Required Insert Count is less than | |||
or equal to the decoder's Insert Count, the field section can be | or equal to the decoder's Insert Count, the field section can be | |||
processed immediately. Otherwise, the stream on which the field | processed immediately. Otherwise, the stream on which the field | |||
section was received becomes blocked. | section was received becomes blocked. | |||
While blocked, encoded field section data SHOULD remain in the | While blocked, encoded field section data SHOULD remain in the | |||
blocked stream's flow control window. This data is unusable until | blocked stream's flow-control window. This data is unusable until | |||
the stream becomes unblocked, and releasing the flow control | the stream becomes unblocked, and releasing the flow control | |||
prematurely makes the decoder vulnerable to memory exhaustion | prematurely makes the decoder vulnerable to memory exhaustion | |||
attacks. A stream becomes unblocked when the Insert Count becomes | attacks. A stream becomes unblocked when the Insert Count becomes | |||
unblocked when the Insert Count becomes greater than or equal to the | greater than or equal to the Required Insert Count for all encoded | |||
Required Insert Count for all encoded field sections the decoder has | field sections the decoder has started reading from the stream. | |||
started reading from the stream. | ||||
When processing encoded field sections, the decoder expects the | When processing encoded field sections, the decoder expects the | |||
Required Insert Count to equal the lowest possible value for the | Required Insert Count to equal the lowest possible value for the | |||
Insert Count with which the field section can be decoded, as | Insert Count with which the field section can be decoded, as | |||
prescribed in Section 2.1.2. If it encounters a Required Insert | prescribed in Section 2.1.2. If it encounters a Required Insert | |||
Count smaller than expected, it MUST treat this as a connection error | Count smaller than expected, it MUST treat this as a connection error | |||
of type QPACK_DECOMPRESSION_FAILED; see Section 2.2.3. If it | of type QPACK_DECOMPRESSION_FAILED; see Section 2.2.3. If it | |||
encounters a Required Insert Count larger than expected, it MAY treat | encounters a Required Insert Count larger than expected, it MAY treat | |||
this as a connection error of type QPACK_DECOMPRESSION_FAILED. | this as a connection error of type QPACK_DECOMPRESSION_FAILED. | |||
skipping to change at page 11, line 7 ¶ | skipping to change at line 438 ¶ | |||
Cancellation instruction; see Section 4.4.2. This signals to the | Cancellation instruction; see Section 4.4.2. This signals to the | |||
encoder that all references to the dynamic table on that stream are | encoder that all references to the dynamic table on that stream are | |||
no longer outstanding. A decoder with a maximum dynamic table | no longer outstanding. A decoder with a maximum dynamic table | |||
capacity (Section 3.2.3) equal to zero MAY omit sending Stream | capacity (Section 3.2.3) equal to zero MAY omit sending Stream | |||
Cancellations, because the encoder cannot have any dynamic table | Cancellations, because the encoder cannot have any dynamic table | |||
references. An encoder cannot infer from this instruction that any | references. An encoder cannot infer from this instruction that any | |||
updates to the dynamic table have been received. | updates to the dynamic table have been received. | |||
The Section Acknowledgment and Stream Cancellation instructions | The Section Acknowledgment and Stream Cancellation instructions | |||
permit the encoder to remove references to entries in the dynamic | permit the encoder to remove references to entries in the dynamic | |||
table. When an entry with absolute index lower than the Known | table. When an entry with an absolute index lower than the Known | |||
Received Count has zero references, then it is considered evictable; | Received Count has zero references, then it is considered evictable; | |||
see Section 2.1.1. | see Section 2.1.1. | |||
2.2.2.3. New Table Entries | 2.2.2.3. New Table Entries | |||
After receiving new table entries on the encoder stream, the decoder | After receiving new table entries on the encoder stream, the decoder | |||
chooses when to emit Insert Count Increment instructions; see | chooses when to emit Insert Count Increment instructions; see | |||
Section 4.4.3. Emitting this instruction after adding each new | Section 4.4.3. Emitting this instruction after adding each new | |||
dynamic table entry will provide the timeliest feedback to the | 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 Section Acknowledgments; see | replace them entirely with Section Acknowledgments; see | |||
Section 4.4.1. 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.3. Invalid References | 2.2.3. Invalid References | |||
If the decoder encounters a reference in a field line representation | If the decoder encounters a reference in a field line representation | |||
to a dynamic table entry that has already been evicted or that has an | to a dynamic table entry that has already been evicted or that has an | |||
absolute index greater than or equal to the declared Required Insert | absolute index greater than or equal to the declared Required Insert | |||
skipping to change at page 12, line 9 ¶ | skipping to change at line 488 ¶ | |||
Appendix A. | 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). Each entry is | values can be empty (that is, have a length of 0). Each entry is | |||
identified by a unique index. | identified by a unique index. | |||
Note that the QPACK static table is indexed from 0, whereas the HPACK | Note that 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 field | When the decoder encounters an invalid static table index in a field | |||
line representation it MUST treat this as a connection error of type | line representation, it MUST treat this as a connection error of type | |||
QPACK_DECOMPRESSION_FAILED. If this index is received on the encoder | QPACK_DECOMPRESSION_FAILED. If this index is received on the encoder | |||
stream, this MUST be treated as a connection error of type | stream, this MUST be treated as a connection error of type | |||
QPACK_ENCODER_STREAM_ERROR. | QPACK_ENCODER_STREAM_ERROR. | |||
3.2. Dynamic Table | 3.2. Dynamic Table | |||
The dynamic table consists of a list of field lines maintained in | The dynamic table consists of a list of field lines maintained in | |||
first-in, first-out order. A QPACK encoder and decoder share a | first-in, first-out order. A QPACK encoder and decoder share a | |||
dynamic table that is initially empty. The encoder adds entries to | dynamic table that is initially empty. The encoder adds entries to | |||
the dynamic table and sends them to the decoder via instructions on | the dynamic table and sends them to the decoder via instructions on | |||
skipping to change at page 13, line 39 ¶ | skipping to change at line 558 ¶ | |||
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 Section 5. | SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder; see Section 5. | |||
The encoder MUST NOT set a dynamic table capacity that exceeds this | The encoder MUST NOT set a dynamic table capacity that exceeds this | |||
maximum, but it can choose to use a lower dynamic table capacity; see | maximum, but it can choose to use a lower dynamic table capacity; see | |||
Section 4.3.1. | 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 zero, the server MAY set it to a non-zero value in its | SETTING is zero, 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 | |||
QPACK_DECODER_STREAM_ERROR. | QPACK_DECODER_STREAM_ERROR. | |||
For HTTP/3 servers and HTTP/3 clients when 0-RTT is not attempted or | For clients not using 0-RTT data (whether 0-RTT is not attempted or | |||
is rejected, the maximum table capacity is 0 until the encoder | is rejected) and for all HTTP/3 servers, the maximum table capacity | |||
processes a SETTINGS frame with a non-zero value of | is 0 until the encoder processes a SETTINGS frame with a non-zero | |||
SETTINGS_QPACK_MAX_TABLE_CAPACITY. | value of SETTINGS_QPACK_MAX_TABLE_CAPACITY. | |||
When the maximum table capacity is zero, the encoder MUST NOT insert | When the maximum table capacity is zero, the encoder MUST NOT insert | |||
entries into the dynamic table, and MUST NOT send any encoder | entries into the dynamic table and MUST NOT send any encoder | |||
instructions on the encoder stream. | instructions on the encoder stream. | |||
3.2.4. Absolute Indexing | 3.2.4. Absolute Indexing | |||
Each entry possesses an absolute index that is fixed for the lifetime | Each entry possesses an absolute index that is fixed for the lifetime | |||
of that entry. The first entry inserted has an absolute index of 0; | of that entry. The first entry inserted has an absolute index of 0; | |||
indices increase by one with each insertion. | indices increase by one with each insertion. | |||
3.2.5. Relative Indexing | 3.2.5. Relative Indexing | |||
skipping to change at page 15, line 25 ¶ | skipping to change at line 636 ¶ | |||
d = count of entries dropped | d = count of entries dropped | |||
In this example, Base = n - 2 | In this example, Base = n - 2 | |||
Figure 3: Example Dynamic Table Indexing - Relative Index in | Figure 3: Example Dynamic Table Indexing - Relative Index in | |||
Representation | Representation | |||
3.2.6. Post-Base Indexing | 3.2.6. Post-Base Indexing | |||
Post-Base indices are used in field line representations for entries | Post-Base indices are used in field line representations for entries | |||
with absolute indices greater than or equal to Base, starting at 0 | with absolute indices greater than or equal to Base, starting at 0 | |||
for the entry with absolute index equal to Base, and increasing in | for the entry with absolute index equal to Base and increasing in the | |||
the same direction as the absolute index. | same direction as the absolute index. | |||
Post-Base indices allow an encoder to process a field section in a | Post-Base indices allow an encoder to process a field section 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) field sections. | this (or other) field sections. | |||
Base | Base | |||
| | | | |||
V | V | |||
+-----+-----+-----+-----+-----+ | +-----+-----+-----+-----+-----+ | |||
| n-1 | n-2 | n-3 | ... | d | Absolute Index | | n-1 | n-2 | n-3 | ... | d | Absolute Index | |||
skipping to change at page 16, line 26 ¶ | skipping to change at line 680 ¶ | |||
QPACK implementations MUST be able to decode integers up to and | QPACK implementations MUST be able to decode integers up to and | |||
including 62 bits long. | including 62 bits long. | |||
4.1.2. String Literals | 4.1.2. String Literals | |||
The string literal defined by Section 5.2 of [RFC7541] is also used | The string literal defined by Section 5.2 of [RFC7541] is also used | |||
throughout. This string format includes optional Huffman encoding. | throughout. This string format includes optional Huffman encoding. | |||
HPACK defines string literals to begin on a byte boundary. They | HPACK defines string literals to begin on a byte boundary. They | |||
begin with a single bit flag, denoted as 'H' in this document | begin with a single bit flag, denoted as 'H' in this document | |||
(indicating whether the string is Huffman-coded), followed by the | (indicating whether the string is Huffman encoded), followed by the | |||
Length encoded as a 7-bit prefix integer, and finally Length bytes of | string length encoded as a 7-bit prefix integer, and finally the | |||
data. When Huffman encoding is enabled, the Huffman table from | indicated number of bytes of data. When Huffman encoding is enabled, | |||
Appendix B of [RFC7541] is used without modification and Length | the Huffman table from Appendix B of [RFC7541] is used without | |||
indicates the size of the string after encoding. | modification and the indicated length is the size of the string after | |||
encoding. | ||||
This document expands the definition of string literals by permitting | This document expands the definition of string literals by permitting | |||
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 mid-byte, with the first (8-N) bits allocated to a | literal" begins mid-byte, with the first (8-N) bits allocated to a | |||
previous field. The string uses one bit for the Huffman flag, | previous field. The string uses one bit for the Huffman flag, | |||
followed by the Length encoded as an (N-1)-bit prefix integer. The | followed by the length of the encoded string as a (N-1)-bit prefix | |||
prefix size, N, can have a value between 2 and 8 inclusive. The | integer. The prefix size, N, can have a value between 2 and 8, | |||
remainder of the string literal is unmodified. | inclusive. The remainder of the string 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. Encoder and Decoder Streams | 4.2. Encoder and Decoder Streams | |||
QPACK defines two unidirectional stream types: | QPACK defines two unidirectional stream types: | |||
* An encoder stream is a unidirectional stream of type 0x02. It | * 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. | |||
* A decoder stream is a unidirectional stream of type 0x03. It | * 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 at most one encoder stream and at most one decoder | MUST initiate, at most, one encoder stream and, at most, one decoder | |||
stream. Receipt of a second instance of either stream type MUST be | stream. Receipt of a second instance of either stream type MUST be | |||
treated as a connection error of type H3_STREAM_CREATION_ERROR. | treated as a connection error of type H3_STREAM_CREATION_ERROR. | |||
These streams MUST NOT be closed. Closure of either unidirectional | The sender MUST NOT close either of these streams, and the receiver | |||
stream type MUST be treated as a connection error of type | MUST NOT request that the sender close either of these streams. | |||
H3_CLOSED_CRITICAL_STREAM. | Closure of either unidirectional stream type MUST be treated as a | |||
connection error of type H3_CLOSED_CRITICAL_STREAM. | ||||
An endpoint MAY avoid creating an encoder stream if it will not be | An endpoint MAY avoid creating an encoder stream if it will not be | |||
used (for example if its encoder does not wish to use the dynamic | used (for example, if its encoder does not wish to use the dynamic | |||
table, or if the maximum size of the dynamic table permitted by the | table or if the maximum size of the dynamic table permitted by the | |||
peer is zero). | peer is zero). | |||
An endpoint MAY avoid creating a decoder stream if its decoder sets | An endpoint MAY avoid creating a decoder stream if its decoder sets | |||
the maximum capacity of the dynamic table to zero. | the maximum capacity of the dynamic table to zero. | |||
An endpoint MUST allow its peer to create an encoder stream and a | An endpoint MUST allow its peer to create an encoder stream and a | |||
decoder stream even if the connection's settings prevent their use. | decoder stream even if the connection's settings prevent their use. | |||
4.3. Encoder Instructions | 4.3. Encoder Instructions | |||
skipping to change at page 18, line 18 ¶ | skipping to change at line 770 ¶ | |||
the decoder. The decoder MUST treat a new dynamic table capacity | the decoder. The decoder MUST treat a new dynamic table capacity | |||
value that exceeds this limit as a connection error of type | value that exceeds this limit as a connection error of type | |||
QPACK_ENCODER_STREAM_ERROR. | QPACK_ENCODER_STREAM_ERROR. | |||
Reducing the dynamic table capacity can cause entries to be evicted; | Reducing the dynamic table capacity can cause entries to be evicted; | |||
see Section 3.2.2. This MUST NOT cause the eviction of entries that | see Section 3.2.2. This MUST NOT cause the eviction of entries that | |||
are not evictable; see Section 2.1.1. Changing the capacity of the | are not evictable; see Section 2.1.1. Changing the capacity of the | |||
dynamic table is not acknowledged as this instruction does not insert | dynamic table is not acknowledged as this instruction does not insert | |||
an entry. | an entry. | |||
4.3.2. Insert With Name Reference | 4.3.2. Insert with Name Reference | |||
An encoder adds an entry to the dynamic table where the field name | An encoder adds an entry to the dynamic table where the field name | |||
matches the field name of an entry stored in the static or the | matches the field name of an entry stored in the static or the | |||
dynamic table using an instruction that starts with the '1' 1-bit | dynamic table using an instruction that starts with the '1' 1-bit | |||
pattern. The second ('T') bit indicates whether the reference is to | pattern. The second ('T') bit indicates whether the reference is to | |||
the static or dynamic table. The 6-bit prefix integer | the static or dynamic table. The 6-bit prefix integer | |||
(Section 4.1.1) that follows is used to locate the table entry for | (Section 4.1.1) that follows is used to locate the table entry for | |||
the field name. When T=1, the number represents the static table | the field name. When T=1, the number represents the static table | |||
index; when T=0, the number is the relative index of the entry in the | index; when T=0, the number is the relative index of the entry in the | |||
dynamic table. | dynamic table. | |||
skipping to change at page 18, line 44 ¶ | skipping to change at line 796 ¶ | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 1 | T | Name Index (6+) | | | 1 | T | Name Index (6+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length bytes) | | | Value String (Length bytes) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Figure 6: Insert Field Line -- Indexed Name | Figure 6: Insert Field Line -- Indexed Name | |||
4.3.3. Insert With Literal Name | 4.3.3. Insert with Literal Name | |||
An encoder adds an entry to the dynamic table where both the field | An encoder adds an entry to the dynamic table where both the field | |||
name and the field value are represented as string literals using an | name and the field value are represented as string literals using an | |||
instruction that starts with the '01' 2-bit pattern. | instruction that starts with the '01' 2-bit pattern. | |||
This is followed by the name represented as a 6-bit prefix string | This is followed by the name represented as a 6-bit prefix string | |||
literal, and the value represented as an 8-bit prefix string literal; | literal and the value represented as an 8-bit prefix string literal; | |||
see Section 4.1.2. | see Section 4.1.2. | |||
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+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
skipping to change at page 19, line 32 ¶ | skipping to change at line 833 ¶ | |||
followed by the relative index of the existing entry represented as | followed by the relative index of the existing entry represented as | |||
an integer with a 5-bit prefix; see Section 4.1.1. | an integer with a 5-bit prefix; see Section 4.1.1. | |||
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 8: Duplicate | Figure 8: Duplicate | |||
The existing entry is re-inserted into the dynamic table without | The existing entry is reinserted into the dynamic table without | |||
resending either the name or the value. This is useful to avoid | resending either the name or the value. This is useful to avoid | |||
adding a reference to an older entry, which might block inserting new | adding a reference to an older entry, which might block inserting new | |||
entries. | entries. | |||
4.4. Decoder Instructions | 4.4. Decoder Instructions | |||
A decoder sends decoder instructions on the decoder stream to inform | A decoder sends decoder instructions on the decoder stream to inform | |||
the encoder about the processing of field sections and table updates | the encoder about the processing of field sections and table updates | |||
to ensure consistency of the dynamic table. | to ensure consistency of the dynamic table. | |||
4.4.1. Section Acknowledgment | 4.4.1. Section Acknowledgment | |||
After processing an encoded field section whose declared Required | After processing an encoded field section whose declared Required | |||
Insert Count is not zero, the decoder emits a Section Acknowledgment | Insert Count is not zero, the decoder emits a Section Acknowledgment | |||
instruction. The instruction starts with the '1' 1-bit pattern, | instruction. The instruction starts with the '1' 1-bit pattern, | |||
followed by the field section's associated stream ID encoded as a | followed by the field section's associated stream ID encoded as a | |||
7-bit prefix integer; see Section 4.1.1. | 7-bit prefix integer; see Section 4.1.1. | |||
This instruction is used as described in Section 2.1.4 and in | This instruction is used as described in Sections 2.1.4 and 2.2.2. | |||
Section 2.2.2. | ||||
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 9: Section Acknowledgment | Figure 9: Section Acknowledgment | |||
If an encoder receives a Section Acknowledgment instruction referring | If an encoder receives a Section Acknowledgment instruction referring | |||
to a stream on which every encoded field section with a non-zero | to a stream on which every encoded field section with a non-zero | |||
skipping to change at page 21, line 7 ¶ | skipping to change at line 903 ¶ | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | Increment (6+) | | | 0 | 0 | Increment (6+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
Figure 11: Insert Count Increment | Figure 11: Insert Count Increment | |||
An encoder that receives an Increment field equal to zero, or one | An encoder that receives an Increment field equal to zero, or one | |||
that increases the Known Received Count beyond what the encoder has | that increases the Known Received Count beyond what the encoder has | |||
sent MUST treat this as a connection error of type | sent, MUST treat this as a connection error of type | |||
QPACK_DECODER_STREAM_ERROR. | QPACK_DECODER_STREAM_ERROR. | |||
4.5. Field Line Representations | 4.5. Field Line Representations | |||
An encoded field section consists of a prefix and a possibly empty | An encoded field section consists of a prefix and a possibly empty | |||
sequence of representations defined in this section. Each | sequence of representations defined in this section. Each | |||
representation corresponds to a single field line. These | representation corresponds to a single field line. These | |||
representations reference the static table or the dynamic table in a | representations reference the static table or the dynamic table in a | |||
particular state, but do not modify that state. | particular state, but they do not modify that state. | |||
Encoded field sections are carried in frames on streams defined by | Encoded field sections are carried in frames on streams defined by | |||
the enclosing protocol. | the enclosing protocol. | |||
4.5.1. Encoded Field Section Prefix | 4.5.1. Encoded Field Section Prefix | |||
Each encoded field section is prefixed with two integers. The | Each encoded field section is prefixed with two integers. The | |||
Required Insert Count is encoded as an integer with an 8-bit prefix | Required Insert Count is encoded as an integer with an 8-bit prefix | |||
using the encoding described in Section 4.5.1.1. The Base is encoded | using the encoding described in Section 4.5.1.1. The Base is encoded | |||
as a sign bit ('S') and a Delta Base value with a 7-bit prefix; see | as a Sign bit ('S') and a Delta Base value with a 7-bit prefix; see | |||
Section 4.5.1.2. | Section 4.5.1.2. | |||
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+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Encoded Field Lines ... | | Encoded Field Lines ... | |||
+-------------------------------+ | +-------------------------------+ | |||
skipping to change at page 22, line 10 ¶ | skipping to change at line 951 ¶ | |||
rest of the field section. | rest of the field section. | |||
The encoder transforms the Required Insert Count as follows before | The encoder transforms the Required Insert Count as follows before | |||
encoding: | encoding: | |||
if ReqInsertCount == 0: | if ReqInsertCount == 0: | |||
EncInsertCount = 0 | EncInsertCount = 0 | |||
else: | else: | |||
EncInsertCount = (ReqInsertCount mod (2 * MaxEntries)) + 1 | EncInsertCount = (ReqInsertCount mod (2 * MaxEntries)) + 1 | |||
Here "MaxEntries" is the maximum number of entries that the dynamic | Here MaxEntries is the maximum number of entries that the dynamic | |||
table can have. The smallest entry has empty name and value strings | table can have. The smallest entry has empty name and value strings | |||
and has the size of 32. Hence "MaxEntries" is calculated as | and has the size of 32. Hence, MaxEntries is calculated as: | |||
MaxEntries = floor( MaxTableCapacity / 32 ) | MaxEntries = floor( MaxTableCapacity / 32 ) | |||
"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 connection error of type | conformant encoder, it MUST treat this as a connection error of type | |||
QPACK_DECOMPRESSION_FAILED. | QPACK_DECOMPRESSION_FAILED. | |||
skipping to change at page 23, line 40 ¶ | skipping to change at line 1007 ¶ | |||
Insert Count will be encoded modulo 6. If a decoder has received 10 | Insert Count will be encoded modulo 6. If a decoder has received 10 | |||
inserts, then an encoded value of 4 indicates that the Required | inserts, then an encoded value of 4 indicates that the Required | |||
Insert Count is 9 for the field section. | Insert Count is 9 for the field section. | |||
4.5.1.2. Base | 4.5.1.2. Base | |||
The Base is used to resolve references in the dynamic table as | The Base is used to resolve references in the dynamic table as | |||
described in Section 3.2.5. | described in Section 3.2.5. | |||
To save space, the Base is encoded relative to the Required Insert | To save space, the Base is encoded relative to the Required Insert | |||
Count using a one-bit sign ('S') and the Delta Base value. A sign | Count using a one-bit Sign ('S' in Figure 12) and the Delta Base | |||
bit of 0 indicates that the Base is greater than or equal to the | value. A Sign bit of 0 indicates that the Base is greater than or | |||
value of the Required Insert Count; the decoder adds the value of | equal to the value of the Required Insert Count; the decoder adds the | |||
Delta Base to the Required Insert Count to determine the value of the | value of Delta Base to the Required Insert Count to determine the | |||
Base. A sign bit of 1 indicates that the Base is less than the | value of the Base. A Sign bit of 1 indicates that the Base is less | |||
Required Insert Count; the decoder subtracts the value of Delta Base | than the Required Insert Count; the decoder subtracts the value of | |||
from the Required Insert Count and also subtracts one to determine | Delta Base from the Required Insert Count and also subtracts one to | |||
the value of the Base. That is: | determine the value of the Base. That is: | |||
if S == 0: | if Sign == 0: | |||
Base = ReqInsertCount + DeltaBase | Base = ReqInsertCount + DeltaBase | |||
else: | else: | |||
Base = ReqInsertCount - DeltaBase - 1 | Base = ReqInsertCount - DeltaBase - 1 | |||
A single-pass encoder determines the Base before encoding a field | A single-pass encoder determines the Base before encoding a field | |||
section. If the encoder inserted entries in the dynamic table while | section. If the encoder inserted entries in the dynamic table while | |||
encoding the field section and is referencing them, Required Insert | encoding the field section and is referencing them, Required Insert | |||
Count will be greater than the Base, so the encoded difference is | Count will be greater than the Base, so the encoded difference is | |||
negative and the sign bit is set to 1. If the field section was not | negative and the Sign bit is set to 1. If the field section was not | |||
encoded using representations that reference the most recent entry in | encoded using representations that reference the most recent entry in | |||
the table and did not insert any new entries, the Base will be | the table and did not insert any new entries, the Base will be | |||
greater than the Required Insert Count, so the delta will be positive | greater than the Required Insert Count, so the encoded difference | |||
and the sign bit is set to 0. | will be positive and the Sign bit is set to 0. | |||
The value of Base MUST NOT be negative. Though the protocol might | ||||
operate correctly with a negative Base using post-Base indexing, it | ||||
is unnecessary and inefficient. An endpoint MUST treat a field block | ||||
with a Sign bit of 1 as invalid if the value of Required Insert Count | ||||
is less than or equal to the value of Delta Base. | ||||
An encoder that produces table updates before encoding a field | An encoder that produces table updates before encoding a field | |||
section might set Base to the value of Required Insert Count. In | section might set Base to the value of Required Insert Count. In | |||
such case, both the sign bit and the Delta Base will be set to zero. | such a case, both the Sign bit and the Delta Base will be set to | |||
zero. | ||||
A field section that was encoded without references to the dynamic | A field section that was encoded without references to the dynamic | |||
table can use any value for the Base; setting Delta Base to zero is | table can use any value for the Base; setting Delta Base to zero is | |||
one of the most efficient encodings. | one of the most efficient encodings. | |||
For example, with a Required Insert Count of 9, a decoder receives an | 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 | Sign 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 | |||
relative index of 1 refers to the 5th entry that was added to the | relative index of 1 refers to the fifth 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 eighth entry. | |||
4.5.2. Indexed Field Line | 4.5.2. Indexed Field Line | |||
An indexed field line representation identifies an entry in the | An indexed field line representation identifies an entry in the | |||
static table, or an entry in the dynamic table with an absolute index | static table or an entry in the dynamic table with an absolute index | |||
less than the value of the Base. | less than the value of the Base. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 1 | T | Index (6+) | | | 1 | T | Index (6+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
Figure 13: Indexed Field Line | Figure 13: Indexed Field Line | |||
This representation starts with the '1' 1-bit pattern, followed by | This representation starts with the '1' 1-bit pattern, followed by | |||
the 'T' bit indicating whether the reference is into the static or | the 'T' bit, indicating whether the reference is into the static or | |||
dynamic table. The 6-bit prefix integer (Section 4.1.1) that follows | dynamic table. The 6-bit prefix integer (Section 4.1.1) that follows | |||
is used to locate the table entry for the field line. When T=1, the | is used to locate the table entry for the field line. When T=1, the | |||
number represents the static table index; when T=0, the number is the | number represents the static table index; when T=0, the number is the | |||
relative index of the entry in the dynamic table. | relative index of the entry in the dynamic table. | |||
4.5.3. Indexed Field Line With Post-Base Index | 4.5.3. Indexed Field Line with Post-Base Index | |||
An indexed field line with post-base index representation identifies | An indexed field line with post-Base index representation identifies | |||
an entry in the dynamic table with an absolute index greater than or | an entry in the dynamic table with an absolute index greater than or | |||
equal to the value of the Base. | equal to the value of the Base. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 0 | 1 | Index (4+) | | | 0 | 0 | 0 | 1 | Index (4+) | | |||
+---+---+---+---+---------------+ | +---+---+---+---+---------------+ | |||
Figure 14: Indexed Field Line with Post-Base Index | Figure 14: Indexed Field Line with Post-Base Index | |||
This representation starts with the '0001' 4-bit pattern. This is | This representation starts with the '0001' 4-bit pattern. This is | |||
followed by the post-base index (Section 3.2.6) of the matching field | followed by the post-Base index (Section 3.2.6) of the matching field | |||
line, represented as an integer with a 4-bit prefix; see | line, represented as an integer with a 4-bit prefix; see | |||
Section 4.1.1. | Section 4.1.1. | |||
4.5.4. Literal Field Line With Name Reference | 4.5.4. Literal Field Line with Name Reference | |||
A literal field line with name reference representation encodes a | A literal field line with name reference representation encodes a | |||
field line where the field name matches the field name of an entry in | field line where the field name matches the field name of an entry in | |||
the static table, or the field name of an entry in the dynamic table | the static table or the field name of an entry in the dynamic table | |||
with an absolute index less than the value of the Base. | with an absolute index less than the value of the Base. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 1 | N | T |Name Index (4+)| | | 0 | 1 | N | T |Name Index (4+)| | |||
+---+---+---+---+---------------+ | +---+---+---+---+---------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length bytes) | | | Value String (Length bytes) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Figure 15: Literal Field Line With Name Reference | Figure 15: Literal Field Line with Name Reference | |||
This representation starts with the '01' 2-bit pattern. The | This representation starts with the '01' 2-bit pattern. The | |||
following bit, 'N', indicates whether an intermediary is permitted to | following bit, 'N', indicates whether an intermediary is permitted to | |||
add this field line to the dynamic table on subsequent hops. When | add this field line to the dynamic table on subsequent hops. When | |||
the 'N' bit is set, the encoded field line MUST always be encoded | the 'N' bit is set, the encoded field line MUST always be encoded | |||
with a literal representation. In particular, when a peer sends a | with a literal representation. In particular, when a peer sends a | |||
field line that it received represented as a literal field line with | field line that it received represented as a literal field line with | |||
the 'N' bit set, it MUST use a literal representation to forward this | the 'N' bit set, it MUST use a literal representation to forward this | |||
field line. This bit is intended for protecting field values that | field line. This bit is intended for protecting field values that | |||
are not to be put at risk by compressing them; see Section 7.1 for | are not to be put at risk by compressing them; see Section 7.1 for | |||
skipping to change at page 26, line 15 ¶ | skipping to change at line 1129 ¶ | |||
The fourth ('T') bit indicates whether the reference is to the static | The fourth ('T') bit indicates whether the reference is to the static | |||
or dynamic table. The 4-bit prefix integer (Section 4.1.1) that | or dynamic table. The 4-bit prefix integer (Section 4.1.1) that | |||
follows is used to locate the table entry for the field name. When | follows is used to locate the table entry for the field name. When | |||
T=1, the number represents the static table index; when T=0, the | T=1, the number represents the static table index; when T=0, the | |||
number is the relative index of the entry in the dynamic table. | number is the relative index of the entry in the dynamic table. | |||
Only the field name is taken from the dynamic table entry; the field | Only the field name is taken from the dynamic table entry; the field | |||
value is encoded as an 8-bit prefix string literal; see | value is encoded as an 8-bit prefix string literal; see | |||
Section 4.1.2. | Section 4.1.2. | |||
4.5.5. Literal Field Line With Post-Base Name Reference | 4.5.5. Literal Field Line with Post-Base Name Reference | |||
A literal field line with post-base name reference representation | A literal field line with post-Base name reference representation | |||
encodes a field line where the field name matches the field name of a | encodes a field line where the field name matches the field name of a | |||
dynamic table entry with an absolute index greater than or equal to | dynamic table entry with an absolute index greater than or equal to | |||
the value of the Base. | the value of the Base. | |||
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) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Figure 16: Literal Field Line With Post-Base Name Reference | Figure 16: Literal Field Line with Post-Base Name Reference | |||
This representation starts with the '0000' 4-bit pattern. The fifth | This representation starts with the '0000' 4-bit pattern. The fifth | |||
bit is the 'N' bit as described in Section 4.5.4. This is followed | bit is the 'N' bit as described in Section 4.5.4. This is followed | |||
by a post-base index of the dynamic table entry (Section 3.2.6) | by a post-Base index of the dynamic table entry (Section 3.2.6) | |||
encoded as an integer with a 3-bit prefix; see Section 4.1.1. | encoded as an integer with a 3-bit prefix; see Section 4.1.1. | |||
Only the field name is taken from the dynamic table entry; the field | Only the field name is taken from the dynamic table entry; the field | |||
value is encoded as an 8-bit prefix string literal; see | value is encoded as an 8-bit prefix string literal; see | |||
Section 4.1.2. | Section 4.1.2. | |||
4.5.6. Literal Field Line With Literal Name | 4.5.6. Literal Field Line with Literal Name | |||
The literal field line with literal name representation encodes a | The literal field line with literal name representation encodes a | |||
field name and a field value as string literals. | field name and a field value as string literals. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 1 | N | H |NameLen(3+)| | | 0 | 0 | 1 | N | H |NameLen(3+)| | |||
+---+---+---+---+---+-----------+ | +---+---+---+---+---+-----------+ | |||
| Name String (Length bytes) | | | Name String (Length bytes) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length bytes) | | | Value String (Length bytes) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Figure 17: Literal Field Line With Literal Name | Figure 17: Literal Field Line with Literal Name | |||
This representation starts with the '001' 3-bit pattern. The fourth | This representation starts with the '001' 3-bit pattern. The fourth | |||
bit is the 'N' bit as described in Section 4.5.4. The name follows, | bit is the 'N' bit as described in Section 4.5.4. The name follows, | |||
represented as a 4-bit prefix string literal, then the value, | represented as a 4-bit prefix string literal, then the value, | |||
represented as an 8-bit prefix string literal; see Section 4.1.2. | represented as an 8-bit prefix string literal; see Section 4.1.2. | |||
5. Configuration | 5. Configuration | |||
QPACK defines two settings for the HTTP/3 SETTINGS frame: | QPACK defines two settings for the HTTP/3 SETTINGS frame: | |||
SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x1): The default value is zero. | SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x01): The default value is zero. | |||
See Section 3.2 for usage. This is the equivalent of the | See 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): The default value is zero. | SETTINGS_QPACK_BLOCKED_STREAMS (0x07): The default value is zero. | |||
See Section 2.1.2. | See Section 2.1.2. | |||
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 that prevent the stream or connection from continuing: | of QPACK that prevent the stream or connection from continuing: | |||
QPACK_DECOMPRESSION_FAILED (0x200): The decoder failed to interpret | QPACK_DECOMPRESSION_FAILED (0x0200): The decoder failed to interpret | |||
an encoded field section and is not able to continue decoding that | an encoded field section and is not able to continue decoding that | |||
field section. | field section. | |||
QPACK_ENCODER_STREAM_ERROR (0x201): The decoder failed to interpret | QPACK_ENCODER_STREAM_ERROR (0x0201): The decoder failed to interpret | |||
an encoder instruction received on the encoder stream. | an encoder instruction received on the encoder stream. | |||
QPACK_DECODER_STREAM_ERROR (0x202): The encoder failed to interpret | QPACK_DECODER_STREAM_ERROR (0x0202): The encoder failed to interpret | |||
a decoder instruction received on the decoder stream. | a decoder instruction received on the decoder stream. | |||
7. Security Considerations | 7. Security Considerations | |||
This section describes potential areas of security concern with | This section describes potential areas of security concern with | |||
QPACK: | QPACK: | |||
* Use of compression as a length-based oracle for verifying guesses | * Use of compression as a length-based oracle for verifying guesses | |||
about secrets that are compressed into a shared compression | about secrets that are compressed into a shared compression | |||
context. | context. | |||
skipping to change at page 28, line 28 ¶ | skipping to change at line 1233 ¶ | |||
The compression context used to encode header and trailer fields can | The compression context used to encode header and trailer fields can | |||
be probed by an attacker who can both define fields to be encoded and | be probed by an attacker who can both define fields to be encoded and | |||
transmitted and observe the length of those fields once they are | transmitted and observe the length of those fields once they are | |||
encoded. When an attacker can do both, they can adaptively modify | encoded. When an attacker can do both, they can adaptively modify | |||
requests in order to confirm guesses about the dynamic table state. | requests in order to confirm guesses about the dynamic table state. | |||
If a guess is compressed into a shorter length, the attacker can | If a guess is compressed into a shorter length, the attacker can | |||
observe the encoded length and infer that the guess was correct. | observe the encoded length and infer that the guess was correct. | |||
This is possible even over the Transport Layer Security Protocol | This is possible even over the Transport Layer Security Protocol | |||
(TLS, see [TLS]) and the QUIC Transport Protocol (see | ([TLS]) and the QUIC Transport Protocol ([QUIC-TRANSPORT]), because | |||
[QUIC-TRANSPORT]), because while TLS and QUIC provide confidentiality | while TLS and QUIC provide confidentiality protection for content, | |||
protection for content, they only provide a limited amount of | they only provide a limited amount of protection for the length of | |||
protection for the length of that content. | that content. | |||
Note: Padding schemes only provide limited protection against an | | Note: Padding schemes only provide limited protection against | |||
attacker with these capabilities, potentially only forcing an | | an attacker with these capabilities, potentially only forcing | |||
increased number of guesses to learn the length associated with a | | an increased number of guesses to learn the length associated | |||
given guess. Padding schemes also work directly against | | with a given guess. Padding schemes also work directly against | |||
compression by increasing the number of bits that are transmitted. | | compression by increasing the number of bits that are | |||
| transmitted. | ||||
Attacks like CRIME ([CRIME]) demonstrated the existence of these | Attacks like CRIME ([CRIME]) demonstrated the existence of these | |||
general attacker capabilities. The specific attack exploited the | general attacker capabilities. The specific attack exploited the | |||
fact that DEFLATE ([RFC1951]) removes redundancy based on prefix | fact that DEFLATE ([RFC1951]) removes redundancy based on prefix | |||
matching. This permitted the attacker to confirm guesses a character | matching. This permitted the attacker to confirm guesses a character | |||
at a time, reducing an exponential-time attack into a linear-time | at a time, reducing an exponential-time attack into a linear-time | |||
attack. | attack. | |||
7.1.1. Applicability to QPACK and HTTP | 7.1.1. Applicability to QPACK and HTTP | |||
QPACK mitigates but does not completely prevent attacks modeled on | QPACK mitigates, but does not completely prevent, attacks modeled on | |||
CRIME ([CRIME]) by forcing a guess to match an entire field line, | CRIME ([CRIME]) by forcing a guess to match an entire field line | |||
rather than individual characters. An attacker can only learn | rather than individual characters. An attacker can only learn | |||
whether a guess is correct or not, so is reduced to a brute force | whether a guess is correct or not, so the attacker is reduced to a | |||
guess for the field values associated with a given field name. | brute-force guess for the field values associated with a given field | |||
name. | ||||
The viability of recovering specific field values therefore depends | Therefore, the viability of recovering specific field values depends | |||
on the entropy of values. As a result, values with high entropy are | on the entropy of values. As a result, values with high entropy are | |||
unlikely to be recovered successfully. However, values with low | unlikely to be recovered successfully. However, values with low | |||
entropy remain vulnerable. | entropy remain vulnerable. | |||
Attacks of this nature are possible any time that two mutually | Attacks of this nature are possible any time that two mutually | |||
distrustful entities control requests or responses that are placed | distrustful entities control requests or responses that are placed | |||
onto a single HTTP/3 connection. If the shared QPACK compressor | onto a single HTTP/3 connection. If the shared QPACK compressor | |||
permits one entity to add entries to the dynamic table, and the other | permits one entity to add entries to the dynamic table, and the other | |||
to refer to those entries while encoding chosen field lines, then the | to refer to those entries while encoding chosen field lines, then the | |||
attacker (the second entity) can learn the state of the table by | attacker (the second entity) can learn the state of the table by | |||
skipping to change at page 30, line 23 ¶ | skipping to change at line 1328 ¶ | |||
the field value. Disabling access to the dynamic table for a given | the field value. Disabling access to the dynamic table for a given | |||
field name might occur for shorter values more quickly or with higher | field name might occur for shorter values more quickly or with higher | |||
probability than for longer values. | probability than for longer values. | |||
This mitigation is most effective between two endpoints. If messages | This mitigation is most effective between two endpoints. If messages | |||
are re-encoded by an intermediary without knowledge of which entity | are re-encoded by an intermediary without knowledge of which entity | |||
constructed a given message, the intermediary could inadvertently | constructed a given message, the intermediary could inadvertently | |||
merge compression contexts that the original encoder had specifically | merge compression contexts that the original encoder had specifically | |||
kept separate. | kept separate. | |||
Note: Simply removing entries corresponding to the field from the | | Note: Simply removing entries corresponding to the field from | |||
dynamic table can be ineffectual if the attacker has a reliable | | the dynamic table can be ineffectual if the attacker has a | |||
way of causing values to be reinstalled. For example, a request | | reliable way of causing values to be reinstalled. For example, | |||
to load an image in a web browser typically includes the Cookie | | a request to load an image in a web browser typically includes | |||
header field (a potentially highly valued target for this sort of | | the Cookie header field (a potentially highly valued target for | |||
attack), and web sites can easily force an image to be loaded, | | this sort of attack), and websites can easily force an image to | |||
thereby refreshing the entry in the dynamic table. | | be loaded, thereby refreshing the entry in the dynamic table. | |||
7.1.3. Never-Indexed Literals | 7.1.3. Never-Indexed Literals | |||
Implementations can also choose to protect sensitive fields by not | Implementations can also choose to protect sensitive fields by not | |||
compressing them and instead encoding their value as literals. | compressing them and instead encoding their value as literals. | |||
Refusing to insert a field line into the dynamic table is only | Refusing to insert a field line into the dynamic table is only | |||
effective if doing so is avoided on all hops. The never-indexed | effective if doing so is avoided on all hops. The never-indexed | |||
literal bit (see Section 4.5.4) can be used to signal to | literal bit (see Section 4.5.4) can be used to signal to | |||
intermediaries that a particular value was intentionally sent as a | intermediaries that a particular value was intentionally sent as a | |||
skipping to change at page 31, line 28 ¶ | skipping to change at line 1377 ¶ | |||
is sent to any server. In that case, confirmation that a particular | is sent to any server. In that case, confirmation that a particular | |||
User-Agent value has been used provides little value. | User-Agent value has been used provides little value. | |||
Note that these criteria for deciding to use a never-indexed literal | Note that these criteria for deciding to use a never-indexed literal | |||
representation will evolve over time as new attacks are discovered. | representation will evolve over time as new attacks are discovered. | |||
7.2. Static Huffman Encoding | 7.2. Static Huffman Encoding | |||
There is no currently known attack against a static Huffman encoding. | There is no currently known attack against a static Huffman encoding. | |||
A study has shown that using a static Huffman encoding table created | A study has shown that using a static Huffman encoding table created | |||
an information leakage, however this same study concluded that an | an information leakage; however, this same study concluded that an | |||
attacker could not take advantage of this information leakage to | attacker could not take advantage of this information leakage to | |||
recover any meaningful amount of information (see [PETAL]). | recover any meaningful amount of information (see [PETAL]). | |||
7.3. Memory Consumption | 7.3. Memory Consumption | |||
An attacker can try to cause an endpoint to exhaust its memory. | An attacker can try to cause an endpoint to exhaust its memory. | |||
QPACK is designed to limit both the peak and stable amounts of memory | QPACK is designed to limit both the peak and stable amounts of memory | |||
allocated by an endpoint. | allocated by an endpoint. | |||
QPACK uses the definition of the maximum size of the dynamic table | QPACK uses the definition of the maximum size of the dynamic table | |||
skipping to change at page 32, line 17 ¶ | skipping to change at line 1412 ¶ | |||
dynamic table. In HTTP/3, this is realized by setting an appropriate | dynamic table. In HTTP/3, this is realized by setting an appropriate | |||
value for the SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter. An | value for the SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter. An | |||
encoder can limit the amount of state memory it uses by choosing a | encoder can limit the amount of state memory it uses by choosing a | |||
smaller dynamic table size than the decoder allows and signaling this | smaller dynamic table size than the decoder allows and signaling this | |||
to the decoder (see Section 4.3.1). | to the decoder (see Section 4.3.1). | |||
A decoder can limit the amount of state memory used for blocked | A decoder can limit the amount of state memory used for blocked | |||
streams by setting an appropriate value for the maximum number of | streams by setting an appropriate value for the maximum number of | |||
blocked streams. In HTTP/3, this is realized by setting an | blocked streams. In HTTP/3, this is realized by setting an | |||
appropriate value for the SETTINGS_QPACK_BLOCKED_STREAMS parameter. | appropriate value for the SETTINGS_QPACK_BLOCKED_STREAMS parameter. | |||
Streams which risk becoming blocked consume no additional state | Streams that risk becoming blocked consume no additional state memory | |||
memory on the encoder. | on the encoder. | |||
An encoder allocates memory to track all dynamic table references in | An encoder allocates memory to track all dynamic table references in | |||
unacknowledged field sections. An implementation can directly limit | unacknowledged field sections. An implementation can directly limit | |||
the amount of state memory by only using as many references to the | the amount of state memory by only using as many references to the | |||
dynamic table as it wishes to track; no signaling to the decoder is | dynamic table as it wishes to track; no signaling to the decoder is | |||
required. However, limiting references to the dynamic table will | required. However, limiting references to the dynamic table will | |||
reduce compression effectiveness. | reduce compression effectiveness. | |||
The amount of temporary memory consumed by an encoder or decoder can | The amount of temporary memory consumed by an encoder or decoder can | |||
be limited by processing field lines sequentially. A decoder | be limited by processing field lines sequentially. A decoder | |||
skipping to change at page 33, line 14 ¶ | skipping to change at line 1457 ¶ | |||
An implementation has to set a limit for the values it accepts for | An implementation has to set a limit for the values it accepts for | |||
integers, as well as for the encoded length; see Section 4.1.1. In | integers, as well as for the encoded length; see Section 4.1.1. In | |||
the same way, it has to set a limit to the length it accepts for | the same way, it has to set a limit to the length it accepts for | |||
string literals; see Section 4.1.2. These limits SHOULD be large | string literals; see Section 4.1.2. These limits SHOULD be large | |||
enough to process the largest individual field the HTTP | enough to process the largest individual field the HTTP | |||
implementation can be configured to accept. | implementation can be configured to accept. | |||
If an implementation encounters a value larger than it is able to | If an implementation encounters a value larger than it is able to | |||
decode, this MUST be treated as a stream error of type | decode, this MUST be treated as a stream error of type | |||
QPACK_DECOMPRESSION_FAILED if on a request stream, or a connection | QPACK_DECOMPRESSION_FAILED if on a request stream or a connection | |||
error of the appropriate type if on the encoder or decoder stream. | error of the appropriate type if on the encoder or decoder stream. | |||
8. IANA Considerations | 8. IANA Considerations | |||
This document makes multiple registrations in the registries defined | ||||
by [HTTP/3]. The allocations created by this document are all | ||||
assigned permanent status and list a change controller of the IETF | ||||
and a contact of the HTTP working group (ietf-http-wg@w3.org). | ||||
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 | |||
[HTTP3]. | [HTTP/3]. | |||
+==========================+======+===============+=========+ | +==========================+======+===============+=========+ | |||
| Setting Name | Code | Specification | Default | | | Setting Name | Code | Specification | Default | | |||
+==========================+======+===============+=========+ | +==========================+======+===============+=========+ | |||
| QPACK_MAX_TABLE_CAPACITY | 0x1 | Section 5 | 0 | | | QPACK_MAX_TABLE_CAPACITY | 0x01 | Section 5 | 0 | | |||
+--------------------------+------+---------------+---------+ | +--------------------------+------+---------------+---------+ | |||
| QPACK_BLOCKED_STREAMS | 0x7 | Section 5 | 0 | | | QPACK_BLOCKED_STREAMS | 0x07 | Section 5 | 0 | | |||
+--------------------------+------+---------------+---------+ | +--------------------------+------+---------------+---------+ | |||
Table 1 | Table 1: Additions to the HTTP/3 Settings Registry | |||
For fomatting reasons, the setting names here are abbreviated by | For formatting reasons, the setting names here are abbreviated by | |||
removing the 'SETTING_' prefix. | removing the 'SETTINGS_' prefix. | |||
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 Types" registry | |||
established in [HTTP3]. | established in [HTTP/3]. | |||
+======================+======+===============+========+ | +======================+======+===============+========+ | |||
| Stream Type | Code | Specification | Sender | | | Stream Type | Code | Specification | Sender | | |||
+======================+======+===============+========+ | +======================+======+===============+========+ | |||
| QPACK Encoder Stream | 0x02 | Section 4.2 | Both | | | QPACK Encoder Stream | 0x02 | Section 4.2 | Both | | |||
+----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| QPACK Decoder Stream | 0x03 | Section 4.2 | Both | | | QPACK Decoder Stream | 0x03 | Section 4.2 | Both | | |||
+----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
Table 2 | Table 2: Additions to the HTTP/3 Stream Types Registry | |||
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 Codes" registry | |||
established in [HTTP3]. | established in [HTTP/3]. | |||
+============================+=======+=============+===============+ | +============================+========+=============+===============+ | |||
| Name | Code | Description | Specification | | | Name | Code |Description | Specification | | |||
+============================+=======+=============+===============+ | +============================+========+=============+===============+ | |||
| QPACK_DECOMPRESSION_FAILED | 0x200 | Decoding of | Section 6 | | | QPACK_DECOMPRESSION_FAILED | 0x0200 |Decoding of a| Section 6 | | |||
| | | a field | | | | | |field section| | | |||
| | | section | | | | | |failed | | | |||
| | | failed | | | +----------------------------+--------+-------------+---------------+ | |||
+----------------------------+-------+-------------+---------------+ | | QPACK_ENCODER_STREAM_ERROR | 0x0201 |Error on the | Section 6 | | |||
| QPACK_ENCODER_STREAM_ERROR | 0x201 | Error on | Section 6 | | | | |encoder | | | |||
| | | the encoder | | | | | |stream | | | |||
| | | stream | | | +----------------------------+--------+-------------+---------------+ | |||
+----------------------------+-------+-------------+---------------+ | | QPACK_DECODER_STREAM_ERROR | 0x0202 |Error on the | Section 6 | | |||
| QPACK_DECODER_STREAM_ERROR | 0x202 | Error on | Section 6 | | | | |decoder | | | |||
| | | the decoder | | | | | |stream | | | |||
| | | stream | | | +----------------------------+--------+-------------+---------------+ | |||
+----------------------------+-------+-------------+---------------+ | ||||
Table 3 | Table 3: Additions to the HTTP/3 Error Codes Registry | |||
9. References | 9. References | |||
9.1. Normative References | 9.1. Normative References | |||
[HTTP3] Bishop, M., Ed., "Hypertext Transfer Protocol Version 3 | [HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
(HTTP/3)", Work in Progress, Internet-Draft, draft-ietf- | Ed., "HTTP Semantics", STD 97, RFC 9110, | |||
quic-http-34, 2 February 2021, | DOI 10.17487/RFC9110, June 2022, | |||
<https://tools.ietf.org/html/draft-ietf-quic-http-34>. | <https://www.rfc-editor.org/info/rfc9110>. | |||
[HTTP/3] Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, | ||||
June 2022, <https://www.rfc-editor.org/info/rfc9114>. | ||||
[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", Work in Progress, | Multiplexed and Secure Transport", RFC 9000, | |||
Internet-Draft, draft-ietf-quic-transport-34, 2 February | DOI 10.17487/RFC9000, May 2021, | |||
2021, <https://tools.ietf.org/html/draft-ietf-quic- | <https://www.rfc-editor.org/info/rfc9000>. | |||
transport-34>. | ||||
[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>. | |||
[RFC2360] Scott, G., "Guide for Internet Standards Writers", BCP 22, | [RFC2360] Scott, G., "Guide for Internet Standards Writers", BCP 22, | |||
RFC 2360, DOI 10.17487/RFC2360, June 1998, | RFC 2360, DOI 10.17487/RFC2360, June 1998, | |||
<https://www.rfc-editor.org/info/rfc2360>. | <https://www.rfc-editor.org/info/rfc2360>. | |||
[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>. | |||
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
[SEMANTICS] | ||||
Fielding, R., Nottingham, M., and J. Reschke, "HTTP | ||||
Semantics", Work in Progress, Internet-Draft, draft-ietf- | ||||
httpbis-semantics-14, 12 January 2021, | ||||
<http://www.ietf.org/internet-drafts/draft-ietf-httpbis- | ||||
semantics-14.txt>. | ||||
9.2. Informative References | 9.2. Informative References | |||
[CRIME] Wikipedia, "CRIME", May 2015, <http://en.wikipedia.org/w/ | [CRIME] Wikipedia, "CRIME", May 2015, <http://en.wikipedia.org/w/ | |||
index.php?title=CRIME&oldid=660948120>. | index.php?title=CRIME&oldid=660948120>. | |||
[HTTP/2] Thomson, M., Ed. and C. Benfield, Ed., "HTTP/2", RFC 9113, | ||||
DOI 10.17487/RFC9113, June 2022, | ||||
<https://www.rfc-editor.org/info/rfc9113>. | ||||
[PETAL] Tan, J. and J. Nahata, "PETAL: Preset Encoding | [PETAL] Tan, J. and J. Nahata, "PETAL: Preset Encoding | |||
Table Information Leakage", April 2013, | Table Information Leakage", April 2013, | |||
<http://www.pdl.cmu.edu/PDL-FTP/associated/CMU-PDL- | <http://www.pdl.cmu.edu/PDL-FTP/associated/CMU-PDL- | |||
13-106.pdf>. | 13-106.pdf>. | |||
[RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification | [RFC1951] Deutsch, P., "DEFLATE Compressed Data Format Specification | |||
version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996, | version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996, | |||
<https://www.rfc-editor.org/info/rfc1951>. | <https://www.rfc-editor.org/info/rfc1951>. | |||
[RFC6454] Barth, A., "The Web Origin Concept", RFC 6454, | [RFC6454] Barth, A., "The Web Origin Concept", RFC 6454, | |||
DOI 10.17487/RFC6454, December 2011, | DOI 10.17487/RFC6454, December 2011, | |||
<https://www.rfc-editor.org/info/rfc6454>. | <https://www.rfc-editor.org/info/rfc6454>. | |||
[RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | ||||
Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | ||||
DOI 10.17487/RFC7540, May 2015, | ||||
<https://www.rfc-editor.org/info/rfc7540>. | ||||
[TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | [TLS] Rescorla, E., "The Transport Layer Security (TLS) Protocol | |||
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018, | |||
<https://www.rfc-editor.org/info/rfc8446>. | <https://www.rfc-editor.org/info/rfc8446>. | |||
Appendix A. Static Table | Appendix A. Static Table | |||
This table was generated by analyzing actual Internet traffic in 2018 | This table was generated by analyzing actual Internet traffic in 2018 | |||
and including the most common header fields, after filtering out some | and including the most common header fields, after filtering out some | |||
unsupported and non-standard values. Due to this methodology, some | unsupported and non-standard values. Due to this methodology, some | |||
of the entries may be inconsistent or appear multiple times with | of the entries may be inconsistent or appear multiple times with | |||
skipping to change at page 40, line 36 ¶ | skipping to change at line 1811 ¶ | |||
+-------+----------------------------------+-----------------------+ | +-------+----------------------------------+-----------------------+ | |||
| 95 | user-agent | | | | 95 | user-agent | | | |||
+-------+----------------------------------+-----------------------+ | +-------+----------------------------------+-----------------------+ | |||
| 96 | x-forwarded-for | | | | 96 | x-forwarded-for | | | |||
+-------+----------------------------------+-----------------------+ | +-------+----------------------------------+-----------------------+ | |||
| 97 | x-frame-options | deny | | | 97 | x-frame-options | deny | | |||
+-------+----------------------------------+-----------------------+ | +-------+----------------------------------+-----------------------+ | |||
| 98 | x-frame-options | sameorigin | | | 98 | x-frame-options | sameorigin | | |||
+-------+----------------------------------+-----------------------+ | +-------+----------------------------------+-----------------------+ | |||
Table 4 | Table 4: Static Table | |||
Any line breaks that appear within field names or values are due to | Any line breaks that appear within field names or values are due to | |||
formatting. | formatting. | |||
Appendix B. Encoding and Decoding Examples | Appendix B. Encoding and Decoding Examples | |||
The following examples represent a series of exchanges between an | The following examples represent a series of exchanges between an | |||
encoder and a decoder. The exchanges are designed to exercise most | encoder and a decoder. The exchanges are designed to exercise most | |||
QPACK instructions, and highlight potentially common patterns and | QPACK instructions and highlight potentially common patterns and | |||
their impact on dynamic table state. The encoder sends three encoded | their impact on dynamic table state. The encoder sends three encoded | |||
field sections containing one field line each, as well as two | field sections containing one field line each, as well as two | |||
speculative inserts that are not referenced. | speculative inserts that are not referenced. | |||
The state of the encoder's dynamic table is shown, along with its | The state of the encoder's dynamic table is shown, along with its | |||
current size. Each entry is shown with the Absolute Index of the | current size. Each entry is shown with the Absolute Index of the | |||
entry (Abs), the current number of outstanding encoded field sections | entry (Abs), the current number of outstanding encoded field sections | |||
with references to that entry (Ref), along with the name and value. | with references to that entry (Ref), along with the name and value. | |||
Entries above the 'acknowledged' line have been acknowledged by the | Entries above the 'acknowledged' line have been acknowledged by the | |||
decoder. | decoder. | |||
B.1. Literal Field Line With Name Reference | B.1. Literal Field Line with Name Reference | |||
The encoder sends an encoded field section containing a literal | The encoder sends an encoded field section containing a literal | |||
representation of a field with a static name reference. | representation of a field with a static name reference. | |||
Data | Interpretation | Data | Interpretation | |||
| Encoder's Dynamic Table | | Encoder's Dynamic Table | |||
Stream: 0 | Stream: 0 | |||
0000 | Required Insert Count = 0, Base = 0 | 0000 | Required Insert Count = 0, Base = 0 | |||
510b 2f69 6e64 6578 | Literal Field Line with Name Reference | 510b 2f69 6e64 6578 | Literal Field Line with Name Reference | |||
skipping to change at page 44, line 8 ¶ | skipping to change at line 1937 ¶ | |||
The encoder duplicates an existing entry in the dynamic table, then | The encoder duplicates an existing entry in the dynamic table, then | |||
sends an encoded field section referencing the dynamic table entries | sends an encoded field section referencing the dynamic table entries | |||
including the duplicated entry. The packet containing the encoder | including the duplicated entry. The packet containing the encoder | |||
stream data is delayed. Before the packet arrives, the decoder | stream data is delayed. Before the packet arrives, the decoder | |||
cancels the stream and notifies the encoder that the encoded field | cancels the stream and notifies the encoder that the encoded field | |||
section was not processed. | section was not processed. | |||
Stream: Encoder | Stream: Encoder | |||
02 | Duplicate (Relative Index = 2) | 02 | Duplicate (Relative Index = 2) | |||
| Absolute Index = | | Absolute Index = | |||
| Insert Count(4) - Index(2) - 1 = 1 | | Insert Count(3) - Index(2) - 1 = 0 | |||
Abs Ref Name Value | Abs Ref Name Value | |||
0 0 :authority www.example.com | 0 0 :authority www.example.com | |||
1 0 :path /sample/path | 1 0 :path /sample/path | |||
2 0 custom-key custom-value | 2 0 custom-key custom-value | |||
^-- acknowledged --^ | ^-- acknowledged --^ | |||
3 0 :authority www.example.com | 3 0 :authority www.example.com | |||
Size=217 | Size=217 | |||
Stream: 8 | Stream: 8 | |||
skipping to change at page 44, line 45 ¶ | skipping to change at line 1974 ¶ | |||
Size=217 | Size=217 | |||
Stream: Decoder | Stream: Decoder | |||
48 | Stream Cancellation (Stream=8) | 48 | Stream Cancellation (Stream=8) | |||
Abs Ref Name Value | Abs Ref Name Value | |||
0 0 :authority www.example.com | 0 0 :authority www.example.com | |||
1 0 :path /sample/path | 1 0 :path /sample/path | |||
2 0 custom-key custom-value | 2 0 custom-key custom-value | |||
^-- acknowledged --^ | ^-- acknowledged --^ | |||
4 0 :authority www.example.com | 3 0 :authority www.example.com | |||
Size=217 | Size=217 | |||
B.5. Dynamic Table Insert, Eviction | B.5. Dynamic Table Insert, Eviction | |||
The encoder inserts another header into the dynamic table, which | The encoder inserts another header into the dynamic table, which | |||
evicts the oldest entry. The encoder does not send any encoded field | evicts the oldest entry. The encoder does not send any encoded field | |||
sections. | sections. | |||
Stream: Encoder | Stream: Encoder | |||
810d 6375 7374 6f6d | Insert With Name Reference | 810d 6375 7374 6f6d | Insert With Name Reference | |||
skipping to change at page 45, line 20 ¶ | skipping to change at line 1998 ¶ | |||
| (custom-key=custom-value2) | | (custom-key=custom-value2) | |||
Abs Ref Name Value | Abs Ref Name Value | |||
1 0 :path /sample/path | 1 0 :path /sample/path | |||
2 0 custom-key custom-value | 2 0 custom-key custom-value | |||
^-- acknowledged --^ | ^-- acknowledged --^ | |||
3 0 :authority www.example.com | 3 0 :authority www.example.com | |||
4 0 custom-key custom-value2 | 4 0 custom-key custom-value2 | |||
Size=215 | Size=215 | |||
Appendix C. Sample One Pass Encoding Algorithm | Appendix C. Sample Single-Pass Encoding Algorithm | |||
Pseudo-code for single pass encoding, excluding handling of | Pseudocode for single-pass encoding, excluding handling of | |||
duplicates, non-blocking mode, available encoder stream flow control | duplicates, non-blocking mode, available encoder stream flow control | |||
and reference tracking. | and reference tracking. | |||
# Helper functions: | # Helper functions: | |||
# ==== | # ==== | |||
# Encode an interger with the specified prefix and length | # Encode an integer with the specified prefix and length | |||
encodeInteger(buffer, prefix, value, prefixLength) | encodeInteger(buffer, prefix, value, prefixLength) | |||
# Encode a dynamic table insert instruction with optional static | # Encode a dynamic table insert instruction with optional static | |||
# or dynamic name index (but not both) | # or dynamic name index (but not both) | |||
encodeInsert(buffer, staticNameIndex, dynamicNameIndex, fieldLine) | encodeInsert(buffer, staticNameIndex, dynamicNameIndex, fieldLine) | |||
# Encode a static index reference | # Encode a static index reference | |||
encodeStaticIndexReference(buffer, staticIndex) | encodeStaticIndexReference(buffer, staticIndex) | |||
# Encode a dynamic index reference relative to base | # Encode a dynamic index reference relative to Base | |||
encodeDynamicIndexReference(buffer, dynamicIndex, base) | encodeDynamicIndexReference(buffer, dynamicIndex, base) | |||
# Encode a literal with an optional static name index | # Encode a literal with an optional static name index | |||
encodeLiteral(buffer, staticNameIndex, fieldLine) | encodeLiteral(buffer, staticNameIndex, fieldLine) | |||
# Encode a literal with a dynamic name index relative to base | # Encode a literal with a dynamic name index relative to Base | |||
encodeDynamicLiteral(buffer, dynamicNameIndex, base, fieldLine) | encodeDynamicLiteral(buffer, dynamicNameIndex, base, fieldLine) | |||
# Encoding Algorithm | # Encoding Algorithm | |||
# ==== | # ==== | |||
base = dynamicTable.getInsertCount() | base = dynamicTable.getInsertCount() | |||
requiredInsertCount = 0 | requiredInsertCount = 0 | |||
for line in fieldLines: | for line in fieldLines: | |||
staticIndex = staticTable.findIndex(line) | staticIndex = staticTable.findIndex(line) | |||
if staticIndex is not None: | if staticIndex is not None: | |||
encodeStaticIndexReference(streamBuffer, staticIndex) | encodeStaticIndexReference(streamBuffer, staticIndex) | |||
skipping to change at page 46, line 23 ¶ | skipping to change at line 2050 ¶ | |||
dynamicNameIndex = dynamicTable.findName(line.name) | dynamicNameIndex = dynamicTable.findName(line.name) | |||
if shouldIndex(line) and dynamicTable.canIndex(line): | if shouldIndex(line) and dynamicTable.canIndex(line): | |||
encodeInsert(encoderBuffer, staticNameIndex, | encodeInsert(encoderBuffer, staticNameIndex, | |||
dynamicNameIndex, line) | dynamicNameIndex, line) | |||
dynamicIndex = dynamicTable.add(line) | dynamicIndex = dynamicTable.add(line) | |||
if dynamicIndex is None: | if dynamicIndex is None: | |||
# Could not index it, literal | # Could not index it, literal | |||
if dynamicNameIndex is not None: | if dynamicNameIndex is not None: | |||
# Encode literal with dynamic name, possibly above base | # Encode literal with dynamic name, possibly above Base | |||
encodeDynamicLiteral(streamBuffer, dynamicNameIndex, | encodeDynamicLiteral(streamBuffer, dynamicNameIndex, | |||
base, line) | base, line) | |||
requiredInsertCount = max(requiredInsertCount, | requiredInsertCount = max(requiredInsertCount, | |||
dynamicNameIndex) | dynamicNameIndex) | |||
else: | else: | |||
# Encodes a literal with a static name or literal name | # Encodes a literal with a static name or literal name | |||
encodeLiteral(streamBuffer, staticNameIndex, line) | encodeLiteral(streamBuffer, staticNameIndex, line) | |||
else: | else: | |||
# Dynamic index reference | # Dynamic index reference | |||
assert(dynamicIndex is not None) | assert(dynamicIndex is not None) | |||
requiredInsertCount = max(requiredInsertCount, dynamicIndex) | requiredInsertCount = max(requiredInsertCount, dynamicIndex) | |||
# Encode dynamicIndex, possibly above base | # Encode dynamicIndex, possibly above Base | |||
encodeDynamicIndexReference(streamBuffer, dynamicIndex, base) | encodeDynamicIndexReference(streamBuffer, dynamicIndex, base) | |||
# encode the prefix | # encode the prefix | |||
if requiredInsertCount == 0: | if requiredInsertCount == 0: | |||
encodeInteger(prefixBuffer, 0x00, 0, 8) | encodeInteger(prefixBuffer, 0x00, 0, 8) | |||
encodeInteger(prefixBuffer, 0x00, 0, 7) | encodeInteger(prefixBuffer, 0x00, 0, 7) | |||
else: | else: | |||
wireRIC = ( | wireRIC = ( | |||
requiredInsertCount | requiredInsertCount | |||
% (2 * getMaxEntries(maxTableCapacity)) | % (2 * getMaxEntries(maxTableCapacity)) | |||
skipping to change at page 47, line 4 ¶ | skipping to change at line 2079 ¶ | |||
else: | else: | |||
wireRIC = ( | wireRIC = ( | |||
requiredInsertCount | requiredInsertCount | |||
% (2 * getMaxEntries(maxTableCapacity)) | % (2 * getMaxEntries(maxTableCapacity)) | |||
) + 1; | ) + 1; | |||
encodeInteger(prefixBuffer, 0x00, wireRIC, 8) | encodeInteger(prefixBuffer, 0x00, wireRIC, 8) | |||
if base >= requiredInsertCount: | if base >= requiredInsertCount: | |||
encodeInteger(prefixBuffer, 0x00, | encodeInteger(prefixBuffer, 0x00, | |||
base - requiredInsertCount, 7) | base - requiredInsertCount, 7) | |||
else: | else: | |||
encodeInteger(prefixBuffer, 0x80, | encodeInteger(prefixBuffer, 0x80, | |||
requiredInsertCount - base - 1, 7) | requiredInsertCount - base - 1, 7) | |||
return encoderBuffer, prefixBuffer + streamBuffer | return encoderBuffer, prefixBuffer + streamBuffer | |||
Appendix D. Change Log | ||||
*RFC Editor's Note:* Please remove this section prior to | ||||
publication of a final version of this document. | ||||
D.1. Since draft-ietf-quic-qpack-19 | ||||
Editorial changes only | ||||
D.2. Since draft-ietf-quic-qpack-18 | ||||
Editorial changes only | ||||
D.3. Since draft-ietf-quic-qpack-17 | ||||
Editorial changes only | ||||
D.4. Since draft-ietf-quic-qpack-16 | ||||
Editorial changes only | ||||
D.5. Since draft-ietf-quic-qpack-15 | ||||
No changes | ||||
D.6. Since draft-ietf-quic-qpack-14 | ||||
Added security considerations | ||||
D.7. Since draft-ietf-quic-qpack-13 | ||||
No changes | ||||
D.8. Since draft-ietf-quic-qpack-12 | ||||
Editorial changes only | ||||
D.9. Since draft-ietf-quic-qpack-11 | ||||
Editorial changes only | ||||
D.10. Since draft-ietf-quic-qpack-10 | ||||
Editorial changes only | ||||
D.11. Since draft-ietf-quic-qpack-09 | ||||
* Decoders MUST emit Header Acknowledgments (#2939) | ||||
* Updated error code for multiple encoder or decoder streams (#2970) | ||||
* Added explicit defaults for new SETTINGS (#2974) | ||||
D.12. Since draft-ietf-quic-qpack-08 | ||||
* Endpoints are permitted to create encoder and decoder streams even | ||||
if they can't use them (#2100, #2529) | ||||
* Maximum values for settings removed (#2766, #2767) | ||||
D.13. Since draft-ietf-quic-qpack-06 | ||||
* Clarify initial dynamic table capacity maximums (#2276, #2330, | ||||
#2330) | ||||
D.14. Since draft-ietf-quic-qpack-05 | ||||
* Introduced the terms dynamic table capacity and maximum dynamic | ||||
table capacity. | ||||
* Renamed SETTINGS_HEADER_TABLE_SIZE to | ||||
SETTINGS_QPACK_MAX_TABLE_CAPACITY. | ||||
D.15. Since draft-ietf-quic-qpack-04 | ||||
* Changed calculation of Delta Base Index to avoid an illegal value | ||||
(#2002, #2005) | ||||
D.16. Since draft-ietf-quic-qpack-03 | ||||
* Change HTTP settings defaults (#2038) | ||||
* Substantial editorial reorganization | ||||
D.17. Since draft-ietf-quic-qpack-02 | ||||
* Largest Reference encoded modulo MaxEntries (#1763) | ||||
* New Static Table (#1355) | ||||
* Table Size Update with Insert Count=0 is a connection error | ||||
(#1762) | ||||
* Stream Cancellations are optional when | ||||
SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | ||||
* Implementations must handle 62 bit integers (#1760) | ||||
* Different error types for each QPACK stream, other changes to | ||||
error handling (#1726) | ||||
* Preserve header field order (#1725) | ||||
* Initial table size is the maximum permitted when table is first | ||||
usable (#1642) | ||||
D.18. Since draft-ietf-quic-qpack-01 | ||||
* Only header blocks that reference the dynamic table are | ||||
acknowledged (#1603, #1605) | ||||
D.19. Since draft-ietf-quic-qpack-00 | ||||
* Renumbered instructions for consistency (#1471, #1472) | ||||
* Decoder is allowed to validate largest reference (#1404, #1469) | ||||
* Header block acknowledgments also acknowledge the associated | ||||
largest reference (#1370, #1400) | ||||
* Added an acknowledgment for unread streams (#1371, #1400) | ||||
* Removed framing from encoder stream (#1361,#1467) | ||||
* Control streams use typed unidirectional streams rather than fixed | ||||
stream IDs (#910,#1359) | ||||
D.20. Since draft-ietf-quic-qcram-00 | ||||
* Separate instruction sets for table updates and header blocks | ||||
(#1235, #1142, #1141) | ||||
* Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125, | ||||
#1314) | ||||
* Added mechanisms that support one-pass encoding (#1138, #1320) | ||||
* Added a setting to control the number of blocked decoders (#238, | ||||
#1140, #1143) | ||||
* Moved table updates and acknowledgments to dedicated streams | ||||
(#1121, #1122, #1238) | ||||
Acknowledgments | Acknowledgments | |||
The IETF QUIC Working Group received an enormous amount of support | The IETF QUIC Working Group received an enormous amount of support | |||
from many people. | from many people. | |||
The compression design team did substantial work exploring the | The compression design team did substantial work exploring the | |||
problem space and influencing the initial draft. The contributions | problem space and influencing the initial draft version of this | |||
of design team members Roberto Peon, Martin Thomson, and Dmitri | document. The contributions of design team members Roberto Peon, | |||
Tikhonov are gratefully acknowledged. | Martin Thomson, and Dmitri Tikhonov are gratefully acknowledged. | |||
The following people also provided substantial contributions to this | The following people also provided substantial contributions to this | |||
document: | document: | |||
* Bence Beky | * Bence Beky | |||
* Alessandro Ghedini | * Alessandro Ghedini | |||
* Ryan Hamilton | * Ryan Hamilton | |||
* Robin Marx | * Robin Marx | |||
* Patrick McManus | * Patrick McManus | |||
* 奥 一穂 (Kazuho Oku) | * 奥 一穂 (Kazuho Oku) | |||
* Lucas Pardue | * Lucas Pardue | |||
* Biren Roy | * Biren Roy | |||
* Ian Swett | * Ian Swett | |||
This draft draws heavily on the text of [RFC7541]. The indirect | This document draws heavily on the text of [RFC7541]. The indirect | |||
input of those authors is also gratefully acknowledged. | input of those authors is also gratefully acknowledged. | |||
Buck's contribution was supported by Google during his employment | Buck Krasic's contribution was supported by Google during his | |||
there. | employment there. | |||
A portion of Mike's contribution was supported by Microsoft during | A portion of Mike Bishop's contribution was supported by Microsoft | |||
his employment there. | during his employment there. | |||
Authors' Addresses | Authors' Addresses | |||
Charles 'Buck' Krasic | ||||
Netflix | ||||
Email: ckrasic@netflix.com | Charles 'Buck' Krasic | |||
Email: krasic@acm.org | ||||
Mike Bishop | Mike Bishop | |||
Akamai Technologies | Akamai Technologies | |||
Email: mbishop@evequefou.be | Email: mbishop@evequefou.be | |||
Alan Frindell (editor) | Alan Frindell (editor) | |||
Email: afrind@fb.com | Email: afrind@fb.com | |||
End of changes. 136 change blocks. | ||||
485 lines changed or deleted | 302 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |