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.
Facebook Facebook
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)
Facebook Facebook
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/