draft-ietf-quic-qpack-06.txt   draft-ietf-quic-qpack-07.txt 
QUIC C. Krasic QUIC C. Krasic
Internet-Draft Netflix Internet-Draft Netflix
Intended status: Standards Track M. Bishop Intended status: Standards Track M. Bishop
Expires: July 27, 2019 Akamai Technologies Expires: September 12, 2019 Akamai Technologies
A. Frindell, Ed. A. Frindell, Ed.
Facebook Facebook
January 23, 2019 March 11, 2019
QPACK: Header Compression for HTTP over QUIC QPACK: Header Compression for HTTP over QUIC
draft-ietf-quic-qpack-06 draft-ietf-quic-qpack-07
Abstract Abstract
This specification defines QPACK, a compression format for This specification defines QPACK, a compression format for
efficiently representing HTTP header fields, to be used in HTTP/3. efficiently representing HTTP header fields, to be used in HTTP/3.
This is a variation of HPACK header compression that seeks to reduce This is a variation of HPACK header compression that seeks to reduce
head-of-line blocking. head-of-line blocking.
Note to Readers Note to Readers
skipping to change at page 1, line 46 skipping to change at page 1, line 46
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on July 27, 2019. This Internet-Draft will expire on September 12, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2019 IETF Trust and the persons identified as the Copyright (c) 2019 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 32 skipping to change at page 2, line 32
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Conventions and Definitions . . . . . . . . . . . . . . . 4 1.1. Conventions and Definitions . . . . . . . . . . . . . . . 4
1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5
2. Compression Process Overview . . . . . . . . . . . . . . . . 5 2. Compression Process Overview . . . . . . . . . . . . . . . . 5
2.1. Encoder . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.1. Encoder . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1.1. Reference Tracking . . . . . . . . . . . . . . . . . 6 2.1.1. Reference Tracking . . . . . . . . . . . . . . . . . 6
2.1.2. Blocked Dynamic Table Insertions . . . . . . . . . . 6 2.1.2. Blocked Dynamic Table Insertions . . . . . . . . . . 6
2.1.3. Avoiding Head-of-Line Blocking . . . . . . . . . . . 7 2.1.3. Avoiding Head-of-Line Blocking . . . . . . . . . . . 7
2.1.4. Known Received Count . . . . . . . . . . . . . . . . 8 2.1.4. Known Received Count . . . . . . . . . . . . . . . . 8
2.2. Decoder . . . . . . . . . . . . . . . . . . . . . . . . . 8 2.2. Decoder . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.2.1. State Synchronization . . . . . . . . . . . . . . . . 8 2.2.1. State Synchronization . . . . . . . . . . . . . . . . 9
2.2.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 9 2.2.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 9
3. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 9 3. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 9 3.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 9
3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 10 3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 10
3.2.1. Dynamic Table Size . . . . . . . . . . . . . . . . . 10 3.2.1. Dynamic Table Size . . . . . . . . . . . . . . . . . 10
3.2.2. Dynamic Table Capacity and Eviction . . . . . . . . . 10 3.2.2. Dynamic Table Capacity and Eviction . . . . . . . . . 10
3.2.3. Maximum Dynamic Table Capacity . . . . . . . . . . . 11 3.2.3. Maximum Dynamic Table Capacity . . . . . . . . . . . 11
3.2.4. Initial Dynamic Table Capacity . . . . . . . . . . . 11 3.2.4. Absolute Indexing . . . . . . . . . . . . . . . . . . 12
3.2.5. Absolute Indexing . . . . . . . . . . . . . . . . . . 11 3.2.5. Relative Indexing . . . . . . . . . . . . . . . . . . 12
3.2.6. Relative Indexing . . . . . . . . . . . . . . . . . . 11 3.2.6. Post-Base Indexing . . . . . . . . . . . . . . . . . 13
3.2.7. Post-Base Indexing . . . . . . . . . . . . . . . . . 12 3.2.7. Invalid References . . . . . . . . . . . . . . . . . 13
3.2.8. Invalid References . . . . . . . . . . . . . . . . . 13 4. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 14
4. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 13 4.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 14
4.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 13 4.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 14
4.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 13 4.1.2. String Literals . . . . . . . . . . . . . . . . . . . 14
4.1.2. String Literals . . . . . . . . . . . . . . . . . . . 13 4.2. Instructions . . . . . . . . . . . . . . . . . . . . . . 14
4.2. Stream Types . . . . . . . . . . . . . . . . . . . . . . 14 4.2.1. Encoder and Decoder Streams . . . . . . . . . . . . . 15
4.3. Encoder Stream . . . . . . . . . . . . . . . . . . . . . 14 4.3. Encoder Instructions . . . . . . . . . . . . . . . . . . 15
4.3.1. Insert With Name Reference . . . . . . . . . . . . . 15 4.3.1. Insert With Name Reference . . . . . . . . . . . . . 15
4.3.2. Insert Without Name Reference . . . . . . . . . . . . 15 4.3.2. Insert Without Name Reference . . . . . . . . . . . . 16
4.3.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 16 4.3.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 16
4.3.4. Set Dynamic Table Capacity . . . . . . . . . . . . . 16 4.3.4. Set Dynamic Table Capacity . . . . . . . . . . . . . 17
4.4. Decoder Stream . . . . . . . . . . . . . . . . . . . . . 17 4.4. Decoder Instructions . . . . . . . . . . . . . . . . . . 17
4.4.1. Insert Count Increment . . . . . . . . . . . . . . . 17 4.4.1. Insert Count Increment . . . . . . . . . . . . . . . 17
4.4.2. Header Acknowledgement . . . . . . . . . . . . . . . 18 4.4.2. Header Acknowledgement . . . . . . . . . . . . . . . 18
4.4.3. Stream Cancellation . . . . . . . . . . . . . . . . . 18 4.4.3. Stream Cancellation . . . . . . . . . . . . . . . . . 19
4.5. Request and Push Streams . . . . . . . . . . . . . . . . 19 4.5. Header Block Instructions . . . . . . . . . . . . . . . . 19
4.5.1. Header Block Prefix . . . . . . . . . . . . . . . . . 19 4.5.1. Header Block Prefix . . . . . . . . . . . . . . . . . 20
4.5.2. Indexed Header Field . . . . . . . . . . . . . . . . 21 4.5.2. Indexed Header Field . . . . . . . . . . . . . . . . 22
4.5.3. Indexed Header Field With Post-Base Index . . . . . . 22 4.5.3. Indexed Header Field With Post-Base Index . . . . . . 23
4.5.4. Literal Header Field With Name Reference . . . . . . 22 4.5.4. Literal Header Field With Name Reference . . . . . . 23
4.5.5. Literal Header Field With Post-Base Name Reference . 23 4.5.5. Literal Header Field With Post-Base Name Reference . 24
4.5.6. Literal Header Field Without Name Reference . . . . . 23 4.5.6. Literal Header Field Without Name Reference . . . . . 24
5. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 24 5. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 25
6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 24 6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 25
7. Security Considerations . . . . . . . . . . . . . . . . . . . 25 7. Security Considerations . . . . . . . . . . . . . . . . . . . 26
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 25 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26
8.1. Settings Registration . . . . . . . . . . . . . . . . . . 25 8.1. Settings Registration . . . . . . . . . . . . . . . . . . 26
8.2. Stream Type Registration . . . . . . . . . . . . . . . . 25 8.2. Stream Type Registration . . . . . . . . . . . . . . . . 26
8.3. Error Code Registration . . . . . . . . . . . . . . . . . 25 8.3. Error Code Registration . . . . . . . . . . . . . . . . . 26
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 26 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 27
9.1. Normative References . . . . . . . . . . . . . . . . . . 26 9.1. Normative References . . . . . . . . . . . . . . . . . . 27
9.2. Informative References . . . . . . . . . . . . . . . . . 27 9.2. Informative References . . . . . . . . . . . . . . . . . 28
9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 27 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 27 Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 28
Appendix B. Sample One Pass Encoding Algorithm . . . . . . . . . 32 Appendix B. Sample One Pass Encoding Algorithm . . . . . . . . . 33
Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 34 Appendix C. Change Log . . . . . . . . . . . . . . . . . . . . . 35
C.1. Since draft-ietf-quic-qpack-05 . . . . . . . . . . . . . 34 C.1. Since draft-ietf-quic-qpack-06 . . . . . . . . . . . . . 35
C.2. Since draft-ietf-quic-qpack-04 . . . . . . . . . . . . . 34 C.2. Since draft-ietf-quic-qpack-05 . . . . . . . . . . . . . 35
C.3. Since draft-ietf-quic-qpack-03 . . . . . . . . . . . . . 34 C.3. Since draft-ietf-quic-qpack-04 . . . . . . . . . . . . . 35
C.4. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 34 C.4. Since draft-ietf-quic-qpack-03 . . . . . . . . . . . . . 35
C.5. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 35 C.5. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 35
C.6. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 35 C.6. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 36
C.7. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 35 C.7. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 36
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 35 C.8. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 36
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 36 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 36
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37
1. Introduction 1. Introduction
The QUIC transport protocol was designed from the outset to support The QUIC transport protocol was designed from the outset to support
HTTP semantics, and its design subsumes many of the features of HTTP semantics, and its design subsumes many of the features of
HTTP/2. HTTP/2 uses HPACK ([RFC7541]) for header compression, but HTTP/2. HTTP/2 uses HPACK ([RFC7541]) for header compression, but
QUIC's stream multiplexing comes into some conflict with HPACK. A QUIC's stream multiplexing comes into some conflict with HPACK. A
key goal of the design of QUIC is to improve stream multiplexing key goal of the design of QUIC is to improve stream multiplexing
relative to HTTP/2 by reducing head-of-line blocking. If HPACK were relative to HTTP/2 by reducing head-of-line blocking. If HPACK were
used for HTTP/3, it would induce head-of-line blocking due to built- used for HTTP/3, it would induce head-of-line blocking due to built-
skipping to change at page 6, line 22 skipping to change at page 6, line 22
2.1.1. Reference Tracking 2.1.1. Reference Tracking
An encoder MUST ensure that a header block which references a dynamic An encoder MUST ensure that a header block which references a dynamic
table entry is not received by the decoder after the referenced entry table entry is not received by the decoder after the referenced entry
has been evicted. Hence the encoder needs to track information about has been evicted. Hence the encoder needs to track information about
each compressed header block that references the dynamic table until each compressed header block that references the dynamic table until
that header block is acknowledged by the decoder. that header block is acknowledged by the decoder.
2.1.2. Blocked Dynamic Table Insertions 2.1.2. Blocked Dynamic Table Insertions
A dynamic table entry is considered blocking and cannot be evicted
until its insertion has been acknowledged and there are no
outstanding unacknowledged references to the entry. In particular, a
dynamic table entry that has never been referenced can still be
blocking.
Note: A blocking entry is unrelated to a blocked stream, which is a
stream that a decoder cannot decode as a result of references to
entries that are not yet available. Any encoder that uses the
dynamic table has to keep track of blocked entries, whereas
blocked streams are optional.
An encoder MUST NOT insert an entry into the dynamic table (or An encoder MUST NOT insert an entry into the dynamic table (or
duplicate an existing entry) if doing so would evict an entry with duplicate an existing entry) if doing so would evict a blocking
unacknowledged references. For header blocks that might rely on the entry. In this case, the encoder can send literal representations of
newly added entry, the encoder can use a literal representation. header fields.
To ensure that the encoder is not prevented from adding new entries, To ensure that the encoder is not prevented from adding new entries,
the encoder can avoid referencing entries that are close to eviction. the encoder can avoid referencing entries that are close to eviction.
Rather than reference such an entry, the encoder can emit a Duplicate Rather than reference such an entry, the encoder can emit a Duplicate
instruction (see Section 4.3.3), and reference the duplicate instead. instruction (see Section 4.3.3), 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 unreferenced entries. To achieve that can be reclaimed by evicting non-blocking entries. To achieve
this, the encoder can maintain a draining index, which is the this, the encoder can maintain a draining index, which is the
smallest absolute index in the dynamic table that it will emit a smallest absolute index in the dynamic table that it will emit a
reference for. As new entries are inserted, the encoder increases reference for. As new entries are inserted, the encoder increases
the draining index to maintain the section of the table that it will the draining index to maintain the section of the table that it will
not reference. If the encoder does not create new references to not reference. If the encoder does not create new references to
entries with an absolute index lower than the draining index, the entries with an absolute index lower than the draining index, the
number of unacknowledged references to those entries will eventually number of unacknowledged references to those entries will eventually
become zero, allowing them to be evicted. become zero, allowing them to be evicted.
+----------+---------------------------------+--------+ +----------+---------------------------------+--------+
skipping to change at page 7, line 24 skipping to change at page 7, line 27
Figure 1: Draining Dynamic Table Entries Figure 1: Draining Dynamic Table Entries
2.1.3. Avoiding Head-of-Line Blocking 2.1.3. Avoiding Head-of-Line Blocking
Because QUIC does not guarantee order between data on different Because QUIC does not guarantee order between data on different
streams, a header block might reference an entry in the dynamic table streams, a header block might reference an entry in the dynamic table
that has not yet been received. that has not yet been received.
Each header block contains a Required Insert Count, the lowest Each header block contains a Required Insert Count, the lowest
possible value for the Insert Count with which the header block can possible value for the Insert Count with which the header block can
be decoded. For a header block with no references to the dynamic be decoded. For a header block with references to the dynamic table,
table, the Required Insert Count is zero. the Required Insert Count is one larger than the largest Absolute
Index of all referenced dynamic table entries. For a header block
with no references to the dynamic table, the Required Insert Count is
zero.
If the decoder encounters a header block with a Required Insert Count
value larger than defined above, it MAY treat this as a stream error
of type HTTP_QPACK_DECOMPRESSION_FAILED. If the decoder encounters a
header block with a Required Insert Count value smaller than defined
above, it MUST treat this as a stream error of type
HTTP_QPACK_DECOMPRESSION_FAILED as prescribed in Section 3.2.7.
When the Required Insert Count is zero, the frame contains no When the Required Insert Count is zero, the frame contains no
references to the dynamic table and can always be processed references to the dynamic table and can always be processed
immediately. immediately.
If the Required Insert Count is greater than the number of dynamic If the Required Insert Count is greater than the number of dynamic
table entries received, the stream is considered "blocked." While table entries received, the stream is considered "blocked." While
blocked, header field data SHOULD remain in the blocked stream's flow blocked, header field data SHOULD remain in the blocked stream's flow
control window. A stream becomes unblocked when the Insert Count control window. A stream becomes unblocked when the Insert Count
becomes greater than or equal to the Required Insert Count for all becomes greater than or equal to the Required Insert Count for all
header blocks the decoder has started reading from the stream. header blocks the decoder has started reading from the stream.
If the decoder encounters a header block where the largest Absolute
Index used is not equal to the largest value permitted by the
Required Insert Count, it MAY treat this as a stream error of type
HTTP_QPACK_DECOMPRESSION_FAILED.
The SETTINGS_QPACK_BLOCKED_STREAMS setting (see Section 5) specifies The SETTINGS_QPACK_BLOCKED_STREAMS setting (see Section 5) specifies
an upper bound on the number of streams which can be blocked. An an upper bound on the number of streams which can be blocked. An
encoder MUST limit the number of streams which could become blocked encoder MUST limit the number of streams which could become blocked
to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. Note to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. Note
that the decoder might not actually become blocked on every stream that the decoder might not actually become blocked on every stream
which risks becoming blocked. If the decoder encounters more blocked which risks becoming blocked. If the decoder encounters more blocked
streams than it promised to support, it MUST treat this as a stream streams than it promised to support, it MUST treat this as a stream
error of type HTTP_QPACK_DECOMPRESSION_FAILED. error of type HTTP_QPACK_DECOMPRESSION_FAILED.
An encoder can decide whether to risk having a stream become blocked. An encoder can decide whether to risk having a stream become blocked.
skipping to change at page 8, line 35 skipping to change at page 8, line 44
To acknowledge dynamic table entries which are not referenced by To acknowledge dynamic table entries which are not referenced by
header blocks, for example because the encoder or the decoder have header blocks, for example because the encoder or the decoder have
chosen not to risk blocked streams, the decoder sends an Insert Count chosen not to risk blocked streams, the decoder sends an Insert Count
Increment instruction (see Section 4.4.1). Increment instruction (see Section 4.4.1).
2.2. Decoder 2.2. Decoder
As in HPACK, the decoder processes header blocks and emits the As in HPACK, the decoder processes header blocks and emits the
corresponding header lists. It also processes dynamic table corresponding header lists. It also processes dynamic table
modifications from instructions on the encoder stream. modifications from encoder instructions received on the encoder
stream.
The decoder MUST emit header fields in the order their The decoder MUST emit header fields in the order their
representations appear in the input header block. representations appear in the input header block.
2.2.1. State Synchronization 2.2.1. State Synchronization
The decoder stream (Section 4.4) signals key events at the decoder The decoder instructions (Section 4.4) signal key events at the
that permit the encoder to track the decoder's state. These events decoder that permit the encoder to track the decoder's state. These
are: events are:
o Complete processing of a header block o Complete processing of a header block
o Abandonment of a stream which might have remaining header blocks o Abandonment of a stream which might have remaining header blocks
o Receipt of new dynamic table entries o Receipt of new dynamic table entries
Knowledge that a header block with references to the dynamic table Knowledge that a header block with references to the dynamic table
has been processed permits the encoder to evict entries to which no has been processed permits the encoder to evict entries to which no
unacknowledged references remain, regardless of whether those unacknowledged references remain (see Section 2.1.2). When a stream
references were potentially blocking (see Section 2.1.2). When a is reset or abandoned, the indication that these header blocks will
stream is reset or abandoned, the indication that these header blocks never be processed serves a similar function (see Section 4.4.3).
will never be processed serves a similar function; see Section 4.4.3.
The decoder chooses when to emit Insert Count Increment instructions The decoder chooses when to emit Insert Count Increment instructions
(see Section 4.4.1). Emitting an instruction after adding each new (see Section 4.4.1). Emitting an instruction after adding each new
dynamic table entry will provide the most timely feedback to the dynamic table entry will provide the most timely feedback to the
encoder, but could be redundant with other decoder feedback. By encoder, but could be redundant with other decoder feedback. By
delaying an Insert Count Increment instruction, the decoder might be delaying an Insert Count Increment instruction, the decoder might be
able to coalesce multiple Insert Count Increment instructions, or able to coalesce multiple Insert Count Increment instructions, or
replace them entirely with Header Acknowledgements (see replace them entirely with Header Acknowledgements (see
Section 4.4.2). However, delaying too long may lead to compression Section 4.4.2). 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
skipping to change at page 9, line 41 skipping to change at page 10, line 5
Unlike in HPACK, entries in the QPACK static and dynamic tables are Unlike in HPACK, entries in the QPACK static and dynamic tables are
addressed separately. The following sections describe how entries in addressed separately. The following sections describe how entries in
each table are addressed. each table are addressed.
3.1. Static Table 3.1. Static Table
The static table consists of a predefined static list of header The static table consists of a predefined static list of header
fields, each of which has a fixed index over time. Its entries are fields, each of which has a fixed index over time. Its entries are
defined in Appendix A. defined in Appendix A.
All entries in the static table have a name and a value. However,
values can be empty (that is, have a length of 0).
Note the QPACK static table is indexed from 0, whereas the HPACK Note the QPACK static table is indexed from 0, whereas the HPACK
static table is indexed from 1. static table is indexed from 1.
When the decoder encounters an invalid static table index on a When the decoder encounters an invalid static table index in a header
request stream or push stream it MUST treat this as a stream error of block instruction it MUST treat this as a stream error of type
type "HTTP_QPACK_DECOMPRESSION_FAILED". If this index is received on "HTTP_QPACK_DECOMPRESSION_FAILED". If this index is received on the
the encoder stream, this MUST be treated as a connection error of encoder stream, this MUST be treated as a connection error of type
type "HTTP_QPACK_ENCODER_STREAM_ERROR". "HTTP_QPACK_ENCODER_STREAM_ERROR".
3.2. Dynamic Table 3.2. Dynamic Table
The dynamic table consists of a list of header fields maintained in The dynamic table consists of a list of header fields maintained in
first-in, first-out order. The dynamic table is initially empty. first-in, first-out order. Each HTTP/3 endpoint holds a dynamic
Entries are added by instructions on the encoder stream (see table that is initially empty. Entries are added by encoder
Section 4.3). instructions received on the encoder stream (see Section 4.3).
The dynamic table can contain duplicate entries (i.e., entries with The dynamic table can contain duplicate entries (i.e., entries with
the same name and same value). Therefore, duplicate entries MUST NOT the same name and same value). Therefore, duplicate entries MUST NOT
be treated as an error by the decoder. be treated as an error by the decoder.
3.2.1. Dynamic Table Size 3.2.1. Dynamic Table Size
The size of the dynamic table is the sum of the size of its entries. The size of the dynamic table is the sum of the size of its entries.
The size of an entry is the sum of its name's length in bytes (as The size of an entry is the sum of its name's length in bytes (as
defined in Section 4.1.2), its value's length in bytes, and 32. defined in Section 4.1.2), its value's length in bytes, and 32.
The size of an entry is calculated using the length of its name and The size of an entry is calculated using the length of its name and
value without Huffman encoding applied. value without Huffman encoding applied.
3.2.2. Dynamic Table Capacity and Eviction 3.2.2. Dynamic Table Capacity and Eviction
The encoder sets the capacity of the dynamic table, which serves as The encoder sets the capacity of the dynamic table, which serves as
the upper limit on its size. the upper limit on its size. The initial capcity of the dynamic
table is zero.
Before a new entry is added to the dynamic table, entries are evicted Before a new entry is added to the dynamic table, entries are evicted
from the end of the dynamic table until the size of the dynamic table from the end of the dynamic table until the size of the dynamic table
is less than or equal to (table capacity - size of new entry) or is less than or equal to (table capacity - size of new entry) or
until the table is empty. The encoder MUST NOT evict a dynamic table until the table is empty. The encoder MUST NOT evict a blocking
entry unless it has first been acknowledged by the decoder. dynamic table entry (see Section 2.1.2).
If the size of the new entry is less than or equal to the dynamic If the size of the new entry is less than or equal to the dynamic
table capacity, then that entry is added to the table. It is an table capacity, then that entry is added to the table. It is an
error if the encoder attempts to add an entry that is larger than the error if the encoder attempts to add an entry that is larger than the
dynamic table capacity; the decoder MUST treat this as a connection dynamic table capacity; the decoder MUST treat this as a connection
error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". error of type "HTTP_QPACK_ENCODER_STREAM_ERROR".
A new entry can reference an entry in the dynamic table that will be A new entry can reference an entry in the dynamic table that will be
evicted when adding this new entry into the dynamic table. evicted when adding this new entry into the dynamic table.
Implementations are cautioned to avoid deleting the referenced name Implementations are cautioned to avoid deleting the referenced name
skipping to change at page 11, line 17 skipping to change at page 11, line 30
3.2.3. Maximum Dynamic Table Capacity 3.2.3. Maximum Dynamic Table Capacity
To bound the memory requirements of the decoder, the decoder limits To bound the memory requirements of the decoder, the decoder limits
the maximum value the encoder is permitted to set for the dynamic the maximum value the encoder is permitted to set for the dynamic
table capacity. In HTTP/3, this limit is determined by the value of table capacity. In HTTP/3, this limit is determined by the value of
SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder (see SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder (see
Section 5). The encoder MUST not set a dynamic table capacity that Section 5). The encoder MUST not set a dynamic table capacity that
exceeds this maximum, but it can choose to use a lower dynamic table exceeds this maximum, but it can choose to use a lower dynamic table
capacity (see Section 4.3.4). capacity (see Section 4.3.4).
3.2.4. Initial Dynamic Table Capacity 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
was not previously sent. When the client's 0-RTT value of the
SETTING is 0, the server MAY set it to a non-zero value in its
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
any other value, or omits SETTINGS_QPACK_MAX_TABLE_CAPACITY from
SETTINGS, the encoder must treat this as a connection error of type
"HTTP_QPACK_DECODER_STREAM_ERROR".
The initial dynamic table capacity is determined by the corresponding For HTTP/3 servers and HTTP/3 clients when 0-RTT is not attempted or
setting when HTTP requests or responses are first permitted to be is rejected, the maximum table capacity is 0 until the encoder
sent. For clients using 0-RTT data in HTTP/3, the initial table processes a SETTINGS frame with a non-zero value of
capacity is the remembered value of the setting, even if the server SETTINGS_QPACK_MAX_TABLE_CAPACITY.
later specifies a larger maximum dynamic table capacity in its
SETTINGS frame. For HTTP/3 servers and HTTP/3 clients when 0-RTT is
not attempted or is rejected, the initial table capacity is the value
of the setting in the peer's SETTINGS frame.
3.2.5. Absolute Indexing When the maximum table capacity is 0, the encoder MUST NOT insert
entries into the dynamic table, and MUST NOT send any encoder
instructions on the encoder stream.
3.2.4. Absolute Indexing
Each entry possesses both an absolute index which is fixed for the Each entry possesses both an absolute index which is fixed for the
lifetime of that entry and a relative index which changes based on lifetime of that entry and a relative index which changes based on
the context of the reference. The first entry inserted has an the context of the reference. The first entry inserted has an
absolute index of "0"; indices increase by one with each insertion. absolute index of "0"; indices increase by one with each insertion.
3.2.6. Relative Indexing 3.2.5. Relative Indexing
The relative index begins at zero and increases in the opposite The relative index begins at zero and increases in the opposite
direction from the absolute index. Determining which entry has a direction from the absolute index. Determining which entry has a
relative index of "0" depends on the context of the reference. relative index of "0" depends on the context of the reference.
On the encoder stream, a relative index of "0" always refers to the In encoder instructions, a relative index of "0" always refers to the
most recently inserted value in the dynamic table. Note that this most recently inserted value in the dynamic table. Note that this
means the entry referenced by a given relative index will change means the entry referenced by a given relative index will change
while interpreting instructions on the encoder stream. while interpreting instructions on the encoder stream.
+-----+---------------+-------+ +-----+---------------+-------+
| n-1 | ... | d | Absolute Index | n-1 | ... | d | Absolute Index
+ - - +---------------+ - - - + + - - +---------------+ - - - +
| 0 | ... | n-d-1 | Relative Index | 0 | ... | n-d-1 | Relative Index
+-----+---------------+-------+ +-----+---------------+-------+
^ | ^ |
| V | V
Insertion Point Dropping Point Insertion Point Dropping Point
n = count of entries inserted n = count of entries inserted
d = count of entries dropped d = count of entries dropped
Example Dynamic Table Indexing - Control Stream Example Dynamic Table Indexing - Control Stream
Unlike on the encoder stream, relative indices on push and request Unlike encoder instructions, relative indices in header block
streams are relative to the Base at the beginning of the header block instructions are relative to the Base at the beginning of the header
(see Section 4.5.1). This ensures that references are stable even if block (see Section 4.5.1). This ensures that references are stable
the dynamic table is updated while decoding a header block. even if the dynamic table is updated while decoding a header block.
The Base is encoded as a value relative to the Required Insert Count. The Base is encoded as a value relative to the Required Insert Count.
The Base identifies which dynamic table entries can be referenced The Base identifies which dynamic table entries can be referenced
using relative indexing, starting with 0 at the last entry added. using relative indexing, starting with 0 at the last entry added.
Post-Base references are used for entries inserted after base, Post-Base references are used for entries inserted after base,
starting at 0 for the first entry added after the Base, see starting at 0 for the first entry added after the Base, see
Section 3.2.7. Section 3.2.6.
Required Required
Insert Insert
Count Base Count Base
| | | |
V V V V
+-----+-----+-----+-----+-------+ +-----+-----+-----+-----+-------+
| n-1 | n-2 | n-3 | ... | d | Absolute Index | n-1 | n-2 | n-3 | ... | d | Absolute Index
+-----+-----+ - +-----+ - + +-----+-----+ - +-----+ - +
| 0 | ... | n-d-3 | Relative Index | 0 | ... | n-d-3 | Relative Index
+-----+-----+-------+ +-----+-----+-------+
n = count of entries inserted n = count of entries inserted
d = count of entries dropped d = count of entries dropped
Example Dynamic Table Indexing - Relative Index on Request Stream Example Dynamic Table Indexing - Relative Index in Header Block
3.2.7. Post-Base Indexing 3.2.6. Post-Base Indexing
A header block on the request stream can reference entries added A header block can reference entries added after the entry identified
after the entry identified by the Base. This allows an encoder to by the Base. This allows an encoder to process a header block in a
process a header block in a single pass and include references to single pass and include references to entries added while processing
entries added while processing this (or other) header blocks. Newly this (or other) header blocks. Newly added entries are referenced
added entries are referenced using Post-Base instructions. Indices using Post-Base instructions. Indices for Post-Base instructions
for Post-Base instructions increase in the same direction as absolute increase in the same direction as absolute indices, with the zero
indices, with the zero value being the first entry inserted after the value being the first entry inserted after the Base.
Base.
Base Base
| |
V V
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
| n-1 | n-2 | n-3 | ... | d | Absolute Index | n-1 | n-2 | n-3 | ... | d | Absolute Index
+-----+-----+-----+-----+-----+ +-----+-----+-----+-----+-----+
| 1 | 0 | Post-Base Index | 1 | 0 | Post-Base Index
+-----+-----+ +-----+-----+
n = count of entries inserted n = count of entries inserted
d = count of entries dropped d = count of entries dropped
Example Dynamic Table Indexing - Post-Base Index on Request Stream Example Dynamic Table Indexing - Post-Base Index in Header Block
3.2.8. Invalid References 3.2.7. Invalid References
If the decoder encounters a reference on a request or push stream to If the decoder encounters a reference in a header block instruction
a dynamic table entry which has already been evicted or which has an to a dynamic table entry which has already been evicted or which has
absolute index greater than or equal to the declared Required Insert an absolute index greater than or equal to the declared Required
Count (see Section 4.5.1), it MUST treat this as a stream error of Insert Count (see Section 4.5.1), it MUST treat this as a stream
type "HTTP_QPACK_DECOMPRESSION_FAILED". error of type "HTTP_QPACK_DECOMPRESSION_FAILED".
If the decoder encounters a reference on the encoder stream to a If the decoder encounters a reference in an encoder instruction to a
dynamic table entry which has already been dropped, it MUST treat dynamic table entry which has already been dropped, it MUST treat
this as a connection error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". this as a connection error of type "HTTP_QPACK_ENCODER_STREAM_ERROR".
4. Wire Format 4. Wire Format
4.1. Primitives 4.1. Primitives
4.1.1. Prefixed Integers 4.1.1. Prefixed Integers
The prefixed integer from Section 5.1 of [RFC7541] is used heavily The prefixed integer from Section 5.1 of [RFC7541] is used heavily
skipping to change at page 14, line 22 skipping to change at page 14, line 42
This document expands the definition of string literals and permits This document expands the definition of string literals and permits
them to begin other than on a byte boundary. An "N-bit prefix string them to begin other than on a byte boundary. An "N-bit prefix string
literal" begins with the same Huffman flag, followed by the length literal" begins with the same Huffman flag, followed by the length
encoded as an (N-1)-bit prefix integer. The remainder of the string encoded as an (N-1)-bit prefix integer. The remainder of the string
literal is unmodified. literal is unmodified.
A string literal without a prefix length noted is an 8-bit prefix A string literal without a prefix length noted is an 8-bit prefix
string literal and follows the definitions in [RFC7541] without string literal and follows the definitions in [RFC7541] without
modification. modification.
4.2. Stream Types 4.2. Instructions
QPACK instructions occur in three locations, each of which uses a There are three separate QPACK instruction spaces. Encoder
separate instruction space: instructions (Section 4.3) carry table updates, decoder instructions
(Section 4.4) carry acknowledgments of table modifications and header
processing, and header block instructions (Section 4.5) convey an
encoded representation of a header list by referring to the QPACK
table state.
o The encoder stream is a unidirectional stream of type "0x48" Encoder and decoder instructions appear on the unidirectional stream
(ASCII 'H') which carries table updates from encoder to decoder. types described in this section. Header block instructions are
contained in HEADERS and PUSH_PROMISE frames, which are conveyed on
request or push streams as described in [HTTP3].
o The decoder stream is a unidirectional stream of type "0x68" 4.2.1. Encoder and Decoder Streams
(ASCII 'h') which carries acknowledgements of table modifications
and header processing from decoder to encoder.
o Finally, the contents of HEADERS and PUSH_PROMISE frames on QPACK defines two unidirectional stream types:
request streams and push streams reference the QPACK table state.
There MUST be exactly one of each unidirectional stream type in each o An encoder stream is a unidirectional stream of type "0x02". It
direction. Receipt of a second instance of either stream type MUST carries an unframed sequence of encoder instructions from encoder
be treated as a connection error of HTTP_WRONG_STREAM_COUNT. These to decoder.
streams MUST NOT be closed. Closure of either unidirectional stream
MUST be treated as a connection error of type
HTTP_CLOSED_CRITICAL_STREAM.
This section describes the instructions which are possible on each o A decoder stream is a unidirectional stream of type "0x03". It
stream type. carries an unframed sequence of decoder instructions from decoder
to encoder.
4.3. Encoder Stream HTTP/3 endpoints contain a QPACK encoder and decoder. Each endpoint
MUST initiate a single encoder stream and decoder stream. Receipt of
a second instance of either stream type be MUST treated as a
connection error of type HTTP_WRONG_STREAM_COUNT. These streams MUST
NOT be closed. Closure of either unidirectional stream type MUST be
treated as a connection error of type HTTP_CLOSED_CRITICAL_STREAM.
4.3. Encoder Instructions
Table updates can add a table entry, possibly using existing entries Table updates can add a table entry, possibly using existing entries
to avoid transmitting redundant information. The name can be to avoid transmitting redundant information. The name can be
transmitted as a reference to an existing entry in the static or the transmitted as a reference to an existing entry in the static or the
dynamic table or as a string literal. For entries which already dynamic table or as a string literal. For entries which already
exist in the dynamic table, the full entry can also be used by exist in the dynamic table, the full entry can also be used by
reference, creating a duplicate entry. reference, creating a duplicate entry.
The contents of the encoder stream are an unframed sequence of the This section specifies the following encoder instructions.
following instructions.
4.3.1. Insert With Name Reference 4.3.1. Insert With Name Reference
An addition to the header table where the header field name matches An addition to the header table where the header field name matches
the header field name of an entry stored in the static table or the the header field name of an entry stored in the static table or the
dynamic table starts with the '1' one-bit pattern. The "S" bit dynamic table starts with the '1' one-bit pattern. The "S" bit
indicates whether the reference is to the static (S=1) or dynamic indicates whether the reference is to the static (S=1) or dynamic
(S=0) table. The 6-bit prefix integer (see Section 5.1 of [RFC7541]) (S=0) table. The 6-bit prefix integer (see Section 5.1 of [RFC7541])
that follows is used to locate the table entry for the header name. that follows is used to locate the table entry for the header name.
When S=1, the number represents the static table index; when S=0, the When S=1, the number represents the static table index; when S=0, the
skipping to change at page 17, line 10 skipping to change at page 17, line 30
Figure 3: Set Dynamic Table Capacity Figure 3: Set Dynamic Table Capacity
The new capacity MUST be lower than or equal to the limit described The new capacity MUST be lower than or equal to the limit described
in Section 3.2.3. In HTTP/3, this limit is the value of the in Section 3.2.3. In HTTP/3, this limit is the value of the
SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter (see Section 5) received SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter (see Section 5) received
from the decoder. The decoder MUST treat a new dynamic table from the decoder. The decoder MUST treat a new dynamic table
capacity value that exceeds this limit as a connection error of type capacity value that exceeds this limit as a connection error of type
"HTTP_QPACK_ENCODER_STREAM_ERROR". "HTTP_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 (see Section 3.2.2). This MUST NOT cause the eviction of blocking
with outstanding references (see Section 2.1.1). Changing the entries (see Section 2.1.2). Changing the capacity of the dynamic
capacity of the dynamic table is not acknowledged as this instruction table is not acknowledged as this instruction does not insert an
does not insert an entry. entry.
4.4. Decoder Stream 4.4. Decoder Instructions
The decoder stream carries information used to ensure consistency of Decoder instructions provide information used to ensure consistency
the dynamic table. Information is sent from the decoder to the of the dynamic table. They are sent from the decoder to the encoder
encoder; that is, the server informs the client about the processing on a decoder stream; that is, the server informs the client about the
of the client's header blocks and table updates, and the client processing of the client's header blocks and table updates, and the
informs the server about the processing of the server's header blocks client informs the server about the processing of the server's header
and table updates. blocks and table updates.
The contents of the decoder stream are an unframed sequence of the This section specifies the following decoder instructions.
following instructions.
4.4.1. Insert Count Increment 4.4.1. Insert Count Increment
The Insert Count Increment instruction begins with the '00' two-bit The Insert Count Increment instruction begins with the '00' two-bit
pattern. The instruction specifies the total number of dynamic table pattern. The instruction specifies the total number of dynamic table
inserts and duplications since the last Insert Count Increment or inserts and duplications since the last Insert Count Increment or
Header Acknowledgement that increased the Known Received Count for Header Acknowledgement that increased the Known Received Count for
the dynamic table (see Section 2.1.4). The Increment field is the dynamic table (see Section 2.1.4). The Increment field is
encoded as a 6-bit prefix integer. The encoder uses this value to encoded as a 6-bit prefix integer. The encoder uses this value to
determine which table entries might cause a stream to become blocked, determine which table entries might cause a stream to become blocked,
skipping to change at page 18, line 10 skipping to change at page 18, line 26
An encoder that receives an Increment field equal to zero or one that An encoder that receives an Increment field equal to zero or one that
increases the Known Received Count beyond what the encoder has sent increases the Known Received Count beyond what the encoder has sent
MUST treat this as a connection error of type MUST treat this as a connection error of type
"HTTP_QPACK_DECODER_STREAM_ERROR". "HTTP_QPACK_DECODER_STREAM_ERROR".
4.4.2. Header Acknowledgement 4.4.2. Header Acknowledgement
After processing a header block whose declared Required Insert Count After processing a header block whose declared Required Insert Count
is not zero, the decoder emits a Header Acknowledgement instruction is not zero, the decoder emits a Header Acknowledgement instruction
on the decoder stream. The instruction begins with the '1' one-bit on the decoder stream. The instruction begins with the '1' one-bit
pattern and includes the request stream's stream ID, encoded as a pattern and includes the header block's associated stream ID, encoded
7-bit prefix integer. It is used by the peer's encoder to know when as a 7-bit prefix integer. It is used by the peer's encoder to know
it is safe to evict an entry, and possibly update the Known Received when it is safe to evict an entry, and possibly update the Known
Count. Received Count.
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 1 | Stream ID (7+) | | 1 | Stream ID (7+) |
+---+---------------------------+ +---+---------------------------+
Figure 5: Header Acknowledgement Figure 5: Header Acknowledgement
The same Stream ID can be identified multiple times, as multiple The same Stream ID can be identified multiple times, as multiple
header blocks can be sent on a single stream in the case of header blocks can be sent on a single stream in the case of
intermediate responses, trailers, and pushed requests. Since header intermediate responses, trailers, and pushed requests. Since HEADERS
frames on each stream are received and processed in order, this gives and PUSH_PROMISE frames on each stream are received and processed in
the encoder precise feedback on which header blocks within a stream order, this gives the encoder precise feedback on which header blocks
have been fully processed. within a stream have been fully processed.
If an encoder receives a Header Acknowledgement instruction referring If an encoder receives a Header Acknowledgement instruction referring
to a stream on which every header block with a non-zero Required to a stream on which every header block with a non-zero Required
Insert Count has already been acknowledged, that MUST be treated as a Insert Count has already been acknowledged, that MUST be treated as a
connection error of type "HTTP_QPACK_DECODER_STREAM_ERROR". connection error of type "HTTP_QPACK_DECODER_STREAM_ERROR".
When blocking references are permitted, the encoder uses When blocking references are permitted, the encoder uses
acknowledgement of header blocks to update the Known Received Count. acknowledgement of header blocks to update the Known Received Count.
If a header block was potentially blocking, the acknowledgement If a header block was potentially blocking, the acknowledgement
implies that the decoder has received all dynamic table state implies that the decoder has received all dynamic table state
necessary to process the header block. If the Required Insert Count necessary to process the header block. If the Required Insert Count
of an acknowledged header block was greater than the encoder's of an acknowledged header block was greater than the encoder's
current Known Received Count, the block's Required Insert Count current Known Received Count, the block's Required Insert Count
becomes the new Known Received Count. becomes the new Known Received Count.
4.4.3. Stream Cancellation 4.4.3. Stream Cancellation
The instruction begins with the '01' two-bit pattern. The The instruction begins with the '01' two-bit pattern. The
skipping to change at page 19, line 26 skipping to change at page 19, line 39
abandons reading of a stream it needs to signal this using the Stream abandons reading of a stream it needs to signal this using the Stream
Cancellation instruction. This signals to the encoder that all Cancellation instruction. This signals to the encoder that all
references to the dynamic table on that stream are no longer references to the dynamic table on that stream are no longer
outstanding. A decoder with a maximum dynamic table capacity equal outstanding. A decoder with a maximum dynamic table capacity equal
to zero (see Section 3.2.3) MAY omit sending Stream Cancellations, to zero (see Section 3.2.3) MAY omit sending Stream Cancellations,
because the encoder cannot have any dynamic table references. because the encoder cannot have any dynamic table references.
An encoder cannot infer from this instruction that any updates to the An encoder cannot infer from this instruction that any updates to the
dynamic table have been received. dynamic table have been received.
4.5. Request and Push Streams 4.5. Header Block Instructions
HEADERS and PUSH_PROMISE frames on request and push streams reference HTTP/3 endpoints convert header lists to headers blocks and exchange
the dynamic table in a particular state without modifying it. Frames them inside HEADERS and PUSH_PROMISE frames. A decoder interprets
on these streams emit the headers for an HTTP request or response. header block instructions in order to construct a header list. These
instructions reference the static table, or dynamic table in a
particular state without modifying it.
This section specifies the following header block instructions.
4.5.1. Header Block Prefix 4.5.1. Header Block Prefix
Each header block is prefixed with two integers. The Required Insert Each header block is prefixed with two integers. The Required Insert
Count is encoded as an integer with an 8-bit prefix after the Count is encoded as an integer with an 8-bit prefix after the
encoding described in Section 4.5.1.1). The Base is encoded as sign- encoding described in Section 4.5.1.1). The Base is encoded as sign-
and-modulus integer, using a single sign bit and a value with a 7-bit and-modulus integer, using a single sign bit and a value with a 7-bit
prefix (see Section 4.5.1.2). prefix (see Section 4.5.1.2).
These two values are followed by instructions for compressed headers. These two values are followed by instructions for compressed headers.
skipping to change at page 20, line 12 skipping to change at page 20, line 34
Figure 7: Frame Payload Figure 7: Frame Payload
4.5.1.1. Required Insert Count 4.5.1.1. Required Insert Count
Required Insert Count identifies the state of the dynamic table Required Insert Count identifies the state of the dynamic table
needed to process the header block. Blocking decoders use the needed to process the header block. Blocking decoders use the
Required Insert Count to determine when it is safe to process the Required Insert Count to determine when it is safe to process the
rest of the block. rest of the block.
If no references are made to the dynamic table, a value of 0 is The encoder transforms the Required Insert Count as follows before
encoded. Alternatively, where the Required Insert Count is greater encoding:
than zero, the encoder transforms it as follows before encoding:
EncodedInsertCount = (ReqInsertCount mod (2 * MaxEntries)) + 1 if ReqInsertCount == 0:
EncInsertCount = 0
else:
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).
The decoder reconstructs the Required Insert Count using the This encoding limits the length of the prefix on long-lived
following algorithm, where TotalNumberOfInserts is the total number connections.
of inserts into the decoder's dynamic table:
The decoder can reconstruct the Required Insert Count using an
algorithm such as the following. If the decoder encounters a value
of EncodedInsertCount that could not have been produced by a
conformant encoder, it MUST treat this as a stream error of type
"HTTP_QPACK_DECOMPRESSION_FAILED".
TotalNumberOfInserts is the total number of inserts into the
decoder's dynamic table.
FullRange = 2 * MaxEntries
if EncodedInsertCount == 0: if EncodedInsertCount == 0:
ReqInsertCount = 0 ReqInsertCount = 0
else: else:
InsertCount = EncodedInsertCount - 1 if EncodedInsertCount > FullRange:
CurrentWrapped = TotalNumberOfInserts mod (2 * MaxEntries) Error
MaxValue = TotalNumberOfInserts + MaxEntries
if CurrentWrapped >= InsertCount + MaxEntries:
# Insert Count wrapped around 1 extra time
ReqInsertCount += 2 * MaxEntries
else if CurrentWrapped + MaxEntries < InsertCount:
# Decoder wrapped around 1 extra time
CurrentWrapped += 2 * MaxEntries
ReqInsertCount += TotalNumberOfInserts - CurrentWrapped # MaxWrapped is the largest possible value of
# ReqInsertCount that is 0 mod 2*MaxEntries
MaxWrapped = floor(MaxValue / FullRange) * FullRange
ReqInsertCount = MaxWrapped + EncodedInsertCount - 1
This encoding limits the length of the prefix on long-lived # If ReqInsertCount exceeds MaxValue, the Encoder's value
connections. # must have wrapped one fewer time
if ReqInsertCount > MaxValue:
if ReqInsertCount < FullRange:
Error
ReqInsertCount -= FullRange
For example, if the dynamic table is 100 bytes, then the Required For example, if the dynamic table is 100 bytes, then the Required
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 3 indicates that the Required inserts, then an encoded value of 3 indicates that the Required
Insert Count is 9 for the header block. Insert Count is 9 for the header block.
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.6. described in Section 3.2.5.
To save space, the Base is encoded relative to the Insert Count using To save space, the Base is encoded relative to the Insert Count using
a one-bit sign and the "Delta Base" value. A sign bit of 0 indicates a one-bit sign and the "Delta Base" value. A sign bit of 0 indicates
that the Base is greater than or equal to the value of the Insert that the Base is greater than or equal to the value of the Insert
Count; the value of Delta Base is added to the Insert Count to Count; the value of Delta Base is added to the Insert Count to
determine the value of the Base. A sign bit of 1 indicates that the determine the value of the Base. A sign bit of 1 indicates that the
Base is less than the Insert Count. That is: Base is less than the Insert Count. That is:
if S == 0: if S == 0:
Base = ReqInsertCount + DeltaBase Base = ReqInsertCount + DeltaBase
skipping to change at page 22, line 23 skipping to change at page 23, line 9
absolute index less than the Base, this representation starts with absolute index less than the Base, this representation starts with
the '1' 1-bit pattern, followed by the "S" bit indicating whether the the '1' 1-bit pattern, followed by the "S" bit indicating whether the
reference is into the static (S=1) or dynamic (S=0) table. Finally, reference is into the static (S=1) or dynamic (S=0) table. Finally,
the relative index of the matching header field is represented as an the relative index of the matching header field is represented as an
integer with a 6-bit prefix (see Section 5.1 of [RFC7541]). integer with a 6-bit prefix (see Section 5.1 of [RFC7541]).
4.5.3. Indexed Header Field With Post-Base Index 4.5.3. Indexed Header Field With Post-Base Index
If the entry is in the dynamic table with an absolute index greater If the entry is in the dynamic table with an absolute index greater
than or equal to the Base, the representation starts with the '0001' than or equal to the Base, the representation starts with the '0001'
4-bit pattern, followed by the post-base index (see Section 3.2.7) of 4-bit pattern, followed by the post-base index (see Section 3.2.6) of
the matching header field, represented as an integer with a 4-bit the matching header field, represented as an integer with a 4-bit
prefix (see Section 5.1 of [RFC7541]). prefix (see Section 5.1 of [RFC7541]).
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | Index (4+) | | 0 | 0 | 0 | 1 | Index (4+) |
+---+---+---+---+---------------+ +---+---+---+---+---------------+
Indexed Header Field with Post-Base Index Indexed Header Field with Post-Base Index
skipping to change at page 22, line 46 skipping to change at page 23, line 32
A literal header field with a name reference represents a header A literal header field with a name reference represents a header
where the header field name matches the header field name of an entry where the header field name matches the header field name of an entry
stored in the static table or the dynamic table. stored in the static table or the dynamic table.
If the entry is in the static table, or in the dynamic table with an If the entry is in the static table, or in the dynamic table with an
absolute index less than the Base, this representation starts with absolute index less than the Base, this representation starts with
the '01' two-bit pattern. If the entry is in the dynamic table with the '01' two-bit pattern. If the entry is in the dynamic table with
an absolute index greater than or equal to the Base, the an absolute index greater than or equal to the Base, the
representation starts with the '0000' four-bit pattern. representation starts with the '0000' four-bit pattern.
Only the header field name stored in the static or dynamic table is
used. Any header field value MUST be ignored.
The following bit, 'N', indicates whether an intermediary is The following bit, 'N', indicates whether an intermediary is
permitted to add this header to the dynamic header table on permitted to add this header to the dynamic header table on
subsequent hops. When the 'N' bit is set, the encoded header MUST subsequent hops. When the 'N' bit is set, the encoded header MUST
always be encoded with a literal representation. In particular, when always be encoded with a literal representation. In particular, when
a peer sends a header field that it received represented as a literal a peer sends a header field that it received represented as a literal
header field with the 'N' bit set, it MUST use a literal header field with the 'N' bit set, it MUST use a literal
representation to forward this header field. This bit is intended representation to forward this header field. This bit is intended
for protecting header field values that are not to be put at risk by for protecting header field values that are not to be put at risk by
compressing them (see Section 7.1 of [RFC7541] for more details). compressing them (see Section 7.1 of [RFC7541] for more details).
skipping to change at page 23, line 29 skipping to change at page 24, line 27
absolute index less than the Base, the header field name is absolute index less than the Base, the header field name is
represented using the relative index of that entry, which is represented using the relative index of that entry, which is
represented as an integer with a 4-bit prefix (see Section 5.1 of represented as an integer with a 4-bit prefix (see Section 5.1 of
[RFC7541]). The "S" bit indicates whether the reference is to the [RFC7541]). The "S" bit indicates whether the reference is to the
static (S=1) or dynamic (S=0) table. static (S=1) or dynamic (S=0) table.
4.5.5. Literal Header Field With Post-Base Name Reference 4.5.5. Literal Header Field With Post-Base Name Reference
For entries in the dynamic table with an absolute index greater than For entries in the dynamic table with an absolute index greater than
or equal to the Base, the header field name is represented using the or equal to the Base, the header field name is represented using the
post-base index of that entry (see Section 3.2.7) encoded as an post-base index of that entry (see Section 3.2.6) encoded as an
integer with a 3-bit prefix. integer with a 3-bit prefix.
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+ +---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | N |NameIdx(3+)| | 0 | 0 | 0 | 0 | N |NameIdx(3+)|
+---+---+---+---+---+-----------+ +---+---+---+---+---+-----------+
| H | Value Length (7+) | | H | Value Length (7+) |
+---+---------------------------+ +---+---------------------------+
| Value String (Length bytes) | | Value String (Length bytes) |
+-------------------------------+ +-------------------------------+
skipping to change at page 24, line 46 skipping to change at page 25, line 43
SETTINGS_QPACK_BLOCKED_STREAMS (0x7): An integer with a maximum SETTINGS_QPACK_BLOCKED_STREAMS (0x7): An integer with a maximum
value of 2^16 - 1. The default value is zero. See Section 2.1.3. value of 2^16 - 1. The default value is zero. See Section 2.1.3.
6. Error Handling 6. Error Handling
The following error codes are defined for HTTP/3 to indicate failures The following error codes are defined for HTTP/3 to indicate failures
of QPACK which prevent the stream or connection from continuing: of QPACK which prevent the stream or connection from continuing:
HTTP_QPACK_DECOMPRESSION_FAILED (TBD): The decoder failed to HTTP_QPACK_DECOMPRESSION_FAILED (TBD): The decoder failed to
interpret an instruction on a request or push stream and is not interpret a header block instruction and is not able to continue
able to continue decoding that header block. decoding that header block.
HTTP_QPACK_ENCODER_STREAM_ERROR (TBD): The decoder failed to HTTP_QPACK_ENCODER_STREAM_ERROR (TBD): The decoder failed to
interpret an instruction on the encoder stream. interpret an encoder instruction received on the encoder stream.
HTTP_QPACK_DECODER_STREAM_ERROR (TBD): The encoder failed to HTTP_QPACK_DECODER_STREAM_ERROR (TBD): The encoder failed to
interpret an instruction on the decoder stream. interpret a decoder instruction received on the decoder stream.
Upon encountering an error, an implementation MAY elect to treat it Upon encountering an error, an implementation MAY elect to treat it
as a connection error even if this document prescribes that it MUST as a connection error even if this document prescribes that it MUST
be treated as a stream error. be treated as a stream error.
7. Security Considerations 7. Security Considerations
TBD. TBD.
8. IANA Considerations 8. IANA Considerations
8.1. Settings Registration 8.1. Settings Registration
This document creates two new settings in the "HTTP/3 Settings" This document specifies two settings. The entries in the following
registry established in [HTTP3]. table are registered in the "HTTP/3 Settings" registry established in
[HTTP3].
The entries in the following table are registered by this document.
+--------------------------+------+---------------+ +--------------------------+------+---------------+
| Setting Name | Code | Specification | | Setting Name | Code | Specification |
+--------------------------+------+---------------+ +--------------------------+------+---------------+
| QPACK_MAX_TABLE_CAPACITY | 0x1 | Section 5 | | QPACK_MAX_TABLE_CAPACITY | 0x1 | Section 5 |
| | | | | | | |
| QPACK_BLOCKED_STREAMS | 0x7 | Section 5 | | QPACK_BLOCKED_STREAMS | 0x7 | Section 5 |
+--------------------------+------+---------------+ +--------------------------+------+---------------+
8.2. Stream Type Registration 8.2. Stream Type Registration
This document creates two new settings in the "HTTP/3 Stream Type" This document specifies two stream types. The entries in the
registry established in [HTTP3]. following table are registered in the "HTTP/3 Stream Type" registry
established in [HTTP3].
The entries in the following table are registered by this document.
+----------------------+------+---------------+--------+ +----------------------+------+---------------+--------+
| Stream Type | Code | Specification | Sender | | Stream Type | Code | Specification | Sender |
+----------------------+------+---------------+--------+ +----------------------+------+---------------+--------+
| QPACK Encoder Stream | 0x48 | Section 4 | Both | | QPACK Encoder Stream | 0x02 | Section 4.2.1 | Both |
| | | | | | | | | |
| QPACK Decoder Stream | 0x68 | Section 4 | Both | | QPACK Decoder Stream | 0x03 | Section 4.2.1 | Both |
+----------------------+------+---------------+--------+ +----------------------+------+---------------+--------+
8.3. Error Code Registration 8.3. Error Code Registration
This document establishes the following new error codes in the This document specifies three error codes. The entries in the
"HTTP/3 Error Code" registry established in [HTTP3]. following table are registered in the "HTTP/3 Error Code" registry
established in [HTTP3].
+------------------------------+------+--------------+--------------+ +------------------------------+------+--------------+--------------+
| Name | Code | Description | Specificatio | | Name | Code | Description | Specificatio |
| | | | n | | | | | n |
+------------------------------+------+--------------+--------------+ +------------------------------+------+--------------+--------------+
| HTTP_QPACK_DECOMPRESSION_FAI | TBD | Decompressio | Section 6 | | HTTP_QPACK_DECOMPRESSION_FAI | TBD | Decompressio | Section 6 |
| LED | | n of a | | | LED | | n of a | |
| | | header block | | | | | header block | |
| | | failed | | | | | failed | |
| | | | | | | | | |
skipping to change at page 26, line 28 skipping to change at page 27, line 28
| HTTP_QPACK_DECODER_STREAM_ER | TBD | Error on the | Section 6 | | HTTP_QPACK_DECODER_STREAM_ER | TBD | Error on the | Section 6 |
| ROR | | decoder | | | ROR | | decoder | |
| | | stream | | | | | stream | |
+------------------------------+------+--------------+--------------+ +------------------------------+------+--------------+--------------+
9. References 9. References
9.1. Normative References 9.1. Normative References
[HTTP3] Bishop, M., Ed., "Hypertext Transfer Protocol Version 3 [HTTP3] Bishop, M., Ed., "Hypertext Transfer Protocol Version 3
(HTTP/3)", draft-ietf-quic-http-18 (work in progress), (HTTP/3)", draft-ietf-quic-http-19 (work in progress),
January 2019. March 2019.
[QUIC-TRANSPORT] [QUIC-TRANSPORT]
Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based Iyengar, J., Ed. and M. Thomson, Ed., "QUIC: A UDP-Based
Multiplexed and Secure Transport", draft-ietf-quic- Multiplexed and Secure Transport", draft-ietf-quic-
transport-17 (work in progress), January 2019. transport-18 (work in progress), March 2019.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015,
<https://www.rfc-editor.org/info/rfc7541>. <https://www.rfc-editor.org/info/rfc7541>.
skipping to change at page 34, line 10 skipping to change at page 35, line 10
encodeInteger(prefixBuffer, 0x80, encodeInteger(prefixBuffer, 0x80,
largestReference - baseIndex, 7) largestReference - baseIndex, 7)
return controlBuffer, prefixBuffer + streamBuffer return controlBuffer, prefixBuffer + streamBuffer
Appendix C. Change Log Appendix C. Change Log
*RFC Editor's Note:* Please remove this section prior to *RFC Editor's Note:* Please remove this section prior to
publication of a final version of this document. publication of a final version of this document.
C.1. Since draft-ietf-quic-qpack-05 C.1. Since draft-ietf-quic-qpack-06
o Clarify initial dynamic table capacity maximums (#2276, #2330,
#2330)
C.2. Since draft-ietf-quic-qpack-05
o Introduced the terms dynamic table capacity and maximum dynamic o Introduced the terms dynamic table capacity and maximum dynamic
table capacity. table capacity.
o Renamed SETTINGS_HEADER_TABLE_SIZE to o Renamed SETTINGS_HEADER_TABLE_SIZE to
SETTINGS_QPACK_MAX_TABLE_CAPACITY. SETTINGS_QPACK_MAX_TABLE_CAPACITY.
C.2. Since draft-ietf-quic-qpack-04 C.3. Since draft-ietf-quic-qpack-04
o Changed calculation of Delta Base Index to avoid an illegal value o Changed calculation of Delta Base Index to avoid an illegal value
(#2002, #2005) (#2002, #2005)
C.3. Since draft-ietf-quic-qpack-03 C.4. Since draft-ietf-quic-qpack-03
o Change HTTP settings defaults (#2038) o Change HTTP settings defaults (#2038)
o Substantial editorial reorganization o Substantial editorial reorganization
C.4. Since draft-ietf-quic-qpack-02 C.5. Since draft-ietf-quic-qpack-02
o Largest Reference encoded modulo MaxEntries (#1763) o Largest Reference encoded modulo MaxEntries (#1763)
o New Static Table (#1355) o New Static Table (#1355)
o Table Size Update with Insert Count=0 is a connection error o Table Size Update with Insert Count=0 is a connection error
(#1762) (#1762)
o Stream Cancellations are optional when o Stream Cancellations are optional when
SETTINGS_HEADER_TABLE_SIZE=0 (#1761) SETTINGS_HEADER_TABLE_SIZE=0 (#1761)
skipping to change at page 34, line 47 skipping to change at page 36, line 4
o Stream Cancellations are optional when o Stream Cancellations are optional when
SETTINGS_HEADER_TABLE_SIZE=0 (#1761) SETTINGS_HEADER_TABLE_SIZE=0 (#1761)
o Implementations must handle 62 bit integers (#1760) o Implementations must handle 62 bit integers (#1760)
o Different error types for each QPACK stream, other changes to o Different error types for each QPACK stream, other changes to
error handling (#1726) error handling (#1726)
o Preserve header field order (#1725) o Preserve header field order (#1725)
o Initial table size is the maximum permitted when table is first o Initial table size is the maximum permitted when table is first
usable (#1642) usable (#1642)
C.5. Since draft-ietf-quic-qpack-01 C.6. Since draft-ietf-quic-qpack-01
o Only header blocks that reference the dynamic table are o Only header blocks that reference the dynamic table are
acknowledged (#1603, #1605) acknowledged (#1603, #1605)
C.6. Since draft-ietf-quic-qpack-00 C.7. Since draft-ietf-quic-qpack-00
o Renumbered instructions for consistency (#1471, #1472) o Renumbered instructions for consistency (#1471, #1472)
o Decoder is allowed to validate largest reference (#1404, #1469) o Decoder is allowed to validate largest reference (#1404, #1469)
o Header block acknowledgments also acknowledge the associated o Header block acknowledgments also acknowledge the associated
largest reference (#1370, #1400) largest reference (#1370, #1400)
o Added an acknowledgment for unread streams (#1371, #1400) o Added an acknowledgment for unread streams (#1371, #1400)
o Removed framing from encoder stream (#1361,#1467) o Removed framing from encoder stream (#1361,#1467)
o Control streams use typed unidirectional streams rather than fixed o Control streams use typed unidirectional streams rather than fixed
stream IDs (#910,#1359) stream IDs (#910,#1359)
C.7. Since draft-ietf-quic-qcram-00 C.8. Since draft-ietf-quic-qcram-00
o Separate instruction sets for table updates and header blocks o Separate instruction sets for table updates and header blocks
(#1235, #1142, #1141) (#1235, #1142, #1141)
o Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125, o Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125,
#1314) #1314)
o Added mechanisms that support one-pass encoding (#1138, #1320) o Added mechanisms that support one-pass encoding (#1138, #1320)
o Added a setting to control the number of blocked decoders (#238, o Added a setting to control the number of blocked decoders (#238,
 End of changes. 84 change blocks. 
210 lines changed or deleted 269 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/