| draft-ietf-quic-qpack-02.txt | draft-ietf-quic-qpack-03.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: February 16, 2019 Akamai Technologies | Expires: April 6, 2019 Akamai Technologies | |||
| A. Frindell, Ed. | A. Frindell, Ed. | |||
| August 15, 2018 | October 03, 2018 | |||
| QPACK: Header Compression for HTTP over QUIC | QPACK: Header Compression for HTTP over QUIC | |||
| draft-ietf-quic-qpack-02 | draft-ietf-quic-qpack-03 | |||
| 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/QUIC. | |||
| QUIC. This is a variation of HPACK header compression that seeks to | This is a variation of HPACK header compression that seeks to reduce | |||
| reduce head-of-line blocking. | head-of-line blocking. | |||
| Note to Readers | Note to Readers | |||
| Discussion of this draft takes place on the QUIC working group | Discussion of this draft takes place on the QUIC working group | |||
| mailing list (quic@ietf.org), which is archived at | mailing list (quic@ietf.org), which is archived at | |||
| https://mailarchive.ietf.org/arch/search/?email_list=quic [1]. | https://mailarchive.ietf.org/arch/search/?email_list=quic [1]. | |||
| Working Group information can be found at https://github.com/quicwg | Working Group information can be found at https://github.com/quicwg | |||
| [2]; source code and issues list for this draft can be found at | [2]; source code and issues list for this draft can be found at | |||
| https://github.com/quicwg/base-drafts/labels/-qpack [3]. | https://github.com/quicwg/base-drafts/labels/-qpack [3]. | |||
| 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 February 16, 2019. | This Internet-Draft will expire on April 6, 2019. | |||
| 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 | |||
| skipping to change at page 2, line 26 ¶ | skipping to change at page 2, line 26 ¶ | |||
| 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 | |||
| 2. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 4 | 2. Header Tables . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 4 | 2.1. Static Table . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 4 | 2.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . . . 4 | |||
| 2.2.1. Absolute and Relative Indexing . . . . . . . . . . . 5 | 2.2.1. Maximum Table Size . . . . . . . . . . . . . . . . . 5 | |||
| 2.2.2. Post-Base Indexing . . . . . . . . . . . . . . . . . 6 | 2.2.2. Calculating Table Size . . . . . . . . . . . . . . . 6 | |||
| 2.3. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 7 | 2.2.3. Absolute Indexing . . . . . . . . . . . . . . . . . . 6 | |||
| 2.3.1. State Synchronization . . . . . . . . . . . . . . . . 8 | 2.2.4. Relative Indexing . . . . . . . . . . . . . . . . . . 6 | |||
| 3. Conventions and Definitions . . . . . . . . . . . . . . . . . 9 | 2.2.5. Post-Base Indexing . . . . . . . . . . . . . . . . . 7 | |||
| 3.1. Notational Conventions . . . . . . . . . . . . . . . . . 9 | 2.3. Avoiding Head-of-Line Blocking in HTTP/QUIC . . . . . . . 8 | |||
| 4. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 9 | 2.3.1. State Synchronization . . . . . . . . . . . . . . . . 9 | |||
| 5. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 3. Conventions and Definitions . . . . . . . . . . . . . . . . . 10 | |||
| 5.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 10 | 3.1. Notational Conventions . . . . . . . . . . . . . . . . . 10 | |||
| 5.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 10 | 4. Configuration . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 5.1.2. String Literals . . . . . . . . . . . . . . . . . . . 10 | 5. Wire Format . . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 5.2. QPACK Encoder Stream . . . . . . . . . . . . . . . . . . 11 | 5.1. Primitives . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 5.2.1. Insert With Name Reference . . . . . . . . . . . . . 11 | 5.1.1. Prefixed Integers . . . . . . . . . . . . . . . . . . 11 | |||
| 5.2.2. Insert Without Name Reference . . . . . . . . . . . . 12 | 5.1.2. String Literals . . . . . . . . . . . . . . . . . . . 11 | |||
| 5.2.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 12 | 5.2. QPACK Encoder Stream . . . . . . . . . . . . . . . . . . 12 | |||
| 5.2.4. Dynamic Table Size Update . . . . . . . . . . . . . . 13 | 5.2.1. Insert With Name Reference . . . . . . . . . . . . . 12 | |||
| 5.3. QPACK Decoder Stream . . . . . . . . . . . . . . . . . . 13 | 5.2.2. Insert Without Name Reference . . . . . . . . . . . . 13 | |||
| 5.3.1. Table State Synchronize . . . . . . . . . . . . . . . 13 | 5.2.3. Duplicate . . . . . . . . . . . . . . . . . . . . . . 13 | |||
| 5.3.2. Header Acknowledgement . . . . . . . . . . . . . . . 14 | 5.2.4. Dynamic Table Size Update . . . . . . . . . . . . . . 14 | |||
| 5.3.3. Stream Cancellation . . . . . . . . . . . . . . . . . 15 | 5.3. QPACK Decoder Stream . . . . . . . . . . . . . . . . . . 14 | |||
| 5.4. Request and Push Streams . . . . . . . . . . . . . . . . 15 | 5.3.1. Table State Synchronize . . . . . . . . . . . . . . . 14 | |||
| 5.4.1. Header Data Prefix . . . . . . . . . . . . . . . . . 15 | 5.3.2. Header Acknowledgement . . . . . . . . . . . . . . . 15 | |||
| 5.4.2. Instructions . . . . . . . . . . . . . . . . . . . . 17 | 5.3.3. Stream Cancellation . . . . . . . . . . . . . . . . . 16 | |||
| 6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 19 | 5.4. Request and Push Streams . . . . . . . . . . . . . . . . 17 | |||
| 7. Encoding Strategies . . . . . . . . . . . . . . . . . . . . . 20 | 5.4.1. Header Data Prefix . . . . . . . . . . . . . . . . . 17 | |||
| 7.1. Single Pass Encoding . . . . . . . . . . . . . . . . . . 20 | 5.4.2. Instructions . . . . . . . . . . . . . . . . . . . . 18 | |||
| 7.2. Preventing Eviction Races . . . . . . . . . . . . . . . . 20 | 6. Error Handling . . . . . . . . . . . . . . . . . . . . . . . 21 | |||
| 7.3. Reference Tracking . . . . . . . . . . . . . . . . . . . 20 | 7. Encoding Strategies . . . . . . . . . . . . . . . . . . . . . 22 | |||
| 7.3.1. Blocked Eviction . . . . . . . . . . . . . . . . . . 20 | 7.1. Single Pass Encoding . . . . . . . . . . . . . . . . . . 22 | |||
| 7.3.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 21 | 7.2. Preventing Eviction Races . . . . . . . . . . . . . . . . 22 | |||
| 7.4. Speculative table updates . . . . . . . . . . . . . . . . 21 | 7.3. Reference Tracking . . . . . . . . . . . . . . . . . . . 22 | |||
| 7.5. Sample One Pass Encoding Algorithm . . . . . . . . . . . 21 | 7.3.1. Blocked Dynamic Table Insertions . . . . . . . . . . 22 | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 23 | 7.3.2. Blocked Decoding . . . . . . . . . . . . . . . . . . 23 | |||
| 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23 | 7.4. Speculative table updates . . . . . . . . . . . . . . . . 23 | |||
| 9.1. Settings Registration . . . . . . . . . . . . . . . . . . 23 | 7.5. Sample One Pass Encoding Algorithm . . . . . . . . . . . 24 | |||
| 9.2. Stream Type Registration . . . . . . . . . . . . . . . . 23 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 26 | |||
| 9.3. Error Code Registration . . . . . . . . . . . . . . . . . 23 | 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 24 | 9.1. Settings Registration . . . . . . . . . . . . . . . . . . 26 | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 24 | 9.2. Stream Type Registration . . . . . . . . . . . . . . . . 26 | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 24 | 9.3. Error Code Registration . . . . . . . . . . . . . . . . . 26 | |||
| 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 24 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| Appendix A. Change Log . . . . . . . . . . . . . . . . . . . . . 25 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 27 | |||
| A.1. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 25 | 10.2. Informative References . . . . . . . . . . . . . . . . . 28 | |||
| A.2. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 25 | 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28 | |||
| A.3. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 25 | Appendix A. Static Table . . . . . . . . . . . . . . . . . . . . 28 | |||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 25 | Appendix B. Change Log . . . . . . . . . . . . . . . . . . . . . 33 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 26 | B.1. Since draft-ietf-quic-qpack-02 . . . . . . . . . . . . . 33 | |||
| B.2. Since draft-ietf-quic-qpack-01 . . . . . . . . . . . . . 33 | ||||
| B.3. Since draft-ietf-quic-qpack-00 . . . . . . . . . . . . . 33 | ||||
| B.4. Since draft-ietf-quic-qcram-00 . . . . . . . . . . . . . 34 | ||||
| Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 34 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 34 | ||||
| 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/QUIC, it would induce head-of-line blocking due to | used for HTTP/QUIC, it would induce head-of-line blocking due to | |||
| skipping to change at page 4, line 5 ¶ | skipping to change at page 4, line 7 ¶ | |||
| [RFC7540]. The description of HPACK is [RFC7541]. | [RFC7540]. The description of HPACK is [RFC7541]. | |||
| QPACK reuses core concepts from HPACK, but is redesigned to allow | QPACK reuses core concepts from HPACK, but is redesigned to allow | |||
| correctness in the presence of out-of-order delivery, with | correctness in the presence of out-of-order delivery, with | |||
| flexibility for implementations to balance between resilience against | flexibility for implementations to balance between resilience against | |||
| head-of-line blocking and optimal compression ratio. The design | head-of-line blocking and optimal compression ratio. The design | |||
| goals are to closely approach the compression ratio of HPACK with | goals are to closely approach the compression ratio of HPACK with | |||
| substantially less head-of-line blocking under the same loss | substantially less head-of-line blocking under the same loss | |||
| conditions. | conditions. | |||
| QPACK preserves the ordering of header fields within each header | ||||
| list. An encoder MUST emit header field representations in the order | ||||
| they appear in the input header list. A decoder MUST must emit | ||||
| header fields in the order their representations appear in the input | ||||
| header block. | ||||
| 2. Header Tables | 2. Header Tables | |||
| Like HPACK, QPACK uses two tables for associating header fields to | Like HPACK, QPACK uses two tables for associating header fields to | |||
| indexes. The static table (see Section 2.1) is predefined and | indices. The static table (see Section 2.1) is predefined and | |||
| contains common header fields (some of them with an empty value). | contains common header fields (some of them with an empty value). | |||
| The dynamic table (see Section 2.2) built up over the course of the | The dynamic table (see Section 2.2) is built up over the course of | |||
| connection and can be used by the encoder to index header fields | the connection and can be used by the encoder to index header fields | |||
| repeated in the encoded header lists. | repeated in the encoded header lists. | |||
| 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 is addressed. | each table are addressed. | |||
| 2.1. Static Table | 2.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 of [RFC7541]. Note that because HPACK did not | defined in Appendix A. | |||
| use zero-based references, there is no value at index zero of the | ||||
| static table. | A decoder that encounters an invalid static table index on a request | |||
| stream or push stream MUST treat this as a stream error of type | ||||
| "HTTP_QPACK_DECOMPRESSION_FAILED". If this index is received on the | ||||
| encoder stream, this MUST be treated as a connection error of type | ||||
| "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| 2.2. Dynamic Table | 2.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. The dynamic table is initially empty. | |||
| Entries are added by instructions on the encoder stream (see | Entries are added by instructions on the encoder stream (see | |||
| Section 5.2). | Section 5.2). | |||
| The maximum size of the dynamic table can be modified by the encoder, | ||||
| subject to a decoder-controlled limit (see Section 4 and | ||||
| Section 5.2.4). The initial maximum size is determined by the | ||||
| corresponding setting when HTTP requests or responses are first | ||||
| permitted to be sent. For clients using 0-RTT data in HTTP/QUIC, the | ||||
| table size is the remembered value of the setting, even if the server | ||||
| later specifies a larger maximum in its SETTINGS frame. For HTTP/ | ||||
| QUIC servers and HTTP/QUIC clients when 0-RTT is not attempted or is | ||||
| rejected, the initial maximum table size is the value of the setting | ||||
| in the peer's SETTINGS frame. | ||||
| 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 (maximum size - new entry size) or until the | is less than or equal to (maximum size - new entry size) or until the | |||
| table is empty. | table is empty. The encoder MUST NOT evict a dynamic table entry | |||
| unless it has first been acknowledged by the decoder. | ||||
| If the size of the new entry is less than or equal to the maximum | 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 | 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 | add an entry that is larger than the maximum size; this MUST be | |||
| treated as a connection error of type | treated as a connection error of type | |||
| "HTTP_QPACK_DECOMPRESSION_FAILED". | "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 | |||
| if the referenced entry is evicted from the dynamic table prior to | if the referenced entry is evicted from the dynamic table prior to | |||
| inserting the new entry. | inserting the new entry. | |||
| 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 a decoder. | be treated as an error by a decoder. | |||
| 2.2.1. Maximum Table Size | ||||
| The encoder decides how to update the dynamic table and as such can | 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 | control how much memory is used by the dynamic table. To limit the | |||
| memory requirements of the decoder, the dynamic table size is | memory requirements of the decoder, the dynamic table size is | |||
| strictly bounded. | strictly bounded. | |||
| The decoder determines the maximum size that the encoder is permitted | The decoder determines the maximum size that the encoder is permitted | |||
| to use for the dynamic table. In HTTP/QUIC, this value is determined | to use for the dynamic table. In HTTP/QUIC, this value is determined | |||
| by the SETTINGS_HEADER_TABLE_SIZE setting (see Section 4). | by the SETTINGS_HEADER_TABLE_SIZE setting (see Section 4). | |||
| An encoder can choose to use less capacity than this maximum size | 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 | (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 | 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 | 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 | the dynamic table until the size of the dynamic table is less than or | |||
| equal to the maximum size. | equal to the maximum size. | |||
| This mechanism can be used to completely clear entries from the | This mechanism can be used to completely clear entries from the | |||
| dynamic table by setting a maximum size of 0, which can subsequently | dynamic table by setting a maximum size of 0, which can subsequently | |||
| be restored. | be restored. | |||
| 2.2.1. Absolute and Relative Indexing | 2.2.2. Calculating Table Size | |||
| 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 octets (as | ||||
| defined in Section 5.1.2), its value's length in octets, and 32. | ||||
| The size of an entry is calculated using the length of its name and | ||||
| value without any Huffman encoding applied. | ||||
| "MaxEntries" is the maximum number of entries that the dynamic table | ||||
| can have. The smallest entry has empty name and value strings and | ||||
| has the size of 32. The MaxEntries is calculated as | ||||
| MaxEntries = floor( MaxTableSize / 32 ) | ||||
| MaxTableSize is the maximum size of the dynamic table as specified by | ||||
| the decoder (see Section 2.2.1). | ||||
| 2.2.3. 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 over time | lifetime of that entry and a relative index which changes over time | |||
| based on the context of the reference. The first entry inserted has | based on the context of the reference. The first entry inserted has | |||
| an absolute index of "1"; indices increase sequentially with each | an absolute index of "1"; indices increase sequentially with each | |||
| insertion. | insertion. | |||
| 2.2.4. 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 | On the encoder stream, 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 | ... | d + 1 | Absolute Index | | n | ... | d + 1 | 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 | |||
| Because frames from request streams can be delivered out of order | Because frames from request streams can be delivered out of order | |||
| with instructions on the encoder stream, relative indices are | with instructions on the encoder stream, relative indices are | |||
| relative to the Base Index at the beginning of the header block (see | relative to the Base Index at the beginning of the header block (see | |||
| skipping to change at page 6, line 39 ¶ | skipping to change at page 7, line 39 ¶ | |||
| V | V | |||
| +---+-----+-----+-----+-------+ | +---+-----+-----+-----+-------+ | |||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | | n | n-1 | n-2 | ... | d+1 | 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 - Request Stream | Example Dynamic Table Indexing - Relative Index on Request Stream | |||
| 2.2.2. Post-Base Indexing | 2.2.5. Post-Base Indexing | |||
| A header block on the request stream can reference entries added | A header block on the request stream can reference entries added | |||
| after the entry identified by the Base Index. This allows an encoder | 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 | to process a header block in a single pass and include references to | |||
| entries added while processing this (or other) header blocks. Newly | entries added while processing this (or other) header blocks. Newly | |||
| added entries are referenced using Post-Base instructions. Indices | added entries are referenced using Post-Base instructions. Indices | |||
| for Post-Base instructions increase in the same direction as absolute | for Post-Base instructions increase in the same direction as absolute | |||
| indices, but the zero value is one higher than the Base Index. | indices, but the zero value is one higher than the Base Index. | |||
| Base Index | Base Index | |||
| skipping to change at page 7, line 17 ¶ | skipping to change at page 8, line 17 ¶ | |||
| V | V | |||
| +---+-----+-----+-----+-----+ | +---+-----+-----+-----+-----+ | |||
| | n | n-1 | n-2 | ... | d+1 | Absolute Index | | n | n-1 | n-2 | ... | d+1 | 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 | |||
| Dynamic Table Indexing - Post-Base References | Example Dynamic Table Indexing - Post-Base Index on Request Stream | |||
| If the decoder encounters a reference to an entry which has already | If the decoder encounters a reference on a request or push stream to | |||
| been dropped from the table or which is greater than the declared | a dynamic table entry which has already been dropped or which has an | |||
| Largest Reference (see Section 5.4.1), this MUST be treated as a | absolute index greater than the declared Largest Reference (see | |||
| stream error of type "HTTP_QPACK_DECOMPRESSION_FAILED" error code. | Section 5.4.1), it MUST treat this as a stream error of type | |||
| If this reference occurs on the encoder stream, this MUST be treated | "HTTP_QPACK_DECOMPRESSION_FAILED". | |||
| as a session error. | ||||
| If the decoder encounters a reference on the encoder stream to a | ||||
| dynamic table entry which has already been dropped, it MUST treat | ||||
| this as a connection error of type "HTTP_QPACK_ENCODER_STREAM_ERROR". | ||||
| 2.3. Avoiding Head-of-Line Blocking in HTTP/QUIC | 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 which identifies the | Each header block contains a Largest Reference which identifies the | |||
| table state necessary for decoding. If the greatest absolute index | table state necessary for decoding. If the greatest absolute index | |||
| in the dynamic table is less than the value of the Largest Reference, | in the dynamic table is less than the value of the Largest Reference, | |||
| the stream is considered "blocked." While blocked, header field data | the stream is considered "blocked." While blocked, header field data | |||
| should remain in the blocked stream's flow control window. When the | should remain in the blocked stream's flow control window. When the | |||
| Largest Reference is zero, the frame contains no references to the | Largest Reference is zero, the frame contains no references to the | |||
| dynamic table and can always be processed immediately. A stream | dynamic table and can always be processed immediately. A stream | |||
| becomes unblocked when the greatest absolute index in the dynamic | becomes unblocked when the greatest absolute index in the dynamic | |||
| table becomes greater than or equal to the Largest Reference for all | table becomes greater than or equal to the Largest Reference for all | |||
| header blocks the decoder has started reading from the stream. If a | header blocks the decoder has started reading from the stream. If a | |||
| decoder encounters a header block where the actual largest reference | decoder encounters a header block where the actual largest reference | |||
| is not equal to the largest reference declared in the prefix, it MAY | 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. | 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 (see Section 4). | SETTINGS_QPACK_BLOCKED_STREAMS to a non-zero value (see Section 4). | |||
| This setting specifies an upper bound on the number of streams which | This setting specifies an upper bound on the number of streams which | |||
| can be 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 | |||
| skipping to change at page 8, line 16 ¶ | skipping to change at page 9, line 19 ¶ | |||
| 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 MUST treat this as a | |||
| a stream error of type HTTP_QPACK_DECOMPRESSION_FAILED. | stream error of type HTTP_QPACK_DECOMPRESSION_FAILED. | |||
| 2.3.1. State Synchronization | 2.3.1. State Synchronization | |||
| The decoder stream signals key events at the decoder that permit the | The decoder stream (Section 5.3) signals key events at the decoder | |||
| encoder to track the decoder's state. These events are: | that permit the encoder to track the decoder's state. These 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 | |||
| Regardless of whether a header block contained blocking references, | Regardless of whether a header block contained blocking references, | |||
| the knowledge that it has been processed permits the encoder to evict | the knowledge that it has been processed permits the encoder to evict | |||
| entries to which no unacknowledged references remain; see | entries to which no unacknowledged references remain; see | |||
| skipping to change at page 9, line 15 ¶ | skipping to change at page 10, line 15 ¶ | |||
| 3. Conventions and Definitions | 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 field: A name-value pair sent as part of an HTTP message. | |||
| Header set: The full collection of headers associated with an HTTP | Header list: The ordered collection of header fields associated with | |||
| message. | an HTTP message. A header list can contain multiple header fields | |||
| with the same name. It can also contain duplicate header fields. | ||||
| Header block: The compressed representation of a header set. | Header block: The compressed representation of a header list. | |||
| Encoder: An implementation which transforms a header set into a | Encoder: An implementation which transforms a header list into a | |||
| header block. | header block. | |||
| Decoder: An implementation which transforms a header block into a | Decoder: An implementation which transforms a header block into a | |||
| header set. | header list. | |||
| QPACK is a name, not an acronym. | QPACK is a name, not an acronym. | |||
| 3.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 | |||
| skipping to change at page 10, line 44 ¶ | skipping to change at page 11, line 44 ¶ | |||
| All table updates occur on the encoder stream. Request streams and | All table updates occur on the encoder stream. Request streams and | |||
| push streams only carry header blocks that do not modify the state of | push streams only carry header blocks that do not modify the state of | |||
| the table. | the table. | |||
| 5.1. Primitives | 5.1. Primitives | |||
| 5.1.1. Prefixed Integers | 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 format from [RFC7541] is used | throughout this document. The format from [RFC7541] is used | |||
| unmodified. | unmodified. QPACK implementations MUST be able to decode integers up | |||
| to 62 bits long. | ||||
| 5.1.2. String Literals | 5.1.2. String Literals | |||
| The string literal defined by Section 5.2 of [RFC7541] is also used | The string literal defined by Section 5.2 of [RFC7541] is also used | |||
| throughout. This string format includes optional Huffman encoding. | throughout. This string format includes optional Huffman encoding. | |||
| HPACK defines string literals to begin on a byte boundary. They | HPACK defines string literals to begin on a byte boundary. They | |||
| begin with a single 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. When Huffman encoding is enabled, the | finally Length octets of data. When Huffman encoding is enabled, the | |||
| skipping to change at page 13, line 24 ¶ | skipping to change at page 14, line 24 ¶ | |||
| 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 connection error of type | |||
| is the value of the SETTINGS_HEADER_TABLE_SIZE parameter (see | "HTTP_QPACK_ENCODER_STREAM_ERROR". In HTTP/QUIC, this limit is the | |||
| Section 4) received from the decoder. | value of the SETTINGS_HEADER_TABLE_SIZE parameter (see 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 7.3). | eviction of entries with outstanding references (see Section 7.3). | |||
| Changing the size of the dynamic table is not acknowledged as this | Changing the size of the dynamic table is not acknowledged as this | |||
| instruction does not insert an entry. | instruction does not insert an entry. | |||
| 5.3. 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 | |||
| skipping to change at page 14, line 15 ¶ | skipping to change at page 15, line 16 ¶ | |||
| encoder uses this value to determine which table entries might cause | encoder uses this value to determine which table entries might cause | |||
| a stream to become blocked, as described in Section 2.3.1. | 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 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| | 0 | 0 | Insert Count (6+) | | | 0 | 0 | Insert Count (6+) | | |||
| +---+---+-----------------------+ | +---+---+-----------------------+ | |||
| Figure 3: Table State Synchronize | Figure 3: Table State Synchronize | |||
| An encoder that receives an Insert Count equal to zero or one that | ||||
| increases Largest Known Received beyond what the encoder has sent | ||||
| MUST treat this as a connection error of type | ||||
| "HTTP_QPACK_DECODER_STREAM_ERROR". | ||||
| A decoder chooses when to emit Table State Synchronize instructions. | A decoder chooses when to emit Table State Synchronize instructions. | |||
| Emitting a Table State Synchronize after adding each new dynamic | Emitting a Table State Synchronize after adding each new dynamic | |||
| table entry will provide the most timely feedback to the encoder, but | table entry will provide the most timely feedback to the encoder, but | |||
| could be redundant with other decoder feedback. By delaying a | could be redundant with other decoder feedback. By delaying a | |||
| Table State Synchronize, a decoder might be able to coalesce multiple | Table State Synchronize, a decoder might be able to coalesce multiple | |||
| Table State Synchronize instructions, or replace them entirely with | Table State Synchronize instructions, or replace them entirely with | |||
| Header Acknowledgements. However, delaying too long may lead to | Header Acknowledgements. However, delaying too long may lead to | |||
| compression inefficiencies if the encoder waits for an entry to be | compression inefficiencies if the encoder waits for an entry to be | |||
| acknowledged before using it. | acknowledged before using it. | |||
| 5.3.2. Header Acknowledgement | 5.3.2. Header Acknowledgement | |||
| After processing a header block whose declared Largest Reference is | After processing a header block whose declared Largest Reference is | |||
| not zero, the decoder emits a Header Acknowledgement instruction on | not zero, the decoder emits a Header Acknowledgement instruction on | |||
| the decoder stream. The instruction begins with the '1' one-bit | 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 request stream's stream ID, encoded as a | |||
| 7-bit prefix integer. It is used by the peer's QPACK encoder to know | 7-bit prefix integer. It is used by the peer's QPACK encoder to know | |||
| when it is safe to evict an entry. | when it is safe to evict an entry. | |||
| 0 1 2 3 4 5 6 7 | ||||
| +---+---+---+---+---+---+---+---+ | ||||
| | 1 | Stream ID (7+) | | ||||
| +---+---------------------------+ | ||||
| Figure 4: 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 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 | If an encoder receives a Header Acknowledgement instruction referring | |||
| +---+---+---+---+---+---+---+---+ | to a stream on which every header block with a non-zero Largest | |||
| | 1 | Stream ID (7+) | | Reference has already been acknowledged, that MUST be treated as a | |||
| +---+---------------------------+ | connection error of type "HTTP_QPACK_DECODER_STREAM_ERROR". | |||
| Figure 4: Header Acknowledgement | ||||
| When blocking references are permitted, the encoder uses | When blocking references are permitted, the encoder uses | |||
| acknowledgement of header blocks to update the Largest Known Received | acknowledgement of header blocks to update the Largest Known Received | |||
| index. If a header block was potentially blocking, the | index. If a header block was potentially blocking, the | |||
| acknowledgement implies that the decoder has received all dynamic | acknowledgement implies that the decoder has received all dynamic | |||
| table state necessary to process the header block. If the Largest | table state necessary to process the header block. If the Largest | |||
| Reference of an acknowledged header block was greater than the | Reference of an acknowledged header block was greater than the | |||
| encoder's current Largest Known Received index, the block's Largest | encoder's current Largest Known Received index, the block's Largest | |||
| Reference becomes the new Largest Known Received. | Reference becomes the new Largest Known Received. | |||
| 5.3.3. Stream Cancellation | 5.3.3. Stream Cancellation | |||
| A stream that is reset might have multiple outstanding header blocks. | A stream that is reset might have multiple outstanding header blocks | |||
| A decoder that receives a stream reset before the end of a stream | with dynamic table references. A decoder that receives a stream | |||
| generates a Stream Cancellation instruction on the decoder stream. | reset before the end of a stream generates a Stream Cancellation | |||
| Similarly, a decoder that abandons reading of a stream needs to | instruction on the decoder stream. Similarly, a decoder that | |||
| signal this using the Stream Cancellation instruction. This signals | abandons reading of a stream needs to signal this using the Stream | |||
| to the encoder that all references to the dynamic table on that | Cancellation instruction. This signals to the encoder that all | |||
| stream are no longer outstanding. | references to the dynamic table on that stream are no longer | |||
| outstanding. A decoder with a maximum dynamic table size equal to | ||||
| zero MAY omit sending Stream Cancellations, because the encoder | ||||
| cannot have any dynamic table references. | ||||
| An encoder cannot infer from this instruction that any updates to the | An encoder cannot infer from this instruction that any updates to the | |||
| dynamic table have been received. | dynamic table have been received. | |||
| The instruction begins with the '01' two-bit pattern. The | The instruction begins with the '01' two-bit pattern. The | |||
| instruction includes the stream ID of the affected stream - a request | instruction includes the stream ID of the affected stream - a request | |||
| or push stream - encoded as a 6-bit prefix integer. | or push stream - encoded as a 6-bit prefix integer. | |||
| 0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
| +---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| skipping to change at page 16, line 18 ¶ | skipping to change at page 17, line 29 ¶ | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | S | Delta Base Index (7+) | | | S | Delta Base Index (7+) | | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | Compressed Headers ... | | Compressed Headers ... | |||
| +-------------------------------+ | +-------------------------------+ | |||
| Figure 6: 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. If | |||
| Largest Reference is greater than zero, the encoder transforms it as | ||||
| follows before encoding: | ||||
| LargestReference = LargestReference mod 2*MaxEntries + 1 | ||||
| The decoder reconstructs the Largest Reference using the following | ||||
| algorithm: | ||||
| if LargestReference > 0: | ||||
| LargestReference -= 1 | ||||
| CurrentWrapped = TableLargestAbsoluteIndex mod 2*MaxEntries | ||||
| if CurrentWrapped >= LargestReference + MaxEntries: | ||||
| # Largest Reference wrapped around 1 extra time | ||||
| LargestReference += 2*MaxEntries | ||||
| else if CurrentWrapped + MaxEntries < LargestReference | ||||
| # Decoder wrapped around 1 extra time | ||||
| CurrentWrapped += 2*MaxEntries | ||||
| LargestReference += | ||||
| (TableLargestAbsoluteIndex - CurrentWrapped) | ||||
| TableLargestAbsoluteIndex is the Absolute Index of the most recently | ||||
| inserted item in the decoder's dynamic table. This encoding limits | ||||
| the length of the prefix on long-lived connections. | ||||
| "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 2.2.1. | described in Section 2.2.4. | |||
| To save space, Base Index is encoded relative to Largest Reference | 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 | 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 | 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 | 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 | 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 | the Base Index. A sign bit of 1 indicates that the Base Index is | |||
| less than the Largest Reference. That is: | less than the Largest Reference. That is: | |||
| if sign == 0: | if sign == 0: | |||
| skipping to change at page 17, line 37 ¶ | skipping to change at page 19, line 24 ¶ | |||
| 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]). | |||
| 5.4.2.2. Indexed Header Field With Post-Base Index | 5.4.2.2. 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 Base Index, the representation starts with the '0001' 4-bit | than Base Index, the representation starts with the '0001' 4-bit | |||
| pattern, followed by the post-base index (see Section 2.2.2) of the | pattern, followed by the post-base index (see Section 2.2.5) 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]). | |||
| 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 18, line 43 ¶ | skipping to change at page 20, line 30 ¶ | |||
| 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 | 5.4.2.4. 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 | |||
| Base Index, the header field name is represented using the post-base | Base Index, the header field name is represented using the post-base | |||
| index of that entry (see Section 2.2.2) encoded as an integer with a | index of that entry (see Section 2.2.5) encoded as an integer with a | |||
| 3-bit prefix. | 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 octets) | | | Value String (Length octets) | | |||
| +-------------------------------+ | +-------------------------------+ | |||
| skipping to change at page 19, line 50 ¶ | skipping to change at page 21, line 31 ¶ | |||
| +---+---------------------------+ | +---+---------------------------+ | |||
| | 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 | |||
| 6. Error Handling | 6. Error Handling | |||
| The following error code is defined for HTTP/QUIC to indicate all | The following error codes are defined for HTTP/QUIC to indicate | |||
| failures of QPACK which prevent the stream or connection from | failures of QPACK which prevent the stream or connection from | |||
| continuing: | continuing: | |||
| HTTP_QPACK_DECOMPRESSION_FAILED (0x06): QPACK failed to decompress a | HTTP_QPACK_DECOMPRESSION_FAILED (TBD): The decoder failed to | |||
| frame and cannot continue. | interpret an instruction on a request or push stream and is not | |||
| able to continue decoding that header block. | ||||
| HTTP_QPACK_ENCODER_STREAM_ERROR (TBD): | ||||
| The decoder failed to interpret an instruction on the encoder | ||||
| stream. HTTP_QPACK_DECODER_STREAM_ERROR (TBD): | ||||
| The encoder failed to interpret an instruction on the decoder | ||||
| stream. | ||||
| Upon encountering an error, an implementation MAY elect to treat it | ||||
| as a connection error even if this document prescribes that it MUST | ||||
| be treated as a stream error. | ||||
| 7. Encoding Strategies | 7. Encoding Strategies | |||
| 7.1. Single Pass Encoding | 7.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. | |||
| skipping to change at page 20, line 40 ¶ | skipping to change at page 22, line 37 ¶ | |||
| 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. | |||
| 7.3.1. Blocked Eviction | 7.3.1. Blocked Dynamic Table Insertions | |||
| The encoder MUST NOT permit an entry to be evicted while a reference | An encoder MUST NOT insert an entry into the dynamic table (or | |||
| to that entry remains unacknowledged. If a new header to be inserted | duplicate an existing entry) if doing so would evict an entry with | |||
| into the dynamic table would cause the eviction of such an entry, the | unacknowledged references. For header blocks that might rely on the | |||
| encoder MUST NOT emit the insert instruction until the reference has | newly added entry, the encoder can use a literal representation and | |||
| been processed by the decoder and acknowledged. | maybe insert the entry later. | |||
| The encoder can emit a literal representation for the new header in | To ensure that the encoder is not prevented from adding new entries, | |||
| order to avoid encoding delays, and MAY insert the header into the | the encoder can avoid referencing entries that will be evicted | |||
| table later if desired. | soonest. Rather than reference such an entry, the encoder SHOULD | |||
| emit a Duplicate instruction (see Section 5.2.3), and reference the | ||||
| duplicate instead. | ||||
| To ensure that the blocked eviction case is rare, references to the | Determining which entries are too close to eviction to reference is | |||
| oldest entries in the dynamic table SHOULD be avoided. When one of | an encoder preference. One heuristic is to target a fixed amount of | |||
| the oldest entries in the table is still actively used for | available space in the dynamic table: either unused space or space | |||
| references, the encoder SHOULD emit an Duplicate representation | that can be reclaimed by evicting unreferenced entries. To achieve | |||
| instead (see Section 5.2.3). | this, the encoder can maintain a draining index, which is the | |||
| smallest absolute index in the dynamic table that it will emit a | ||||
| reference for. As new entries are inserted, the encoder increases | ||||
| the draining index to maintain the section of the table that it will | ||||
| not reference. Draining entries - entries with an absolute index | ||||
| lower than the draining index - will not accumulate new references. | ||||
| The number of unacknowledged references to draining entries will | ||||
| eventually become zero, making the entry available for eviction. | ||||
| +----------+---------------------------------+--------+ | ||||
| | Draining | Referenceable | Unused | | ||||
| | Entries | Entries | Space | | ||||
| +----------+---------------------------------+--------+ | ||||
| ^ ^ ^ | ||||
| | | | | ||||
| Dropping Draining Index Base Index / | ||||
| Point Insertion Point | ||||
| Figure 7: Draining Dynamic Table Entries | ||||
| 7.3.2. Blocked Decoding | 7.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 5.3. Since all table updates | not yet been acknowledged (see Section 5.3). Since all table updates | |||
| are processed in sequence on the encoder 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. | |||
| 7.4. Speculative table updates | 7.4. Speculative table updates | |||
| Implementations can _speculatively_ send header frames on the HTTP | Implementations can _speculatively_ send instructions on the encoder | |||
| Control Streams which are not needed for any current HTTP request or | stream which are not needed for any current HTTP request or response. | |||
| response. Such headers could be used strategically to improve | Such headers could be used strategically to improve performance. For | |||
| performance. For instance, the encoder might decide to _refresh_ by | instance, the encoder might decide to _refresh_ by sending Duplicate | |||
| sending Duplicate representations for popular header fields | representations for popular header fields (Section 5.2.3), ensuring | |||
| (Section 5.2.3), ensuring they have small indices and hence minimal | they have small indices and hence minimal size on the wire. | |||
| size on the wire. | ||||
| 7.5. Sample One Pass Encoding Algorithm | 7.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) | |||
| skipping to change at page 23, line 43 ¶ | skipping to change at page 26, line 43 ¶ | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| | Stream Type | Code | Specification | Sender | | | Stream Type | Code | Specification | Sender | | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| | QPACK Encoder Stream | 0x48 | Section 5 | Both | | | QPACK Encoder Stream | 0x48 | Section 5 | Both | | |||
| | | | | | | | | | | | | |||
| | QPACK Decoder Stream | 0x68 | Section 5 | Both | | | QPACK Decoder Stream | 0x68 | Section 5 | Both | | |||
| +----------------------+------+---------------+--------+ | +----------------------+------+---------------+--------+ | |||
| 9.3. Error Code Registration | 9.3. Error Code Registration | |||
| This document establishes one new error code in the "HTTP/QUIC Error | This document establishes the following new error codes in the "HTTP/ | |||
| Code" registry established in [QUIC-HTTP]. | QUIC Error Code" registry established in [QUIC-HTTP]. | |||
| Name: HTTP_QPACK_DECOMPRESSION_FAILED | ||||
| Code: 0x06 | ||||
| Description: QPACK failed to interpret an instruction and cannot | +------------------------------+------+--------------+--------------+ | |||
| continue. | | Name | Code | Description | Specificatio | | |||
| | | | | n | | ||||
| +------------------------------+------+--------------+--------------+ | ||||
| | HTTP_QPACK_DECOMPRESSION_FAI | TBD | Decompressio | Section 6 | | ||||
| | LED | | n of a | | | ||||
| | | | header block | | | ||||
| | | | failed | | | ||||
| | | | | | | ||||
| | HTTP_QPACK_ENCODER_STREAM_ER | TBD | Error on the | Section 6 | | ||||
| | ROR | | encoder | | | ||||
| | | | stream | | | ||||
| | | | | | | ||||
| | HTTP_QPACK_DECODER_STREAM_ER | TBD | Error on the | Section 6 | | ||||
| | ROR | | decoder | | | ||||
| | | | stream | | | ||||
| +------------------------------+------+--------------+--------------+ | ||||
| 10. References | 10. References | |||
| 10.1. Normative References | 10.1. Normative References | |||
| [QUIC-HTTP] | [QUIC-HTTP] | |||
| Bishop, M., Ed., "Hypertext Transfer Protocol (HTTP) over | Bishop, M., Ed., "Hypertext Transfer Protocol (HTTP) over | |||
| QUIC", draft-ietf-quic-http-14 (work in progress), August | QUIC", draft-ietf-quic-http-15 (work in progress), October | |||
| 2018. | 2018. | |||
| [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-13 (work in progress), August 2018. | transport-14 (work in progress), October 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>. | |||
| skipping to change at page 25, line 5 ¶ | skipping to change at page 28, line 24 ¶ | |||
| <https://www.rfc-editor.org/info/rfc7540>. | <https://www.rfc-editor.org/info/rfc7540>. | |||
| 10.3. URIs | 10.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 | |||
| Appendix A. Change Log | Appendix A. Static Table | |||
| +------+-----------------------------+------------------------------+ | ||||
| | Inde | Name | Value | | ||||
| | x | | | | ||||
| +------+-----------------------------+------------------------------+ | ||||
| | 0 | :authority | | | ||||
| | | | | | ||||
| | 1 | :path | / | | ||||
| | | | | | ||||
| | 2 | age | 0 | | ||||
| | | | | | ||||
| | 3 | content-disposition | | | ||||
| | | | | | ||||
| | 4 | content-length | 0 | | ||||
| | | | | | ||||
| | 5 | cookie | | | ||||
| | | | | | ||||
| | 6 | date | | | ||||
| | | | | | ||||
| | 7 | etag | | | ||||
| | | | | | ||||
| | 8 | if-modified-since | | | ||||
| | | | | | ||||
| | 9 | if-none-match | | | ||||
| | | | | | ||||
| | 10 | last-modified | | | ||||
| | | | | | ||||
| | 11 | link | | | ||||
| | | | | | ||||
| | 12 | location | | | ||||
| | | | | | ||||
| | 13 | referer | | | ||||
| | | | | | ||||
| | 14 | set-cookie | | | ||||
| | | | | | ||||
| | 15 | :method | CONNECT | | ||||
| | | | | | ||||
| | 16 | :method | DELETE | | ||||
| | | | | | ||||
| | 17 | :method | GET | | ||||
| | | | | | ||||
| | 18 | :method | HEAD | | ||||
| | | | | | ||||
| | 19 | :method | OPTIONS | | ||||
| | | | | | ||||
| | 20 | :method | POST | | ||||
| | | | | | ||||
| | 21 | :method | PUT | | ||||
| | | | | | ||||
| | 22 | :scheme | http | | ||||
| | | | | | ||||
| | 23 | :scheme | https | | ||||
| | | | | | ||||
| | 24 | :status | 103 | | ||||
| | | | | | ||||
| | 25 | :status | 200 | | ||||
| | | | | | ||||
| | 26 | :status | 304 | | ||||
| | | | | | ||||
| | 27 | :status | 404 | | ||||
| | | | | | ||||
| | 28 | :status | 503 | | ||||
| | | | | | ||||
| | 29 | accept | */* | | ||||
| | | | | | ||||
| | 30 | accept | application/dns-message | | ||||
| | | | | | ||||
| | 31 | accept-encoding | gzip, deflate, br | | ||||
| | | | | | ||||
| | 32 | accept-ranges | bytes | | ||||
| | | | | | ||||
| | 33 | access-control-allow- | cache-control | | ||||
| | | headers | | | ||||
| | | | | | ||||
| | 34 | access-control-allow- | content-type | | ||||
| | | headers | | | ||||
| | | | | | ||||
| | 35 | access-control-allow-origin | * | | ||||
| | | | | | ||||
| | 36 | cache-control | max-age=0 | | ||||
| | | | | | ||||
| | 37 | cache-control | max-age=2592000 | | ||||
| | | | | | ||||
| | 38 | cache-control | max-age=604800 | | ||||
| | | | | | ||||
| | 39 | cache-control | no-cache | | ||||
| | | | | | ||||
| | 40 | cache-control | no-store | | ||||
| | | | | | ||||
| | 41 | cache-control | public, max-age=31536000 | | ||||
| | | | | | ||||
| | 42 | content-encoding | br | | ||||
| | | | | | ||||
| | 43 | content-encoding | gzip | | ||||
| | | | | | ||||
| | 44 | content-type | application/dns-message | | ||||
| | | | | | ||||
| | 45 | content-type | application/javascript | | ||||
| | | | | | ||||
| | 46 | content-type | application/json | | ||||
| | | | | | ||||
| | 47 | content-type | application/x-www-form- | | ||||
| | | | urlencoded | | ||||
| | | | | | ||||
| | 48 | content-type | image/gif | | ||||
| | | | | | ||||
| | 49 | content-type | image/jpeg | | ||||
| | | | | | ||||
| | 50 | content-type | image/png | | ||||
| | | | | | ||||
| | 51 | content-type | text/css | | ||||
| | | | | | ||||
| | 52 | content-type | text/html; charset=utf-8 | | ||||
| | | | | | ||||
| | 53 | content-type | text/plain | | ||||
| | | | | | ||||
| | 54 | content-type | text/plain;charset=utf-8 | | ||||
| | | | | | ||||
| | 55 | range | bytes=0- | | ||||
| | | | | | ||||
| | 56 | strict-transport-security | max-age=31536000 | | ||||
| | | | | | ||||
| | 57 | strict-transport-security | max-age=31536000; | | ||||
| | | | includesubdomains | | ||||
| | | | | | ||||
| | 58 | strict-transport-security | max-age=31536000; | | ||||
| | | | includesubdomains; preload | | ||||
| | | | | | ||||
| | 59 | vary | accept-encoding | | ||||
| | | | | | ||||
| | 60 | vary | origin | | ||||
| | | | | | ||||
| | 61 | x-content-type-options | nosniff | | ||||
| | | | | | ||||
| | 62 | x-xss-protection | 1; mode=block | | ||||
| | | | | | ||||
| | 63 | :status | 100 | | ||||
| | | | | | ||||
| | 64 | :status | 204 | | ||||
| | | | | | ||||
| | 65 | :status | 206 | | ||||
| | | | | | ||||
| | 66 | :status | 302 | | ||||
| | | | | | ||||
| | 67 | :status | 400 | | ||||
| | | | | | ||||
| | 68 | :status | 403 | | ||||
| | | | | | ||||
| | 69 | :status | 421 | | ||||
| | | | | | ||||
| | 70 | :status | 425 | | ||||
| | | | | | ||||
| | 71 | :status | 500 | | ||||
| | | | | | ||||
| | 72 | accept-language | | | ||||
| | | | | | ||||
| | 73 | access-control-allow- | FALSE | | ||||
| | | credentials | | | ||||
| | | | | | ||||
| | 74 | access-control-allow- | TRUE | | ||||
| | | credentials | | | ||||
| | | | | | ||||
| | 75 | access-control-allow- | * | | ||||
| | | headers | | | ||||
| | | | | | ||||
| | 76 | access-control-allow- | get | | ||||
| | | methods | | | ||||
| | | | | | ||||
| | 77 | access-control-allow- | get, post, options | | ||||
| | | methods | | | ||||
| | | | | | ||||
| | 78 | access-control-allow- | options | | ||||
| | | methods | | | ||||
| | | | | | ||||
| | 79 | access-control-expose- | content-length | | ||||
| | | headers | | | ||||
| | | | | | ||||
| | 80 | access-control-request- | content-type | | ||||
| | | headers | | | ||||
| | | | | | ||||
| | 81 | access-control-request- | get | | ||||
| | | method | | | ||||
| | | | | | ||||
| | 82 | access-control-request- | post | | ||||
| | | method | | | ||||
| | | | | | ||||
| | 83 | alt-svc | clear | | ||||
| | | | | | ||||
| | 84 | authorization | | | ||||
| | | | | | ||||
| | 85 | content-security-policy | script-src 'none'; object- | | ||||
| | | | src 'none'; base-uri 'none' | | ||||
| | | | | | ||||
| | 86 | early-data | 1 | | ||||
| | | | | | ||||
| | 87 | expect-ct | | | ||||
| | | | | | ||||
| | 88 | forwarded | | | ||||
| | | | | | ||||
| | 89 | if-range | | | ||||
| | | | | | ||||
| | 90 | origin | | | ||||
| | | | | | ||||
| | 91 | purpose | prefetch | | ||||
| | | | | | ||||
| | 92 | server | | | ||||
| | | | | | ||||
| | 93 | timing-allow-origin | * | | ||||
| | | | | | ||||
| | 94 | upgrade-insecure-requests | 1 | | ||||
| | | | | | ||||
| | 95 | user-agent | | | ||||
| | | | | | ||||
| | 96 | x-forwarded-for | | | ||||
| | | | | | ||||
| | 97 | x-frame-options | deny | | ||||
| | | | | | ||||
| | 98 | x-frame-options | sameorigin | | ||||
| +------+-----------------------------+------------------------------+ | ||||
| Appendix B. 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. | |||
| A.1. Since draft-ietf-quic-qpack-01 | B.1. Since draft-ietf-quic-qpack-02 | |||
| o Largest Reference encoded modulo MaxEntries (#1763) | ||||
| o New Static Table (#1355) | ||||
| o Table Size Update with Insert Count=0 is a connection error | ||||
| (#1762) | ||||
| o Stream Cancellations are optional when | ||||
| SETTINGS_HEADER_TABLE_SIZE=0 (#1761) | ||||
| o Implementations must handle 62 bit integers (#1760) | ||||
| o Different error types for each QPACK stream, other changes to | ||||
| error handling (#1726) | ||||
| o Preserve header field order (#1725) | ||||
| o Initial table size is the maximum permitted when table is first | ||||
| usable (#1642) | ||||
| B.2. 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) | |||
| A.2. Since draft-ietf-quic-qpack-00 | B.3. 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) | |||
| A.3. Since draft-ietf-quic-qcram-00 | B.4. 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. 56 change blocks. | ||||
| 147 lines changed or deleted | 527 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/ | ||||