| draft-ietf-quic-qpack-00.txt | draft-ietf-quic-qpack-01.txt | |||
|---|---|---|---|---|
| QUIC C. Krasic | QUIC C. Krasic | |||
| Internet-Draft Google, Inc | Internet-Draft Netflix | |||
| Intended status: Standards Track M. Bishop | Intended status: Standards Track M. Bishop | |||
| Expires: November 24, 2018 Akamai Technologies | Expires: December 30, 2018 Akamai Technologies | |||
| A. Frindell, Ed. | A. Frindell, Ed. | |||
| May 23, 2018 | June 28, 2018 | |||
| QPACK: Header Compression for HTTP over QUIC | QPACK: Header Compression for HTTP over QUIC | |||
| draft-ietf-quic-qpack-00 | draft-ietf-quic-qpack-01 | |||
| 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 over | efficiently representing HTTP header fields, to be used in HTTP over | |||
| QUIC. This is a variation of HPACK header compression that seeks to | QUIC. This is a variation of HPACK header compression that seeks to | |||
| reduce head-of-line blocking. | reduce 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 November 24, 2018. | This Internet-Draft will expire on December 30, 2018. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2018 IETF Trust and the persons identified as the | Copyright (c) 2018 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.1. Head-of-Line Blocking in HPACK . . . . . . . . . . . . . 3 | 2. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 4 | 2.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2. Conventions and Definitions . . . . . . . . . . . . . . . . . 5 | 2.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2.1. Notational Conventions . . . . . . . . . . . . . . . . . 5 | 2.2.1. Absolute and Relative Indexing . . . . . . . . . . . 5 | |||
| 3. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 5 | 2.2.2. Post-Base Indexing . . . . . . . . . . . . . . . . . 6 | |||
| 3.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 6 | 2.3. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 7 | |||
| 3.2. Indexing . . . . . . . . . . . . . . . . . . . . . . . . 6 | 2.3.1. State Synchronization . . . . . . . . . . . . . . . . 8 | |||
| 3.3. QPACK Encoder Stream . . . . . . . . . . . . . . . . . . 8 | 3. Conventions and Definitions . . . . . . . . . . . . . . . . . 8 | |||
| 3.3.1. Insert With Name Reference . . . . . . . . . . . . . 8 | 3.1. Notational Conventions . . . . . . . . . . . . . . . . . 9 | |||
| 3.3.2. Insert Without Name Reference . . . . . . . . . . . . 9 | 4. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 3.3.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 9 | 5. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 3.3.4. Dynamic Table Size Update . . . . . . . . . . . . . . 10 | 5.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.4. QPACK Decoder Stream . . . . . . . . . . . . . . . . . . 10 | 5.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 10 | |||
| 3.4.1. Table State Synchronize . . . . . . . . . . . . . . . 11 | 5.1.2. String Literals . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.4.2. Header Acknowledgement . . . . . . . . . . . . . . . 11 | 5.2. QPACK Encoder Stream . . . . . . . . . . . . . . . . . . 11 | |||
| 3.5. Request and Push Streams . . . . . . . . . . . . . . . . 11 | 5.2.1. Insert With Name Reference . . . . . . . . . . . . . 11 | |||
| 3.5.1. Header Data Prefix . . . . . . . . . . . . . . . . . 12 | 5.2.2. Insert Without Name Reference . . . . . . . . . . . . 11 | |||
| 3.5.2. Instructions . . . . . . . . . . . . . . . . . . . . 12 | 5.2.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 4. Encoding Strategies . . . . . . . . . . . . . . . . . . . . . 15 | 5.2.4. Dynamic Table Size Update . . . . . . . . . . . . . . 12 | |||
| 4.1. Single pass encoding . . . . . . . . . . . . . . . . . . 15 | 5.3. QPACK Decoder Stream . . . . . . . . . . . . . . . . . . 13 | |||
| 4.2. Preventing Eviction Races . . . . . . . . . . . . . . . . 15 | 5.3.1. Table State Synchronize . . . . . . . . . . . . . . . 13 | |||
| 4.3. Reference Tracking . . . . . . . . . . . . . . . . . . . 15 | 5.3.2. Header Acknowledgement . . . . . . . . . . . . . . . 14 | |||
| 4.3.1. Blocked Eviction . . . . . . . . . . . . . . . . . . 16 | 5.3.3. Stream Cancellation . . . . . . . . . . . . . . . . . 14 | |||
| 4.3.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 16 | 5.4. Request and Push Streams . . . . . . . . . . . . . . . . 15 | |||
| 4.4. Speculative table updates . . . . . . . . . . . . . . . . 16 | 5.4.1. Header Data Prefix . . . . . . . . . . . . . . . . . 15 | |||
| 4.5. Sample One Pass Encoding Algorithm . . . . . . . . . . . 17 | 5.4.2. Instructions . . . . . . . . . . . . . . . . . . . . 16 | |||
| 5. Security Considerations . . . . . . . . . . . . . . . . . . . 18 | 6. Encoding Strategies . . . . . . . . . . . . . . . . . . . . . 19 | |||
| 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 18 | 6.1. Single Pass Encoding . . . . . . . . . . . . . . . . . . 19 | |||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 18 | 6.2. Preventing Eviction Races . . . . . . . . . . . . . . . . 19 | |||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 18 | 6.3. Reference Tracking . . . . . . . . . . . . . . . . . . . 19 | |||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 18 | 6.3.1. Blocked Eviction . . . . . . . . . . . . . . . . . . 20 | |||
| 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 19 | 6.3.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 20 | |||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 19 | 6.4. Speculative table updates . . . . . . . . . . . . . . . . 20 | |||
| Change Log . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 | 6.5. Sample One Pass Encoding Algorithm . . . . . . . . . . . 20 | |||
| B.1. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 19 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 22 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 | 8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 22 | |||
| 8.1. Settings Registration . . . . . . . . . . . . . . . . . . 22 | ||||
| 8.2. Stream Type Registration . . . . . . . . . . . . . . . . 22 | ||||
| 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 22 | ||||
| 9.1. Normative References . . . . . . . . . . . . . . . . . . 22 | ||||
| 9.2. Informative References . . . . . . . . . . . . . . . . . 23 | ||||
| 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 23 | ||||
| Appendix A. Change Log . . . . . . . . . . . . . . . . . . . . . 23 | ||||
| A.1. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 23 | ||||
| A.2. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 24 | ||||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 24 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 25 | ||||
| 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. QUIC's stream multiplexing comes into some conflict with | HTTP/2. HTTP/2 used HPACK ([RFC7541]) for header compression, but | |||
| header compression. A key goal of the design of QUIC is to improve | QUIC's stream multiplexing comes into some conflict with HPACK. A | |||
| stream multiplexing relative to HTTP/2 by eliminating HoL (head of | key goal of the design of QUIC is to improve stream multiplexing | |||
| line) blocking, which can occur in HTTP/2. HoL blocking can happen | relative to HTTP/2 by reducing head-of-line blocking. If HPACK were | |||
| because all HTTP/2 streams are multiplexed onto a single TCP | used for HTTP/QUIC, it would induce head-of-line blocking due to | |||
| connection with its in-order semantics. QUIC can maintain | built-in assumptions of a total ordering across frames on all | |||
| independence between streams because it implements core transport | streams. | |||
| functionality in a fully stream-aware manner. However, the HTTP/QUIC | ||||
| mapping is still subject to HoL blocking if HPACK is used directly. | ||||
| HPACK exploits multiplexing for greater compression, shrinking the | ||||
| representation of headers that have appeared earlier on the same | ||||
| connection. In the context of QUIC, this imposes a vulnerability to | ||||
| HoL blocking (see Section 1.1). | ||||
| QUIC is described in [QUIC-TRANSPORT]. The HTTP/QUIC mapping is | QUIC is described in [QUIC-TRANSPORT]. The HTTP/QUIC mapping is | |||
| described in [QUIC-HTTP]. For a full description of HTTP/2, see | described in [QUIC-HTTP]. For a full description of HTTP/2, see | |||
| [RFC7540]. The description of HPACK is [RFC7541], with important | [RFC7540]. The description of HPACK is [RFC7541], with important | |||
| terminology in Section 1.3. | terminology in Section 1.3. | |||
| QPACK modifies HPACK to allow correctness in the presence of out-of- | QPACK reuses core concepts from HPACK, but is redesigned to allow | |||
| order delivery, with flexibility for implementations to balance | correctness in the presence of out-of-order delivery, with | |||
| between resilience against HoL blocking and optimal compression | flexibility for implementations to balance between resilience against | |||
| ratio. The design goals are to closely approach the compression | head-of-line blocking and optimal compression ratio. The design | |||
| ratio of HPACK with substantially less head-of-line blocking under | goals are to closely approach the compression ratio of HPACK with | |||
| the same loss conditions. | substantially less head-of-line blocking under the same loss | |||
| conditions. | ||||
| QPACK is intended to be a relatively non-intrusive extension to | 2. Header Tables | |||
| HPACK; an implementation should be easily shared within stacks | ||||
| supporting both HTTP/2 over (TLS+)TCP and HTTP/QUIC. | ||||
| 1.1. Head-of-Line Blocking in HPACK | Like HPACK, QPACK uses two tables for associating header fields to | |||
| indexes. The static table (see Section 2.1) is predefined and | ||||
| contains common header fields (some of them with an empty value). | ||||
| HPACK enables several types of header representations, one of which | The dynamic table (see Section 2.2) built up over the course of the | |||
| also adds the header to a dynamic table of header values. These | connection and can be used by the encoder to index header fields | |||
| values are then available for reuse in subsequent header blocks | repeated in the encoded header lists. | |||
| simply by referencing the entry number in the table. | ||||
| If the packet containing a header is lost, that stream cannot | Unlike in HPACK, entries in the QPACK static and dynamic tables are | |||
| complete header processing until the packet is retransmitted. This | addressed separately. The following sections describe how entries in | |||
| is unavoidable. However, other streams which rely on the state | each table is addressed. | |||
| created by that packet _also_ cannot make progress. This is the | ||||
| problem which QUIC solves in general, but which is reintroduced by | ||||
| HPACK when the loss includes a HEADERS frame. | ||||
| 1.2. Avoiding Head-of-Line Blocking in HTTP/QUIC | 2.1. Static Table | |||
| The static table consists of a predefined static list of header | ||||
| fields, each of which has a fixed index over time. Its entries are | ||||
| defined in Appendix A of [RFC7541]. Note that because HPACK did not | ||||
| use zero-based references, there is no value at index zero of the | ||||
| static table. | ||||
| 2.2. Dynamic Table | ||||
| The dynamic table consists of a list of header fields maintained in | ||||
| first-in, first-out order. The dynamic table is initially empty. | ||||
| Entries are added by instructions on the Encoder Stream (see | ||||
| Section 5.2). | ||||
| 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 | ||||
| is less than or equal to (maximum size - new entry size) or until the | ||||
| table is empty. | ||||
| If the size of the new entry is less than or equal to the maximum | ||||
| size, that entry is added to the table. It is an error to attempt to | ||||
| add an entry that is larger than the maximum size; this MUST be | ||||
| treated as a connection error of type | ||||
| "HTTP_QPACK_DECOMPRESSION_FAILED". | ||||
| A new entry can reference an entry in the dynamic table that will be | ||||
| evicted when adding this new entry into the dynamic table. | ||||
| Implementations are cautioned to avoid deleting the referenced name | ||||
| if the referenced entry is evicted from the dynamic table prior to | ||||
| inserting the new entry. | ||||
| The dynamic table can contain duplicate entries (i.e., entries with | ||||
| the same name and same value). Therefore, duplicate entries MUST NOT | ||||
| be treated as an error by a decoder. | ||||
| The encoder decides how to update the dynamic table and as such can | ||||
| control how much memory is used by the dynamic table. To limit the | ||||
| memory requirements of the decoder, the dynamic table size is | ||||
| strictly bounded. | ||||
| The decoder determines the maximum size that the encoder is permitted | ||||
| to use for the dynamic table. In HTTP/QUIC, this value is determined | ||||
| by the SETTINGS_HEADER_TABLE_SIZE setting (see Section 4.2.5.2 of | ||||
| [QUIC-HTTP]). | ||||
| An encoder can choose to use less capacity than this maximum size | ||||
| (see Section 5.2.4), but the chosen size MUST stay lower than or | ||||
| equal to the maximum set by the decoder. Whenever the maximum size | ||||
| for the dynamic table is reduced, entries are evicted from the end of | ||||
| the dynamic table until the size of the dynamic table is less than or | ||||
| equal to the maximum size. | ||||
| This mechanism can be used to completely clear entries from the | ||||
| dynamic table by setting a maximum size of 0, which can subsequently | ||||
| be restored. | ||||
| 2.2.1. Absolute and Relative Indexing | ||||
| Each entry possesses both an absolute index which is fixed for the | ||||
| lifetime of that entry and a relative index which changes over time | ||||
| based on the context of the reference. The first entry inserted has | ||||
| an absolute index of "1"; indices increase sequentially with each | ||||
| insertion. | ||||
| The relative index begins at zero and increases in the opposite | ||||
| direction from the absolute index. Determining which entry has a | ||||
| relative index of "0" depends on the context of the reference. | ||||
| On the control stream, a relative index of "0" always refers to the | ||||
| most recently inserted value in the dynamic table. Note that this | ||||
| means the entry referenced by a given relative index will change | ||||
| while interpreting instructions on the encoder stream. | ||||
| +---+---------------+-----------+ | ||||
| | n | ... | d + 1 | Absolute Index | ||||
| + - +---------------+ - - - - - + | ||||
| | 0 | ... | n - d - 1 | Relative Index | ||||
| +---+---------------+-----------+ | ||||
| ^ | | ||||
| | V | ||||
| Insertion Point Dropping Point | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Example Dynamic Table Indexing - Control Stream | ||||
| Because frames from request streams can be delivered out of order | ||||
| with instructions on the control stream, relative indices are | ||||
| relative to the Base Index at the beginning of the header block (see | ||||
| Section 5.4.1). The Base Index is an absolute index. When | ||||
| interpreting the rest of the frame, the entry identified by Base | ||||
| Index has a relative index of zero. The relative indices of entries | ||||
| do not change while interpreting headers on a request or push stream. | ||||
| Base Index | ||||
| | | ||||
| V | ||||
| +---+-----+-----+-----+-------+ | ||||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | ||||
| +---+-----+ - +-----+ - + | ||||
| | 0 | ... | n-d-3 | Relative Index | ||||
| +-----+-----+-------+ | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Example Dynamic Table Indexing - Request Stream | ||||
| 2.2.2. Post-Base Indexing | ||||
| A header block on the request stream can reference entries added | ||||
| after the entry identified by the Base Index. This allows an encoder | ||||
| to process a header block in a single pass and include references to | ||||
| entries added while processing this (or other) header blocks. Newly | ||||
| added entries are referenced using Post-Base instructions. Indices | ||||
| for Post-Base instructions increase in the same direction as absolute | ||||
| indices, but the zero value is one higher than the Base Index. | ||||
| Base Index | ||||
| | | ||||
| V | ||||
| +---+-----+-----+-----+-----+ | ||||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | ||||
| +---+-----+-----+-----+-----+ | ||||
| | 1 | 0 | Post-Base Index | ||||
| +---+-----+ | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Dynamic Table Indexing - Post-Base References | ||||
| If the decoder encounters a reference to an entry which has already | ||||
| been dropped from the table or which is greater than the declared | ||||
| Largest Reference (see Section 5.4.1), this MUST be treated as a | ||||
| stream error of type "HTTP_QPACK_DECOMPRESSION_FAILED" error code. | ||||
| If this reference occurs on the control stream, this MUST be treated | ||||
| as a session error. | ||||
| 2.3. Avoiding Head-of-Line Blocking in HTTP/QUIC | ||||
| 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 Largest Reference (see Section 3.5.1) | Each header block contains a Largest Reference which identifies the | |||
| which identifies the table state necessary for decoding. If the | table state necessary for decoding. If the greatest absolute index | |||
| greatest absolute index in the dynamic table is less than the value | in the dynamic table is less than the value of the Largest Reference, | |||
| of the Largest Reference, the stream is considered "blocked." While | the stream is considered "blocked." While blocked, header field data | |||
| blocked, header field data should remain in the blocked stream's flow | should remain in the blocked stream's flow control window. When the | |||
| control window. When the Largest Reference is zero, the frame | Largest Reference is zero, the frame contains no references to the | |||
| contains no references to the dynamic table and can always be | dynamic table and can always be processed immediately. A stream | |||
| processed immediately. A stream becomes unblocked when the greatest | becomes unblocked when the greatest absolute index in the dynamic | |||
| absolute index in the dynamic table becomes greater than or equal to | table becomes greater than or equal to the Largest Reference for all | |||
| the Largest Reference for all header blocks the decoder has started | header blocks the decoder has started reading from the stream. If a | |||
| reading from the stream. | decoder encounters a header block where the actual largest reference | |||
| is not equal to the largest reference declared in the prefix, it MAY | ||||
| treat this as a stream error of type HTTP_QPACK_DECOMPRESSION_FAILED. | ||||
| A decoder can permit the possibility of blocked streams by setting | A decoder can permit the possibility of blocked streams by setting | |||
| SETTINGS_QPACK_BLOCKED_STREAMS to a non-zero value. This setting | SETTINGS_QPACK_BLOCKED_STREAMS to a non-zero value (see Section 4). | |||
| specifies an upper bound on the number of streams which can be | This setting specifies an upper bound on the number of streams which | |||
| blocked. | can be 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 be improved by referencing dynamic table | compression efficiency can be improved by referencing dynamic table | |||
| entries that are still in transit, but if there is loss or reordering | entries that are still in transit, but if there is loss or reordering | |||
| the stream can become blocked at the decoder. An encoder avoids the | the stream can become blocked at the decoder. An encoder avoids the | |||
| risk of blocking by only referencing dynamic table entries which have | risk of blocking by only referencing dynamic table entries which have | |||
| been acknowledged, but this means using literals. Since literals | been acknowledged, but this means using literals. Since literals | |||
| make the header block larger, this can result in the encoder becoming | make the header block larger, this can result in the encoder becoming | |||
| blocked on congestion or flow control limits. | blocked on congestion or flow control limits. | |||
| An encoder MUST limit the number of streams which could become | An encoder MUST limit the number of streams which could become | |||
| blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. | blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. | |||
| Note that the decoder might not actually become blocked on every | Note that the decoder might not actually become blocked on every | |||
| stream which risks becoming blocked. If the decoder encounters more | stream which risks becoming blocked. If the decoder encounters more | |||
| blocked streams than it promised to support, it SHOULD treat this as | blocked streams than it promised to support, it SHOULD treat this as | |||
| a stream error of type HTTP_QPACK_DECOMPRESSION_FAILED. | a stream error of type HTTP_QPACK_DECOMPRESSION_FAILED. | |||
| 2. Conventions and Definitions | 2.3.1. State Synchronization | |||
| The decoder stream signals key events at the decoder that permit the | ||||
| encoder to track the decoder's state. These events are: | ||||
| o Successful processing of a header block | ||||
| o Abandonment of a stream which might have remaining header blocks | ||||
| o Receipt of new dynamic table entries | ||||
| Regardless of whether a header block contained blocking references, | ||||
| the knowledge that it was processed successfully permits the encoder | ||||
| to avoid evicting entries while references remain outstanding; see | ||||
| Section 6.3.1. When a stream is reset or abandoned, the indication | ||||
| that these header blocks will never be processed serves a similar | ||||
| function; see Section 5.3.3. | ||||
| For the encoder to identify which dynamic table entries can be safely | ||||
| used without a stream becoming blocked, the encoder tracks the | ||||
| absolute index of the decoder's Largest Known Received entry. | ||||
| When blocking references are permitted, the encoder uses | ||||
| acknowledgement of header blocks to identify the Largest Known | ||||
| Received index, as described in Section 5.3.2. | ||||
| To acknowledge dynamic table entries which are not referenced by | ||||
| header blocks, for example because the encoder or the decoder have | ||||
| chosen not to risk blocked streams, the decoder sends a Table State | ||||
| Synchronize instruction (see Section 5.3.1). | ||||
| 3. 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 BCP | "OPTIONAL" in this document are to be interpreted as described in BCP | |||
| 14 [RFC2119] [RFC8174] when, and only when, they appear in all | 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: | Definitions of terms that are used in this document: | |||
| Header: A name-value pair sent as part of an HTTP message. | Header: A name-value pair sent as part of an HTTP message. | |||
| skipping to change at page 5, line 30 ¶ | skipping to change at page 9, line 13 ¶ | |||
| Header block: The compressed representation of a header set. | Header block: The compressed representation of a header set. | |||
| Encoder: An implementation which transforms a header set into a | Encoder: An implementation which transforms a header set into a | |||
| header block. | header block. | |||
| Decoder: An implementation which transforms a header block into a | Decoder: An implementation which transforms a header block into a | |||
| header set. | header set. | |||
| QPACK is a name, not an acronym. | QPACK is a name, not an acronym. | |||
| 2.1. Notational Conventions | 3.1. Notational Conventions | |||
| Diagrams use the format described in Section 3.1 of [RFC2360], with | Diagrams use the format described in Section 3.1 of [RFC2360], with | |||
| the following additional conventions: | the following additional conventions: | |||
| x (A) Indicates that x is A bits long | x (A) Indicates that x is A bits long | |||
| x (A+) Indicates that x uses the prefixed integer encoding defined | x (A+) Indicates that x uses the prefixed integer encoding defined | |||
| in Section 5.1 of [RFC7541], beginning with an A-bit prefix. | in Section 5.1 of [RFC7541], beginning with an A-bit prefix. | |||
| x ... Indicates that x is variable-length and extends to the end of | x ... Indicates that x is variable-length and extends to the end of | |||
| the region. | the region. | |||
| 3. Wire Format | 4. Configuration | |||
| QPACK defines two settings which are included in the HTTP/QUIC | ||||
| SETTINGS frame. | ||||
| SETTINGS_HEADER_TABLE_SIZE (0x1): An integer with a maximum value of | ||||
| 2^30 - 1. The default value is 4,096 bytes. See (TODO: reference | ||||
| PR#1357) for usage. | ||||
| SETTINGS_QPACK_BLOCKED_STREAMS (0x7): An integer with a maximum | ||||
| value of 2^16 - 1. The default value is 100. See Section 2.3. | ||||
| 5. Wire Format | ||||
| QPACK instructions occur in three locations, each of which uses a | QPACK instructions occur in three locations, each of which uses a | |||
| separate instruction space: | separate instruction space: | |||
| o Table updates are carried by a unidirectional stream from encoder | o The encoder stream is a unidirectional stream of type "0x48" | |||
| to decoder. Instructions on this stream modify the dynamic table | (ASCII 'H') which carries table updates from encoder to decoder. | |||
| state without generating output to any particular request. | Instructions on this stream modify the dynamic table state without | |||
| generating output to any particular request. | ||||
| o Acknowledgements of table modifications and header processing are | o The decoder stream is a unidirectional stream of type "0x68" | |||
| carried by a unidirectional stream from decoder to encoder. | (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 | o Finally, the contents of HEADERS and PUSH_PROMISE frames on | |||
| request streams reference the QPACK table state. | request streams and push streams reference the QPACK table state. | |||
| There MUST be exactly one of each unidirectional stream type in each | ||||
| direction. Receipt of a second instance of either stream type MUST | ||||
| be treated as a connection error of HTTP_WRONG_STREAM_COUNT. 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 | This section describes the instructions which are possible on each | |||
| stream type. | stream type. | |||
| All table updates occur on the control stream. Request streams only | All table updates occur on the encoder stream. Request streams and | |||
| carry header blocks that do not modify the state of the table. | push streams only carry header blocks that do not modify the state of | |||
| the table. | ||||
| 3.1. Primitives | 5.1. Primitives | |||
| 5.1.1. Prefixed Integers | ||||
| The prefixed integer from Section 5.1 of [RFC7541] is used heavily | The prefixed integer from Section 5.1 of [RFC7541] is used heavily | |||
| throughout this document. The string literal, defined by Section 5.2 | throughout this document. The format from [RFC7541] is used | |||
| of [RFC7541], is used with the following modification. | unmodified. | |||
| 5.1.2. String Literals | ||||
| The string literal defined by Section 5.2 of [RFC7541] is also used | ||||
| 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 flag (indicating whether the string is Huffman- | begin with a single flag (indicating whether the string is Huffman- | |||
| coded), followed by the Length encoded as a 7-bit prefix integer, and | coded), followed by the Length encoded as a 7-bit prefix integer, and | |||
| finally Length octets of data. | finally Length octets of data. When Huffman encoding is enabled, the | |||
| Huffman table from Appendix B of [RFC7541] is used without | ||||
| modification. | ||||
| QPACK permits strings to begin other than on a byte boundary. An | This document expands the definition of string literals and permits | |||
| "N-bit prefix string literal" begins with the same Huffman flag, | them to begin other than on a byte boundary. An "N-bit prefix string | |||
| followed by the length encoded as an (N-1)-bit prefix integer. The | literal" begins with the same Huffman flag, followed by the length | |||
| remainder of the string literal is unmodified. | encoded as an (N-1)-bit prefix integer. 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. | |||
| 3.2. Indexing | 5.2. QPACK Encoder Stream | |||
| Entries in the QPACK static and dynamic tables are addressed | ||||
| separately. | ||||
| Entries in the static table have the same indices at all times. The | ||||
| static table is defined in Appendix A of [RFC7541]. Note that | ||||
| because HPACK did not use zero-based references, there is no value at | ||||
| index zero of the static table. | ||||
| Entries are inserted into the dynamic table over time. Each entry | ||||
| possesses both an absolute index which is fixed for the lifetime of | ||||
| that entry and a relative index which changes over time based on the | ||||
| context of the reference. The first entry inserted has an absolute | ||||
| index of "1"; indices increase sequentially with each insertion. | ||||
| On the control stream, a relative index of "0" always refers to the | ||||
| most recently inserted value in the dynamic table. Note that this | ||||
| means the entry referenced by a given relative index can change while | ||||
| interpreting a HEADERS frame as new entries are inserted. | ||||
| +---+---------------+-------+ | ||||
| | n | ... | d + 1 | Absolute Index | ||||
| + - +---------------+ - + | ||||
| | 0 | ... | n-d-1 | Relative Index | ||||
| +---+---------------+-------+ | ||||
| ^ | | ||||
| | V | ||||
| Insertion Point Dropping Point | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Example Dynamic Table Indexing - Control Stream | ||||
| Because frames from request streams can be delivered out of order | ||||
| with instructions on the control stream, relative indices are | ||||
| relative to the Base Index at the beginning of the header block (see | ||||
| Section 3.5.1). The Base Index is the absolute index of the entry | ||||
| which has the relative index of zero when interpreting the frame. | ||||
| The relative indices of entries do not change while interpreting | ||||
| headers on a request or push stream. | ||||
| Base Index | ||||
| | | ||||
| V | ||||
| +---+-----+-----+-----+-------+ | ||||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | ||||
| +---+-----+ - +-----+ - + | ||||
| | 0 | ... | n-d-3 | Relative Index | ||||
| +-----+-----+-------+ | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Example Dynamic Table Indexing - Request Stream | ||||
| Entries with an absolute index greater than a frame's Base Index can | ||||
| be referenced using specific Post-Base instructions. The relative | ||||
| indices of Post-Base references count up from Base Index. | ||||
| Base Index | ||||
| | | ||||
| V | ||||
| +---+-----+-----+-----+-----+ | ||||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | ||||
| +---+-----+-----+-----+-----+ | ||||
| | 1 | 0 | Post-Base Index | ||||
| +---+-----+ | ||||
| n = count of entries inserted | ||||
| d = count of entries dropped | ||||
| Dynamic Table Indexing - Post-Base References | ||||
| If the decoder encounters a reference to an entry which has already | ||||
| been dropped from the table or which is greater than the declared | ||||
| Largest Reference, this MUST be treated as a stream error of type | ||||
| "HTTP_QPACK_DECOMPRESSION_FAILED" error code. If this reference | ||||
| occurs on the control stream, this MUST be treated as a session | ||||
| error. | ||||
| 3.3. QPACK Encoder Stream | ||||
| 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. | |||
| Each set of encoder instructions is prefaced by its length, encoded | The contents of the encoder stream are an unframed sequence of the | |||
| as a variable length integer with an 8-bit prefix. Instructions MUST | following instructions. | |||
| NOT span more than one block. | ||||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | Block Length (8+) | | ||||
| +-------------------------------+ | ||||
| | Instruction Block (*) ... | ||||
| +-------------------------------+ | ||||
| Encoder instruction block | ||||
| 3.3.1. Insert With Name Reference | 5.2.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 header field name is represented using the relative | (S=0) table. The header field name is represented using the relative | |||
| index of that entry, which is represented as an integer with a 6-bit | index of that entry, which is represented as an integer with a 6-bit | |||
| prefix (see Section 5.1 of [RFC7541]). | prefix (see Section 5.1 of [RFC7541]). | |||
| The header name reference is followed by the header field value | The header name reference is followed by the header field value | |||
| skipping to change at page 9, line 23 ¶ | skipping to change at page 11, line 41 ¶ | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | S | Name Index (6+) | | | 1 | S | Name Index (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Insert Header Field -- Indexed Name | Insert Header Field -- Indexed Name | |||
| 3.3.2. Insert Without Name Reference | 5.2.2. Insert Without Name Reference | |||
| An addition to the header table where both the header field name and | An addition to the header table where both the header field name and | |||
| the header field value are represented as string literals (see | the header field value are represented as string literals (see | |||
| Section 3.1) starts with the '01' two-bit pattern. | Section 5.1) starts with the '01' two-bit pattern. | |||
| The name is represented as a 6-bit prefix string literal, while the | The name is represented as a 6-bit prefix string literal, while the | |||
| value is represented as an 8-bit prefix string literal. | value is represented as an 8-bit prefix string literal. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | H | Name Length (5+) | | | 0 | 1 | H | Name Length (5+) | | |||
| +---+---+---+-------------------+ | +---+---+---+-------------------+ | |||
| | Name String (Length octets) | | | Name String (Length octets) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Insert Header Field -- New Name | Insert Header Field -- New Name | |||
| 3.3.3. Duplicate | 5.2.3. Duplicate | |||
| Duplication of an existing entry in the dynamic table starts with the | Duplication of an existing entry in the dynamic table starts with the | |||
| '000' three-bit pattern. The relative index of the existing entry is | '000' three-bit pattern. The relative index of the existing entry is | |||
| represented as an integer with a 5-bit prefix. | represented as an integer with a 5-bit prefix. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 0 | 0 | Index (5+) | | | 0 | 0 | 0 | Index (5+) | | |||
| +---+---+---+-------------------+ | +---+---+---+-------------------+ | |||
| Figure 1: Duplicate | Figure 1: Duplicate | |||
| The existing entry is re-inserted into the dynamic table without | The existing entry is re-inserted into the dynamic table without | |||
| resending either the name or the value. This is useful to mitigate | resending either the name or the value. This is useful to mitigate | |||
| the eviction of older entries which are frequently referenced, both | the eviction of older entries which are frequently referenced, both | |||
| to avoid the need to resend the header and to avoid the entry in the | to avoid the need to resend the header and to avoid the entry in the | |||
| table blocking the ability to insert new headers. | table blocking the ability to insert new headers. | |||
| 3.3.4. Dynamic Table Size Update | 5.2.4. Dynamic Table Size Update | |||
| An encoder informs the decoder of a change to the size of the dynamic | An encoder informs the decoder of a change to the size of the dynamic | |||
| table using an instruction which begins with the '001' three-bit | table using an instruction which begins with the '001' three-bit | |||
| pattern. The new maximum table size is represented as an integer | pattern. The new maximum table size is represented as an integer | |||
| with a 5-bit prefix (see Section 5.1 of [RFC7541]). | with a 5-bit 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 | 1 | Max size (5+) | | | 0 | 0 | 1 | Max size (5+) | | |||
| +---+---+---+-------------------+ | +---+---+---+-------------------+ | |||
| Figure 2: Maximum Dynamic Table Size Change | Figure 2: Maximum Dynamic Table Size Change | |||
| The new maximum size MUST be lower than or equal to the limit | The new maximum size MUST be lower than or equal to the limit | |||
| determined by the protocol using QPACK. A value that exceeds this | determined by the protocol using QPACK. A value that exceeds this | |||
| limit MUST be treated as a decoding error. In HTTP/QUIC, this limit | limit MUST be treated as a decoding error. In HTTP/QUIC, this limit | |||
| is the value of the SETTINGS_HEADER_TABLE_SIZE parameter (see | is the value of the SETTINGS_HEADER_TABLE_SIZE parameter (see | |||
| [QUIC-HTTP]) received from the decoder. | Section 4) received from the decoder. | |||
| Reducing the maximum size of the dynamic table can cause entries to | Reducing the maximum size of the dynamic table can cause entries to | |||
| be evicted (see Section 4.3 of [RFC7541]). This MUST NOT cause the | be evicted (see Section 4.3 of [RFC7541]). This MUST NOT cause the | |||
| eviction of entries with outstanding references (see Section 4.3). | eviction of entries with outstanding references (see Section 6.3). | |||
| Changing the size of the dynamic table is not acknowledged as this | ||||
| instruction does not insert an entry. | ||||
| 3.4. QPACK Decoder Stream | 5.3. QPACK Decoder Stream | |||
| The decoder stream carries information used to ensure consistency of | The decoder stream carries information used to ensure consistency of | |||
| the dynamic table. Information is sent from the QPACK decoder to the | the dynamic table. Information is sent from the QPACK decoder to the | |||
| QPACK encoder; that is, the server informs the client about the | QPACK encoder; that is, the server informs the client about the | |||
| processing of the client's header blocks and table updates, and the | processing of the client's header blocks and table updates, and the | |||
| client informs the server about the processing of the server's header | client informs the server about the processing of the server's header | |||
| blocks and table updates. | blocks and table updates. | |||
| 3.4.1. Table State Synchronize | The contents of the decoder stream are an unframed sequence of the | |||
| following instructions. | ||||
| After processing a set of instructions on the encoder stream, the | 5.3.1. Table State Synchronize | |||
| decoder will emit a Table State Synchronize instruction on the | ||||
| decoder stream. The instruction begins with the '1' one-bit pattern. | The Table State Synchronize instruction begins with the '00' two-bit | |||
| The instruction specifies the total number of dynamic table inserts | pattern. The instruction specifies the total number of dynamic table | |||
| and duplications since the last Table State Synchronize, encoded as a | inserts and duplications since the last Table State Synchronize or | |||
| 7-bit prefix integer. The encoder uses this value to determine which | Header Acknowledgement that increased the Largest Known Received | |||
| table entries are vulnerable to head-of-line blocking. A decoder MAY | dynamic table entry. This is encoded as a 6-bit prefix integer. The | |||
| coalesce multiple synchronization updates into a single update. | encoder uses this value to determine which table entries might cause | |||
| a stream to become blocked, as described in Section 2.3.1. | ||||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | Insert Count (7+) | | | 0 | 0 | Insert Count (6+) | | |||
| +---+---------------------------+ | +---+---+-----------------------+ | |||
| Figure 3: Table Size Synchronize | Figure 3: Table State Synchronize | |||
| 3.4.2. Header Acknowledgement | A decoder chooses when to emit Table State Synchronize instructions. | |||
| Emitting a Table State Synchronize after adding each new dynamic | ||||
| table entry will provide the most timely feedback to the encoder, but | ||||
| could be redundant with other decoder feedback. By delaying a | ||||
| Table State Synchronize, a decoder might be able to coalesce multiple | ||||
| Table State Synchronize instructions, or replace them entirely with | ||||
| Header Acknowledgements. However, delaying too long may lead to | ||||
| compression inefficiencies if the encoder waits for an entry to be | ||||
| acknowledged before using it. | ||||
| 5.3.2. Header Acknowledgement | ||||
| After processing a header block on a request or push stream, the | After processing a header block on a request or push stream, the | |||
| decoder emits a Header Acknowledgement instruction on the decoder | decoder emits a Header Acknowledgement instruction on the decoder | |||
| stream. The instruction begins with the '0' one-bit pattern and | stream. The instruction begins with the '1' one-bit pattern and | |||
| includes the request stream's stream ID, encoded as a 7-bit prefix | includes the request stream's stream ID, encoded as a 7-bit prefix | |||
| integer. It is used by the peer's QPACK encoder to know when it is | integer. It is used by the peer's QPACK encoder to know when it is | |||
| safe to evict an entry. | safe to evict an entry. | |||
| 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 header | |||
| frames on each stream are received and processed in order, this gives | frames on each stream are received and processed in order, this gives | |||
| the encoder precise feedback on which header blocks within a stream | the encoder precise feedback on which header blocks within a stream | |||
| have been fully processed. | have been fully processed. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | Stream ID (7+) | | | 1 | Stream ID (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| Figure 4: Header Acknowledgement | Figure 4: Header Acknowledgement | |||
| 3.5. Request and Push Streams | When blocking references are permitted, the encoder uses | |||
| acknowledgement of header blocks to update the Largest Known Received | ||||
| index. If a header block was potentially blocking, the | ||||
| acknowledgement implies that the decoder has received all dynamic | ||||
| table state necessary to process the header block. If the Largest | ||||
| Reference of an acknowledged header block was greater than the | ||||
| encoder's current Largest Known Received index, the block's Largest | ||||
| Reference becomes the new Largest Known Received. | ||||
| 5.3.3. Stream Cancellation | ||||
| A stream that is reset might have multiple outstanding header blocks. | ||||
| A decoder that receives a stream reset before the end of a stream | ||||
| generates a Stream Cancellation instruction on the decoder stream. | ||||
| Similarly, a decoder that abandons reading of a stream needs to | ||||
| signal this using the Stream Cancellation instruction. This signals | ||||
| to the encoder that all references to the dynamic table on that | ||||
| stream are no longer outstanding. | ||||
| An encoder cannot infer from this instruction that any updates to the | ||||
| dynamic table have been received. | ||||
| The instruction begins with the '01' two-bit pattern. The | ||||
| instruction includes the stream ID of the affected stream - a request | ||||
| or push stream - encoded as a 6-bit prefix integer. | ||||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 1 | Stream ID (6+) | | ||||
| +---+---+-----------------------+ | ||||
| Figure 5: Stream Cancellation | ||||
| 5.4. Request and Push Streams | ||||
| HEADERS and PUSH_PROMISE frames on request and push streams reference | HEADERS and PUSH_PROMISE frames on request and push streams reference | |||
| the dynamic table in a particular state without modifying it. Frames | the dynamic table in a particular state without modifying it. Frames | |||
| on these streams emit the headers for an HTTP request or response. | on these streams emit the headers for an HTTP request or response. | |||
| 3.5.1. Header Data Prefix | 5.4.1. Header Data Prefix | |||
| Header data is prefixed with two integers, "Largest Reference" and | Header data is prefixed with two integers, "Largest Reference" and | |||
| "Base Index". | "Base Index". | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | Largest Reference (8+) | | | Largest Reference (8+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | S | Delta Base Index (7+) | | | S | Delta Base Index (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Compressed Headers ... | | Compressed Headers ... | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Figure 5: Frame Payload | Figure 6: Frame Payload | |||
| "Largest Reference" identifies the largest absolute dynamic index | "Largest Reference" identifies the largest absolute dynamic index | |||
| referenced in the block. Blocking decoders use the Largest Reference | referenced in the block. Blocking decoders use the Largest Reference | |||
| to determine when it is safe to process the rest of the block. | to determine when it is safe to process the rest of the block. | |||
| "Base Index" is used to resolve references in the dynamic table as | "Base Index" is used to resolve references in the dynamic table as | |||
| described in Section 3.2. To save space, Base Index is encoded | described in Section 2.2.1. | |||
| relative to Largest Reference using a one-bit sign flag. | ||||
| baseIndex = largestReference + deltaBaseIndex | To save space, Base Index is encoded relative to Largest Reference | |||
| using a one-bit sign and the "Delta Base Index" value. A sign bit of | ||||
| 0 indicates that the Base Index has an absolute index that is greater | ||||
| than or equal to the Largest Reference; the value of Delta Base Index | ||||
| is added to the Largest Reference to determine the absolute value of | ||||
| the Base Index. A sign bit of 1 indicates that the Base Index is | ||||
| less than the Largest Reference. That is: | ||||
| If the encoder inserted entries to the table while the encoding the | if sign == 0: | |||
| block, Largest Reference will be greater than Base Index, so | baseIndex = largestReference + deltaBaseIndex | |||
| deltaBaseIndex will be negative and encoded with S=1. If the block | else: | |||
| did not reference the most recent entry in the table and did not | baseIndex = largestReference - deltaBaseIndex | |||
| insert any new entries, Largest Reference will be less than Base | ||||
| Index, so deltaBaseIndex will be positive and encoded with S=0. When | ||||
| Largest Reference and Base Index are equal, deltaBaseIndex is 0 and | ||||
| encoded with S=0. | ||||
| 3.5.2. Instructions | A single-pass encoder is expected to determine the absolute value of | |||
| Base Index before encoding a header block. If the encoder inserted | ||||
| entries in the dynamic table while encoding the header block, Largest | ||||
| Reference will be greater than Base Index, so the encoded difference | ||||
| is negative and the sign bit is set to 1. If the header block did | ||||
| not reference the most recent entry in the table and did not insert | ||||
| any new entries, Base Index will be greater than the Largest | ||||
| Reference, so the delta will be positive and the sign bit is set to | ||||
| 0. | ||||
| 3.5.2.1. Indexed Header Field | An encoder that produces table updates before encoding a header block | |||
| might set Largest Reference and Base Index to the same value. When | ||||
| Largest Reference and Base Index are equal, the Delta Base Index is | ||||
| encoded with a zero sign bit. A sign bit set to 1 when the Delta | ||||
| Base Index is 0 MUST be treated as a decoder error. | ||||
| A header block that does not reference the dynamic table can use any | ||||
| value for Base Index; setting both Largest Reference and Base Index | ||||
| to zero is the most efficient encoding. | ||||
| 5.4.2. Instructions | ||||
| 5.4.2.1. Indexed Header Field | ||||
| An indexed header field representation identifies an entry in either | An indexed header field representation identifies an entry in either | |||
| the static table or the dynamic table and causes that header field to | the static table or the dynamic table and causes that header field to | |||
| be added to the decoded header list, as described in Section 3.2 of | be added to the decoded header list, as described in Section 3.2 of | |||
| [RFC7541]. | [RFC7541]. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 1 | S | Index (6+) | | | 1 | S | Index (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| skipping to change at page 13, line 20 ¶ | skipping to change at page 17, line 5 ¶ | |||
| Indexed Header Field | Indexed Header Field | |||
| If the entry is in the static table, or in the dynamic table with an | If the entry is in the static table, or in the dynamic table with an | |||
| absolute index less than or equal to Base Index, this representation | absolute index less than or equal to Base Index, this representation | |||
| starts with the '1' 1-bit pattern, followed by the "S" bit indicating | starts with the '1' 1-bit pattern, followed by the "S" bit indicating | |||
| whether the reference is into the static (S=1) or dynamic (S=0) | whether the reference is into the static (S=1) or dynamic (S=0) | |||
| table. Finally, the relative index of the matching header field is | table. Finally, the relative index of the matching header field is | |||
| represented as an integer with a 6-bit prefix (see Section 5.1 of | represented as an integer with a 6-bit prefix (see Section 5.1 of | |||
| [RFC7541]). | [RFC7541]). | |||
| 0 1 2 3 4 5 6 7 | 5.4.2.2. Indexed Header Field With Post-Base Index | |||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 1 | 0 | 0 | Index (4+) | | ||||
| +---+---+-----------------------+ | ||||
| Indexed Header Field | ||||
| 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 Base Index, the representation starts with the '0100' 4-bit | than Base Index, the representation starts with the '0001' 4-bit | |||
| pattern, followed by the post-base index (see Section 3.2) of the | pattern, followed by the post-base index (see Section 2.2.1) of the | |||
| matching header field, represented as an integer with a 4-bit prefix | matching header field, represented as an integer with a 4-bit prefix | |||
| (see Section 5.1 of [RFC7541]). | (see Section 5.1 of [RFC7541]). | |||
| 3.5.2.2. Literal Header Field With Name Reference | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | ||||
| | 0 | 0 | 0 | 1 | Index (4+) | | ||||
| +---+---+---+---+---------------+ | ||||
| Indexed Header Field with Post-Base Index | ||||
| 5.4.2.3. Literal Header Field With Name Reference | ||||
| A literal header field with a name reference represents a header | A literal header field with a name reference represents a header | |||
| where the header field name matches the header field name of an entry | where the header field name matches the header field name of an entry | |||
| stored in the static table or the dynamic table. | stored in the static table or the dynamic table. | |||
| If the entry is in the static table, or in the dynamic table with an | If the entry is in the static table, or in the dynamic table with an | |||
| absolute index less than or equal to Base Index, this representation | absolute index less than or equal to Base Index, this representation | |||
| starts with the '00' two-bit pattern. If the entry is in the dynamic | starts with the '01' two-bit pattern. If the entry is in the dynamic | |||
| table with an absolute index greater than Base Index, the | table with an absolute index greater than Base Index, the | |||
| representation starts with the '0101' four-bit pattern. | representation starts with the '0000' four-bit pattern. | |||
| 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). | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 0 | N | S |Name Index (4+)| | | 0 | 1 | N | S |Name Index (4+)| | |||
| +---+---+-----------------------+ | +---+---+---+---+---------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Literal Header Field With Name Reference | Literal Header Field With Name Reference | |||
| For entries in the static table or in the dynamic table with an | For entries in the static table or in the dynamic table with an | |||
| absolute index less than or equal to Base Index, the header field | absolute index less than or equal to Base Index, the header field | |||
| name is represented using the relative index of that entry, which is | name 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. | |||
| 5.4.2.4. Literal Header Field With Post-Base Name Reference | ||||
| For entries in the dynamic table with an absolute index greater than | ||||
| Base Index, the header field name is represented using the post-base | ||||
| index of that entry (see Section 2.2.1) encoded as an integer with a | ||||
| 3-bit prefix. | ||||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | 0 | 1 | N |NameIdx(3+)| | | 0 | 0 | 0 | 0 | N |NameIdx(3+)| | |||
| +---+---+-----------------------+ | +---+---+---+---+---+-----------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Literal Header Field With Post-Base Name Reference | Literal Header Field With Post-Base Name Reference | |||
| For entries in the dynamic table with an absolute index greater than | 5.4.2.5. Literal Header Field Without Name Reference | |||
| Base Index, the header field name is represented using the post-base | ||||
| index of that entry (see Section 3.2) encoded as an integer with a | ||||
| 3-bit prefix. | ||||
| 3.5.2.3. Literal Header Field Without Name Reference | ||||
| An addition to the header table where both the header field name and | An addition to the header table where both the header field name and | |||
| the header field value are represented as string literals (see | the header field value are represented as string literals (see | |||
| Section 3.1) starts with the '011' three-bit pattern. | Section 5.1) starts with the '001' three-bit pattern. | |||
| The fourth bit, 'N', indicates whether an intermediary is permitted | The fourth bit, 'N', indicates whether an intermediary is permitted | |||
| to add this header to the dynamic header table on subsequent hops. | to add this header to the dynamic header table on subsequent hops. | |||
| When the 'N' bit is set, the encoded header MUST always be encoded | When the 'N' bit is set, the encoded header 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 | |||
| header field that it received represented as a literal header field | header field that it received represented as a literal header field | |||
| with the 'N' bit set, it MUST use a literal representation to forward | with the 'N' bit set, it MUST use a literal representation to forward | |||
| this header field. This bit is intended for protecting header field | this header field. This bit is intended for protecting header field | |||
| values that are not to be put at risk by compressing them (see | values that are not to be put at risk by compressing them (see | |||
| Section 7.1 of [RFC7541] for more details). | Section 7.1 of [RFC7541] for more details). | |||
| The name is represented as a 4-bit prefix string literal, while the | The name is represented as a 4-bit prefix string literal, while the | |||
| value is represented as an 8-bit prefix string literal. | value is represented as an 8-bit prefix string literal. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 1 | 1 | N | H |NameLen(3+)| | | 0 | 0 | 1 | N | H |NameLen(3+)| | |||
| +---+---+---+-------------------+ | +---+---+---+---+---+-----------+ | |||
| | Name String (Length octets) | | | Name String (Length octets) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | H | Value Length (7+) | | | H | Value Length (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Value String (Length octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Literal Header Field Without Name Reference | Literal Header Field Without Name Reference | |||
| 4. Encoding Strategies | 6. Encoding Strategies | |||
| 4.1. Single pass encoding | 6.1. Single Pass Encoding | |||
| An encoder making a single pass over a list of headers must choose | An encoder making a single pass over a list of headers must choose | |||
| Base Index before knowing Largest Reference. When trying to | Base Index before knowing Largest Reference. When trying to | |||
| reference a header inserted to the table after encoding has begun, | reference a header inserted to the table after encoding has begun, | |||
| the entry is encoded with different instructions that tell the | the entry is encoded with different instructions that tell the | |||
| decoder to use an absolute index greater than the Base Index. | decoder to use an absolute index greater than the Base Index. | |||
| 4.2. Preventing Eviction Races | 6.2. Preventing Eviction Races | |||
| Due to out-of-order arrival, QPACK's eviction algorithm requires | Due to out-of-order arrival, QPACK's eviction algorithm requires | |||
| changes (relative to HPACK) to avoid the possibility that an indexed | changes (relative to HPACK) to avoid the possibility that an indexed | |||
| representation is decoded after the referenced entry has already been | representation is decoded after the referenced entry has already been | |||
| evicted. QPACK employs a two-phase eviction algorithm, in which the | evicted. QPACK employs a two-phase eviction algorithm, in which the | |||
| encoder will not evict entries that have outstanding (unacknowledged) | encoder will not evict entries that have outstanding (unacknowledged) | |||
| references. | references. | |||
| 4.3. Reference Tracking | 6.3. 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 already been evicted. An encoder also respects the limit set by | has already been evicted. An encoder also respects the limit set by | |||
| the decoder on the number of streams that are allowed to become | the decoder on the number of streams that are allowed to become | |||
| blocked. Even if the decoder is willing to tolerate blocked streams, | blocked. Even if the decoder is willing to tolerate blocked streams, | |||
| the encoder might choose to avoid them in certain cases. | the encoder might choose to avoid them in certain cases. | |||
| In order to enable this, the encoder will need to track outstanding | In order to enable this, the encoder will need to track outstanding | |||
| (unacknowledged) header blocks and table updates using feedback | (unacknowledged) header blocks and table updates using feedback | |||
| received from the decoder. | received from the decoder. | |||
| 4.3.1. Blocked Eviction | 6.3.1. Blocked Eviction | |||
| The encoder MUST NOT permit an entry to be evicted while a reference | The encoder MUST NOT permit an entry to be evicted while a reference | |||
| to that entry remains unacknowledged. If a new header to be inserted | to that entry remains unacknowledged. If a new header to be inserted | |||
| into the dynamic table would cause the eviction of such an entry, the | into the dynamic table would cause the eviction of such an entry, the | |||
| encoder MUST NOT emit the insert instruction until the reference has | encoder MUST NOT emit the insert instruction until the reference has | |||
| been processed by the decoder and acknowledged. | been processed by the decoder and acknowledged. | |||
| The encoder can emit a literal representation for the new header in | The encoder can emit a literal representation for the new header in | |||
| order to avoid encoding delays, and MAY insert the header into the | order to avoid encoding delays, and MAY insert the header into the | |||
| table later if desired. | table later if desired. | |||
| To ensure that the blocked eviction case is rare, references to the | To ensure that the blocked eviction case is rare, references to the | |||
| oldest entries in the dynamic table SHOULD be avoided. When one of | oldest entries in the dynamic table SHOULD be avoided. When one of | |||
| the oldest entries in the table is still actively used for | the oldest entries in the table is still actively used for | |||
| references, the encoder SHOULD emit an Duplicate representation | references, the encoder SHOULD emit an Duplicate representation | |||
| instead (see Section 3.3.3). | instead (see Section 5.2.3). | |||
| 4.3.2. Blocked Decoding | 6.3.2. Blocked Decoding | |||
| For header blocks encoded in non-blocking mode, the encoder needs to | For header blocks encoded in non-blocking mode, the encoder needs to | |||
| forego indexed representations that refer to table updates which have | forego indexed representations that refer to table updates which have | |||
| not yet been acknowledged with Section 3.4. Since all table updates | not yet been acknowledged with Section 5.3. Since all table updates | |||
| are processed in sequence on the control stream, an index into the | are processed in sequence on the control stream, an index into the | |||
| dynamic table is sufficient to track which entries have been | dynamic table is sufficient to track which entries have been | |||
| acknowledged. | acknowledged. | |||
| To track blocked streams, the necessary Base Index value for each | To track blocked streams, the necessary Base Index value for each | |||
| stream can be used. Whenever the decoder processes a table update, | stream can be used. Whenever the decoder processes a table update, | |||
| it can begin decoding any blocked streams that now have their | it can begin decoding any blocked streams that now have their | |||
| dependencies satisfied. | dependencies satisfied. | |||
| 4.4. Speculative table updates | 6.4. Speculative table updates | |||
| Implementations can _speculatively_ send header frames on the HTTP | Implementations can _speculatively_ send header frames on the HTTP | |||
| Control Streams which are not needed for any current HTTP request or | Control Streams which are not needed for any current HTTP request or | |||
| response. Such headers could be used strategically to improve | response. Such headers could be used strategically to improve | |||
| performance. For instance, the encoder might decide to _refresh_ by | performance. For instance, the encoder might decide to _refresh_ by | |||
| sending Duplicate representations for popular header fields | sending Duplicate representations for popular header fields | |||
| (Section 3.3.3), ensuring they have small indices and hence minimal | (Section 5.2.3), ensuring they have small indices and hence minimal | |||
| size on the wire. | size on the wire. | |||
| 4.5. Sample One Pass Encoding Algorithm | 6.5. Sample One Pass Encoding Algorithm | |||
| Pseudo-code for single pass encoding, excluding handling of | Pseudo-code for single pass encoding, excluding handling of | |||
| duplicates, non-blocking mode, and reference tracking. | duplicates, non-blocking mode, and reference tracking. | |||
| baseIndex = dynamicTable.baseIndex | baseIndex = dynamicTable.baseIndex | |||
| largestReference = 0 | largestReference = 0 | |||
| for header in headers: | for header in headers: | |||
| staticIdx = staticTable.getIndex(header) | staticIdx = staticTable.getIndex(header) | |||
| if staticIdx: | if staticIdx: | |||
| encodeIndexReference(streamBuffer, staticIdx) | encodeIndexReference(streamBuffer, staticIdx) | |||
| skipping to change at page 17, line 48 ¶ | skipping to change at page 21, line 43 ¶ | |||
| else: | else: | |||
| # Dynamic index reference | # Dynamic index reference | |||
| assert(dynamicIdx) | assert(dynamicIdx) | |||
| largestReference = max(largestReference, dynamicIdx) | largestReference = max(largestReference, dynamicIdx) | |||
| # Encode dynamicIdx, possibly with dynamicIdx above baseIndex | # Encode dynamicIdx, possibly with dynamicIdx above baseIndex | |||
| encodeDynamicIndexReference(streamBuffer, dynamicIdx, | encodeDynamicIndexReference(streamBuffer, dynamicIdx, | |||
| baseIndex) | baseIndex) | |||
| # encode the prefix | # encode the prefix | |||
| encodeInteger(prefixBuffer, 0x00, largestReference, 8) | encodeInteger(prefixBuffer, 0x00, largestReference, 8) | |||
| delta = largestReference - baseIndex | if baseIndex >= largestReference: | |||
| sign = delta > 0 ? 0x80 : 0 | encodeInteger(prefixBuffer, 0, baseIndex - largestReference, 7) | |||
| encodeInteger(prefixBuffer, sign, delta, 7) | else: | |||
| encodeInteger(prefixBuffer, 0x80, | ||||
| largestReference - baseIndex, 7) | ||||
| return controlBuffer, prefixBuffer + streamBuffer | return controlBuffer, prefixBuffer + streamBuffer | |||
| 5. Security Considerations | 7. Security Considerations | |||
| TBD. | TBD. | |||
| 6. IANA Considerations | 8. IANA Considerations | |||
| None. | 8.1. Settings Registration | |||
| 7. References | This document creates two new settings in the "HTTP/QUIC Settings" | |||
| registry established in [QUIC-HTTP]. | ||||
| 7.1. Normative References | The entries in the following table are registered by this document. | |||
| +-----------------------+------+---------------+ | ||||
| | Setting Name | Code | Specification | | ||||
| +-----------------------+------+---------------+ | ||||
| | HEADER_TABLE_SIZE | 0x1 | Section 4 | | ||||
| | | | | | ||||
| | QPACK_BLOCKED_STREAMS | 0x7 | Section 4 | | ||||
| +-----------------------+------+---------------+ | ||||
| 8.2. Stream Type Registration | ||||
| This document creates two new settings in the "HTTP/QUIC Stream Type" | ||||
| registry established in [QUIC-HTTP]. | ||||
| The entries in the following table are registered by this document. | ||||
| +----------------------+------+---------------+--------+ | ||||
| | Stream Type | Code | Specification | Sender | | ||||
| +----------------------+------+---------------+--------+ | ||||
| | QPACK Encoder Stream | 0x48 | Section 5 | Both | | ||||
| | | | | | | ||||
| | QPACK Decoder Stream | 0x68 | Section 5 | Both | | ||||
| +----------------------+------+---------------+--------+ | ||||
| 9. References | ||||
| 9.1. Normative References | ||||
| [QUIC-HTTP] | [QUIC-HTTP] | |||
| Bishop, M., "Hypertext Transfer Protocol (HTTP) over | Bishop, M., Ed., "Hypertext Transfer Protocol (HTTP) over | |||
| QUIC", draft-ietf-quic-http-12 (work in progress), April | QUIC", draft-ietf-quic-http-13 (work in progress), June | |||
| 2018. | 2018. | |||
| [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>. | |||
| [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>. | |||
| 7.2. Informative References | 9.2. Informative References | |||
| [QUIC-TRANSPORT] | [QUIC-TRANSPORT] | |||
| Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed | |||
| and Secure Transport", draft-ietf-quic-transport-11 (work | and Secure Transport", draft-ietf-quic-transport-12 (work | |||
| in progress), April 2018. | in progress), May 2018. | |||
| [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>. | |||
| [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | |||
| Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | |||
| DOI 10.17487/RFC7540, May 2015, | DOI 10.17487/RFC7540, May 2015, | |||
| <https://www.rfc-editor.org/info/rfc7540>. | <https://www.rfc-editor.org/info/rfc7540>. | |||
| 7.3. URIs | 9.3. URIs | |||
| [1] https://mailarchive.ietf.org/arch/search/?email_list=quic | [1] https://mailarchive.ietf.org/arch/search/?email_list=quic | |||
| [2] https://github.com/quicwg | [2] https://github.com/quicwg | |||
| [3] https://github.com/quicwg/base-drafts/labels/-qpack | [3] https://github.com/quicwg/base-drafts/labels/-qpack | |||
| Acknowledgments | Appendix A. Change Log | |||
| This draft draws heavily on the text of [RFC7541]. The indirect | ||||
| input of those authors is gratefully acknowledged, as well as ideas | ||||
| from: | ||||
| o Ryan Hamilton | ||||
| o Patrick McManus | *RFC Editor's Note:* Please remove this section prior to | |||
| publication of a final version of this document. | ||||
| o Kazuho Oku | A.1. Since draft-ietf-quic-qpack-00 | |||
| o Biren Roy | o Renumbered instructions for consistency (#1471, #1472) | |||
| o Ian Swett | o Decoder is allowed to validate largest reference (#1404, #1469) | |||
| o Header block acknowledgments also acknowledge the associated | ||||
| largest reference (#1370, #1400) | ||||
| o Dmitri Tikhonov | o Added an acknowledgment for unread streams (#1371, #1400) | |||
| Change Log | o Removed framing from encoder stream (#1361,#1467) | |||
| *RFC Editor's Note:* Please remove this section prior to | o Control streams use typed unidirectional streams rather than fixed | |||
| publication of a final version of this document. | stream IDs (#910,#1359) | |||
| B.1. Since draft-ietf-quic-qcram-00 | A.2. 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, | |||
| #1140, #1143) | #1140, #1143) | |||
| o Moved table updates and acknowledgments to dedicated streams | o Moved table updates and acknowledgments to dedicated streams | |||
| (#1121, #1122, #1238) | (#1121, #1122, #1238) | |||
| Acknowledgments | ||||
| This draft draws heavily on the text of [RFC7541]. The indirect | ||||
| input of those authors is gratefully acknowledged, as well as ideas | ||||
| from: | ||||
| o Ryan Hamilton | ||||
| o Patrick McManus | ||||
| o Kazuho Oku | ||||
| o Biren Roy | ||||
| o Ian Swett | ||||
| o Dmitri Tikhonov | ||||
| Buck's contribution was supported by Google during his employment | ||||
| there. | ||||
| A substantial portion of Mike's contribution was supported by | ||||
| Microsoft during his employment there. | ||||
| Authors' Addresses | Authors' Addresses | |||
| Charles 'Buck' Krasic | Charles 'Buck' Krasic | |||
| Google, Inc | Netflix | |||
| Email: ckrasic@google.com | Email: ckrasic@netflix.com | |||
| Mike Bishop | Mike Bishop | |||
| Akamai Technologies | Akamai Technologies | |||
| Email: mbishop@evequefou.be | Email: mbishop@evequefou.be | |||
| Alan Frindell (editor) | Alan Frindell (editor) | |||
| Email: afrind@fb.com | Email: afrind@fb.com | |||
| End of changes. 95 change blocks. | ||||
| 309 lines changed or deleted | 547 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||