<?xmlversion='1.0' encoding='utf-8'?> <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.3.24 -->version="1.0" encoding="UTF-8"?> <!DOCTYPE rfcSYSTEM "rfc2629-xhtml.ent"> <?rfc toc="yes"?> <?rfc sortrefs="yes"?> <?rfc symrefs="yes"?> <?rfc docmapping="yes"?>[ <!ENTITY nbsp " "> <!ENTITY zwsp "​"> <!ENTITY nbhy "‑"> <!ENTITY wj "⁠"> ]> <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-quic-qpack-21"category="std"number="9204" obsoletes="" updates="" submissionType="IETF" category="std" consensus="true" xml:lang="en" tocInclude="true" sortRefs="true" symRefs="true" version="3"><!-- xml2rfc v2v3 conversion 3.5.0 --><link href="https://datatracker.ietf.org/doc/draft-ietf-quic-qpack-latest" rel="prev"/> <front> <title abbrev="QPACK">QPACK:HeaderField Compression for HTTP/3</title> <seriesInfoname="Internet-Draft" value="draft-ietf-quic-qpack-21"/>name="RFC" value="9204"/> <author initials="C." surname="Krasic" fullname="Charles 'Buck' Krasic"><organization>Netflix</organization><organization/> <address><email>ckrasic@netflix.com</email><email>krasic@acm.org</email> </address> </author> <author initials="M." surname="Bishop" fullname="Mike Bishop"> <organization>Akamai Technologies</organization> <address> <email>mbishop@evequefou.be</email> </address> </author> <author initials="A." surname="Frindell" fullname="Alan Frindell" role="editor"> <organization>Facebook</organization> <address> <email>afrind@fb.com</email> </address> </author> <dateyear="2021" month="February" day="02"/>year="2022" month="June"/> <area>Transport</area> <workgroup>QUIC</workgroup> <keyword>compression</keyword> <keyword>HTTP/3</keyword> <keyword>HPACK</keyword> <keyword>header</keyword> <keyword>field</keyword> <keyword>trailer</keyword> <abstract> <t>This specification definesQPACK,QPACK: a compression format for efficiently representing HTTPfields,fields that is to be used in HTTP/3. This is a variation of HPACK compression that seeks to reduce head-of-line blocking.</t> </abstract><note> <name>Note to Readers</name> <t>Discussion of this draft takes place on the QUIC working group mailing list (<eref target="mailto:quic@ietf.org">quic@ietf.org</eref>), which is archived at <eref target="https://mailarchive.ietf.org/arch/search/?email_list=quic"/>.</t> <t>Working Group information can be found at <eref target="https://github.com/quicwg"/>; source code and issues list for this draft can be found at <eref target="https://github.com/quicwg/base-drafts/labels/-qpack"/>.</t> </note></front> <middle> <sectionanchor="introduction" numbered="true" toc="default">anchor="introduction"> <name>Introduction</name> <t>The QUIC transport protocol (<xreftarget="QUIC-TRANSPORT" format="default"/>)target="QUIC-TRANSPORT"/>) is designed to support HTTP semantics, and its design subsumes many of the features of HTTP/2 (<xreftarget="RFC7540" format="default"/>).target="HTTP2"/>). HTTP/2 uses HPACK (<xreftarget="RFC7541" format="default"/>)target="RFC7541"/>) for compression of the header and trailer sections. If HPACK were used for HTTP/3 (<xreftarget="HTTP3" format="default"/>),target="HTTP3"/>), it would induce head-of-line blocking for field sections due to built-in assumptions of a total ordering across frames on all streams.</t> <t>QPACK reuses core concepts from HPACK, but is redesigned to allow correctness in the presence of out-of-order delivery, with flexibility for implementations to balance between resilience against head-of-line blocking and optimal compression ratio. The design goals are to closely approach the compression ratio of HPACK with substantially less head-of-line blocking under the same loss conditions.</t> <sectionanchor="conventions-and-definitions" numbered="true" toc="default">anchor="conventions-and-definitions"> <name>Conventions and Definitions</name> <t>The key words"MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY","<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", "<bcp14>MAY</bcp14>", and"OPTIONAL""<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as described in BCP 14 <xreftarget="RFC2119" format="default"/>target="RFC2119"/> <xreftarget="RFC8174" format="default"/>target="RFC8174"/> when, and only when, they appear in all capitals, as shown here.</t><t>Definitions of<t>The following termsthatare used in this document:</t> <dl><dt> HTTP fields: </dt><dt>HTTP fields:</dt> <dd> <t>Metadata sent as part of an HTTP message. The term encompasses both header and trailer fields. Colloquially, the term "headers" has often been used to refer to HTTP header fields and trailer fields; this document uses "fields" for generality.</t> </dd><dt> HTTP<dt>HTTP fieldline: </dt>line:</dt> <dd> <t>A name-value pair sent as part of an HTTP field section. See Sections <xreftarget="SEMANTICS"target="HTTP" section="6.3"sectionFormat="bare" format="default"/>sectionFormat="bare"/> and <xreftarget="SEMANTICS"target="HTTP" section="6.5"sectionFormat="bare" format="default"/>sectionFormat="bare"/> of <xreftarget="SEMANTICS" format="default"/>.</t>target="HTTP"/>.</t> </dd><dt> HTTP<dt>HTTP fieldvalue: </dt>value:</dt> <dd> <t>Data associated with a field name, composed from all field line values with that field name in that section, concatenated together with comma separators.</t> </dd><dt> Field section: </dt><dt>Field section:</dt> <dd> <t>An ordered collection of HTTP field lines associated with an HTTP message. A field section can contain multiple field lines with the same name. It can also contain duplicate field lines. An HTTP message can include both header and trailer sections.</t> </dd><dt> Representation: </dt><dt>Representation:</dt> <dd> <t>An instruction that represents a field line, possibly by reference to the dynamic and static tables.</t> </dd><dt> Encoder: </dt><dt>Encoder:</dt> <dd> <t>An implementation that encodes field sections.</t> </dd><dt> Decoder: </dt><dt>Decoder:</dt> <dd> <t>An implementation that decodes encoded field sections.</t> </dd><dt> Absolute Index: </dt><dt>Absolute Index:</dt> <dd> <t>A unique index for each entry in the dynamic table.</t> </dd><dt> Base: </dt><dt>Base:</dt> <dd> <t>A reference point for relative andpost-basepost-Base indices. Representations that reference dynamic table entries are relative to a Base.</t> </dd><dt> Insert Count: </dt><dt>Insert Count:</dt> <dd> <t>The total number of entries inserted in the dynamic table.</t> </dd> </dl><t>QPACK<t>Note that QPACK is a name, not anacronym.</t>abbreviation.</t> </section> <sectionanchor="notational-conventions" numbered="true" toc="default">anchor="notational-conventions"> <name>Notational Conventions</name> <t>Diagrams in this document use the format described in <xref section="3.1" sectionFormat="of"target="RFC2360" format="default"/>,target="RFC2360"/>, with the following additional conventions:</t> <dl><dt> x (A) </dt><dt>x (A)</dt> <dd> <t>Indicates that x is A bitslong</t>long.</t> </dd><dt> x (A+) </dt><dt>x (A+)</dt> <dd> <t>Indicates that x uses the prefixed integer encoding defined in <xreftarget="prefixed-integers" format="default"/>,target="prefixed-integers"/>, beginning with an A-bit prefix.</t> </dd><dt> x ... </dt><dt>x ...</dt> <dd> <t>Indicates that x isvariable-lengthvariable length and extends to the end of the region.</t> </dd> </dl> </section> </section> <sectionanchor="compression-process-overview" numbered="true" toc="default">anchor="compression-process-overview"> <name>Compression Process Overview</name> <t>Like HPACK, QPACK uses two tables for associating field lines ("headers") to indices. The static table (<xreftarget="header-table-static" format="default"/>)target="header-table-static"/>) is predefined and contains common header field lines (some of them with an empty value). The dynamic table (<xreftarget="header-table-dynamic" format="default"/>)target="header-table-dynamic"/>) is built up over the course of the connection and can be used by the encoder to index both header and trailer field lines in the encoded field sections.</t> <t>QPACK defines unidirectional streams for sending instructions from encoder to decoder and vice versa.</t> <sectionanchor="encoder" numbered="true" toc="default">anchor="encoder"> <name>Encoder</name> <t>An encoder converts a header or trailer section into a series of representations by emitting either an indexed or a literal representation for each field line in the list; see <xreftarget="field-line-representations" format="default"/>.target="field-line-representations"/>. Indexed representations achieve high compression by replacing the literal name and possibly the value with an index to either the static or dynamic table. References to the static table and literal representations do not require any dynamic state and never risk head-of-line blocking. References to the dynamic table risk head-of-line blocking if the encoder has not received an acknowledgment indicating the entry is available at the decoder.</t> <t>An encoderMAY<bcp14>MAY</bcp14> insert any entry in the dynamic table it chooses; it is not limited to field lines it is compressing.</t> <t>QPACK preserves the ordering of field lines within each field section. An encoderMUST<bcp14>MUST</bcp14> emit field representations in the order they appear in the input field section.</t> <t>QPACK is designed tocontainplace themore complexburden of optional state trackingtoon the encoder,while the decoder isresulting in relativelysimple.</t>simple decoders.</t> <sectionanchor="blocked-insertion" numbered="true" toc="default">anchor="blocked-insertion"> <name>Limits on Dynamic Table Insertions</name> <t>Inserting entries into the dynamic table might not be possible if the table contains entries that cannot be evicted.</t> <t>A dynamic table entry cannot be evicted immediately after insertion, even if it has never been referenced. Once the insertion of a dynamic table entry has been acknowledged and there are no outstanding references to the entry in unacknowledged representations, the entry becomes evictable. Note that references on the encoder stream never preclude the eviction of an entry, because those references are guaranteed to be processed before the instruction evicting the entry.</t> <t>If the dynamic table does not contain enough room for a new entry without evicting other entries, and the entries that would be evicted are not evictable, the encoderMUST NOT<bcp14>MUST NOT</bcp14> insert that entry into the dynamic table (including duplicates of existing entries). In order to avoid this, an encoder that uses the dynamic table has to keep track of each dynamic table entry referenced by each field section until those representations are acknowledged by the decoder; see <xreftarget="header-acknowledgment" format="default"/>.</t>target="header-acknowledgment"/>.</t> <sectionanchor="avoiding-prohibited-insertions" numbered="true" toc="default">anchor="avoiding-prohibited-insertions"> <name>Avoiding Prohibited Insertions</name> <t>To ensure that the encoder is not prevented from adding new entries, the encoder can avoid referencing entries that are close to eviction. Rather than reference such an entry, the encoder can emit a Duplicate instruction (<xreftarget="duplicate" format="default"/>),target="duplicate"/>) and reference the duplicate instead.</t> <t>Determining which entries are too close to eviction to reference is an encoder preference. One heuristic is to target a fixed amount of available space in the dynamic table: either unused space or space that can be reclaimed by evicting non-blocking entries. To achieve this, the encoder can maintain a draining index, which is the smallest absolute index (<xreftarget="indexing" format="default"/>)target="indexing"/>) 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. If the encoder does not create new references to entries with an absolute index lower than the draining index, the number of unacknowledged references to those entries will eventually become zero, allowing them to be evicted.</t> <figure anchor="fig-draining-index"> <name>Draining Dynamic Table Entries</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ <-- Newer Entries Older Entries --> (LargerIndicies)Indices) (SmallerIndicies)Indices) +--------+---------------------------------+----------+ | Unused | Referenceable | Draining | | Space | Entries | Entries | +--------+---------------------------------+----------+ ^ ^ ^ | | | Insertion Point Draining Index Dropping Point ]]></artwork> </figure> </section> </section> <sectionanchor="blocked-streams" numbered="true" toc="default">anchor="blocked-streams"> <name>Blocked Streams</name> <t>Because QUIC does not guarantee order between data on different streams, a decoder might encounter a representation that references a dynamic table entry that it has not yet received.</t> <t>Each encoded field section contains a Required Insert Count (<xreftarget="header-prefix" format="default"/>),target="header-prefix"/>), the lowest possible value for the Insert Count with which the field section can be decoded. For a field section encoded using references to the dynamic table, the Required Insert Count is one larger than the largest absolute index of all referenced dynamic table entries. For a field section encoded with no references to the dynamic table, the Required Insert Count is zero.</t> <t>When the decoder receives an encoded field section with a Required Insert Count greater than its own Insert Count, the stream cannot be processedimmediately,immediately and is considered "blocked"; see <xreftarget="blocked-decoding" format="default"/>.</t>target="blocked-decoding"/>.</t> <t>The decoder specifies an upper bound on the number of streams that can be blocked using the SETTINGS_QPACK_BLOCKED_STREAMS setting; see <xreftarget="configuration" format="default"/>.target="configuration"/>. An encoderMUST<bcp14>MUST</bcp14> limit the number of streams that could become blocked to the value of SETTINGS_QPACK_BLOCKED_STREAMS at all times. If a decoder encounters more blocked streams than it promised to support, itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED.</t> <t>Note that the decoder might not become blocked on every stream that risks becoming blocked.</t> <t>An encoder can decide whether to risk having a stream become blocked. If permitted by the value of SETTINGS_QPACK_BLOCKED_STREAMS, compression efficiency can often be improved by referencing dynamic table entries that are still in transit, but if there is loss orreorderingreordering, the stream can become blocked at the decoder. An encoder can avoid the risk of blocking by only referencing dynamic table entries that have been acknowledged, but this could mean using literals. Since literals make the encoded field section larger, this can result in the encoder becoming blocked on congestion orflow controlflow-control limits.</t> </section> <sectionanchor="avoiding-flow-control-deadlocks" numbered="true" toc="default">anchor="avoiding-flow-control-deadlocks"> <name>AvoidingFlow ControlFlow-Control Deadlocks</name> <t>Writing instructions on streams that are limited by flow control can produce deadlocks.</t> <t>A decoder might stop issuingflow controlflow-control credit on the stream that carries an encoded field section until the necessary updates are received on the encoder stream. If the granting offlow controlflow-control credit on the encoder stream (or the connection as a whole) depends on the consumption and release of data on the stream carrying the encoded field section, a deadlock might result.</t> <t>More generally, a stream containing a large instruction can become deadlocked if the decoder withholdsflow controlflow-control credit until the instruction is completely received.</t> <t>To avoid these deadlocks, an encoderSHOULD NOT<bcp14>SHOULD NOT</bcp14> write an instruction unless sufficient stream and connectionflow controlflow-control credit is available for the entire instruction.</t> </section> <sectionanchor="known-received-count" numbered="true" toc="default">anchor="known-received-count"> <name>Known Received Count</name> <t>The Known Received Count is the total number of dynamic table insertions and duplications acknowledged by the decoder. The encoder tracks the Known Received Count in order to identify which dynamic table entries can be referenced without potentially blocking a stream. The decoder tracks the Known Received Count in order to be able to send Insert Count Increment instructions.</t> <t>A Section Acknowledgment instruction (<xreftarget="header-acknowledgment" format="default"/>)target="header-acknowledgment"/>) implies that the decoder has received all dynamic table state necessary to decode the field section. If the Required Insert Count of the acknowledged field section is greater than the current Known Received Count, the Known Received Count is updated to that Required Insert Count value.</t> <t>An Insert Count Increment instruction (<xreftarget="insert-count-increment" format="default"/>)target="insert-count-increment"/>) increases the Known Received Count by its Increment parameter. See <xreftarget="new-table-entries" format="default"/>target="new-table-entries"/> for guidance.</t> </section> </section> <sectionanchor="decoder" numbered="true" toc="default">anchor="decoder"> <name>Decoder</name> <t>As in HPACK, the decoder processes a series of representations and emits the corresponding field sections. It also processes instructions received on the encoder stream that modify the dynamic table. Note that encoded field sections and encoder stream instructions arrive on separate streams. This is unlike HPACK, where encoded field sections (header blocks) can contain instructions that modify the dynamic table, and there is no dedicated stream of HPACK instructions.</t> <t>The decoderMUST<bcp14>MUST</bcp14> emit field lines in the order their representations appear in the encoded field section.</t> <sectionanchor="blocked-decoding" numbered="true" toc="default">anchor="blocked-decoding"> <name>Blocked Decoding</name> <t>Upon receipt of an encoded field section, the decoder examines the Required Insert Count. When the Required Insert Count is less than or equal to the decoder's Insert Count, the field section can be processed immediately. Otherwise, the stream on which the field section was received becomes blocked.</t> <t>While blocked, encoded field section dataSHOULD<bcp14>SHOULD</bcp14> remain in the blocked stream'sflow controlflow-control window. This data is unusable until the stream becomes unblocked, and releasing the flow control prematurely makes the decoder vulnerable to memory exhaustion attacks. A stream becomes unblocked when the Insert Count becomesunblocked when the Insert Count becomesgreater than or equal to the Required Insert Count for all encoded field sections the decoder has started reading from the stream.</t> <t>When processing encoded field sections, the decoder expects the Required Insert Count to equal the lowest possible value for the Insert Count with which the field section can be decoded, as prescribed in <xreftarget="blocked-streams" format="default"/>.target="blocked-streams"/>. If it encounters a Required Insert Count smaller than expected, itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED; see <xreftarget="invalid-references" format="default"/>.target="invalid-references"/>. If it encounters a Required Insert Count larger than expected, itMAY<bcp14>MAY</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED.</t> </section> <sectionanchor="state-synchronization" numbered="true" toc="default">anchor="state-synchronization"> <name>State Synchronization</name> <t>The decoder signals the following events by emitting decoder instructions (<xreftarget="decoder-instructions" format="default"/>)target="decoder-instructions"/>) on the decoder stream.</t> <sectionanchor="completed-processing-of-a-field-section" numbered="true" toc="default">anchor="completed-processing-of-a-field-section"> <name>Completed Processing of a Field Section</name> <t>After the decoder finishes decoding a field section encoded using representations containing dynamic table references, itMUST<bcp14>MUST</bcp14> emit a Section Acknowledgment instruction (<xreftarget="header-acknowledgment" format="default"/>).target="header-acknowledgment"/>). A stream may carry multiple field sections in the case of intermediate responses, trailers, and pushed requests. The encoder interprets each Section Acknowledgment instruction as acknowledging the earliest unacknowledged field section containing dynamic table references sent on the given stream.</t> </section> <sectionanchor="abandonment-of-a-stream" numbered="true" toc="default">anchor="abandonment-of-a-stream"> <name>Abandonment of a Stream</name> <t>When an endpoint receives a stream reset before the end of a stream or before all encoded field sections are processed on that stream, or when it abandons reading of a stream, it generates a Stream Cancellation instruction; see <xreftarget="stream-cancellation" format="default"/>.target="stream-cancellation"/>. This signals to the encoder that all references to the dynamic table on that stream are no longer outstanding. A decoder with a maximum dynamic table capacity (<xreftarget="maximum-dynamic-table-capacity" format="default"/>)target="maximum-dynamic-table-capacity"/>) equal to zeroMAY<bcp14>MAY</bcp14> 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 dynamic table have been received.</t> <t>The Section Acknowledgment and Stream Cancellation instructions permit the encoder to remove references to entries in the dynamic table. When an entry with an absolute index lower than the Known Received Count has zero references, then it is considered evictable; see <xreftarget="blocked-insertion" format="default"/>.</t>target="blocked-insertion"/>.</t> </section> <sectionanchor="new-table-entries" numbered="true" toc="default">anchor="new-table-entries"> <name>New Table Entries</name> <t>After receiving new table entries on the encoder stream, the decoder chooses when to emit Insert Count Increment instructions; see <xreftarget="insert-count-increment" format="default"/>.target="insert-count-increment"/>. Emitting this instruction after adding each new dynamic table entry will provide the timeliest feedback to the encoder, but could be redundant with other decoder feedback. By delaying an Insert Count Increment instruction, the decoder might be able to coalesce multiple Insert Count Incrementinstructions,instructions or replace them entirely with Section Acknowledgments; see <xreftarget="header-acknowledgment" format="default"/>.target="header-acknowledgment"/>. However, delaying too long may lead to compression inefficiencies if the encoder waits for an entry to be acknowledged before using it.</t> </section> </section> <sectionanchor="invalid-references" numbered="true" toc="default">anchor="invalid-references"> <name>Invalid References</name> <t>If the decoder encounters a reference in a field line representation to a dynamic table entry that has already been evicted or that has an absolute index greater than or equal to the declared Required Insert Count (<xreftarget="header-prefix" format="default"/>),target="header-prefix"/>), itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED.</t> <t>If the decoder encounters a reference in an encoder instruction to a dynamic table entry that has already been evicted, itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_ENCODER_STREAM_ERROR.</t> </section> </section> </section> <sectionanchor="reference-tables" numbered="true" toc="default">anchor="reference-tables"> <name>Reference Tables</name> <t>Unlike in HPACK, entries in the QPACK static and dynamic tables are addressed separately. The following sections describe how entries in each table are addressed.</t> <sectionanchor="header-table-static" numbered="true" toc="default">anchor="header-table-static"> <name>Static Table</name> <t>The static table consists of a predefined list of field lines, each of which has a fixed index over time. Its entries are defined in <xreftarget="static-table" format="default"/>.</t>target="static-table"/>.</t> <t>All entries in the static table have a name and a value. However, values can be empty (that is, have a length of 0). Each entry is identified by a unique index.</t> <t>Note that the QPACK static table is indexed from 0, whereas the HPACK static table is indexed from 1.</t> <t>When the decoder encounters an invalid static table index in a field linerepresentationrepresentation, itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED. If this index is received on the encoder stream, thisMUST<bcp14>MUST</bcp14> be treated as a connection error of type QPACK_ENCODER_STREAM_ERROR.</t> </section> <sectionanchor="header-table-dynamic" numbered="true" toc="default">anchor="header-table-dynamic"> <name>Dynamic Table</name> <t>The dynamic table consists of a list of field lines maintained in first-in, first-out order. A QPACK encoder and decoder share a dynamic table that is initially empty. The encoder adds entries to the dynamic table and sends them to the decoder via instructions on the encoder stream; see <xreftarget="encoder-instructions" format="default"/>.</t>target="encoder-instructions"/>.</t> <t>The dynamic table can contain duplicate entries (i.e., entries with the same name and same value). Therefore, duplicate entriesMUST NOT<bcp14>MUST NOT</bcp14> be treated as an error by the decoder.</t> <t>Dynamic table entries can have empty values.</t> <sectionanchor="dynamic-table-size" numbered="true" toc="default">anchor="dynamic-table-size"> <name>Dynamic Table Size</name> <t>The size of the dynamic table is the sum of the size of its entries.</t> <t>The size of an entry is the sum of its name's length in bytes, its value's length in bytes, and 32 additional bytes. The size of an entry is calculated using the length of its name and value without Huffman encoding applied.</t> </section> <sectionanchor="eviction" numbered="true" toc="default">anchor="eviction"> <name>Dynamic Table Capacity and Eviction</name> <t>The encoder sets the capacity of the dynamic table, which serves as the upper limit on its size. The initial capacity of the dynamic table is zero. The encoder sends a Set Dynamic Table Capacity instruction (<xreftarget="set-dynamic-capacity" format="default"/>)target="set-dynamic-capacity"/>) with a non-zero capacity to begin using the dynamic table.</t> <t>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 (table capacity - size of new entry). The encoderMUST NOT<bcp14>MUST NOT</bcp14> cause a dynamic table entry to be evicted unless that entry is evictable; see <xreftarget="blocked-insertion" format="default"/>.target="blocked-insertion"/>. The new entry is then added to the table. It is an error if the encoder attempts to add an entry that is larger than the dynamic table capacity; the decoderMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_ENCODER_STREAM_ERROR.</t> <t>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 or value if the referenced entry is evicted from the dynamic table prior to inserting the new entry.</t> <t>Whenever the dynamic table capacity is reduced by the encoder (<xreftarget="set-dynamic-capacity" format="default"/>),target="set-dynamic-capacity"/>), entries are evicted from the end of the dynamic table until the size of the dynamic table is less than or equal to the new table capacity. This mechanism can be used to completely clear entries from the dynamic table by setting a capacity of 0, which can subsequently be restored.</t> </section> <sectionanchor="maximum-dynamic-table-capacity" numbered="true" toc="default">anchor="maximum-dynamic-table-capacity"> <name>Maximum Dynamic Table Capacity</name> <t>To bound the memory requirements of the decoder, the decoder limits the maximum value the encoder is permitted to set for the dynamic table capacity. In HTTP/3, this limit is determined by the value of SETTINGS_QPACK_MAX_TABLE_CAPACITY sent by the decoder; see <xreftarget="configuration" format="default"/>.target="configuration"/>. The encoderMUST NOT<bcp14>MUST NOT</bcp14> set a dynamic table capacity that exceeds this maximum, but it can choose to use a lower dynamic table capacity; see <xreftarget="set-dynamic-capacity" format="default"/>.</t>target="set-dynamic-capacity"/>.</t> <t>For clients using 0-RTT data in HTTP/3, the server's maximum table capacity is the remembered value of thesetting,setting or zero if the value was not previously sent. When the client's 0-RTT value of the SETTING is zero, the serverMAY<bcp14>MAY</bcp14> set it to a non-zero value in its SETTINGS frame. If the remembered value is non-zero, the serverMUST<bcp14>MUST</bcp14> send the same non-zero value in its SETTINGS frame. If it specifies any other value, or omits SETTINGS_QPACK_MAX_TABLE_CAPACITY from SETTINGS, the encoder must treat this as a connection error of type QPACK_DECODER_STREAM_ERROR.</t> <t>ForHTTP/3 servers and HTTP/3clientswhennot using 0-RTT data (whether 0-RTT is not attempted or isrejected,rejected) and for all HTTP/3 servers, the maximum table capacity is 0 until the encoder processes a SETTINGS frame with a non-zero value of SETTINGS_QPACK_MAX_TABLE_CAPACITY.</t> <t>When the maximum table capacity is zero, the encoderMUST NOT<bcp14>MUST NOT</bcp14> insert entries into the dynamictable,table andMUST NOT<bcp14>MUST NOT</bcp14> send any encoder instructions on the encoder stream.</t> </section> <sectionanchor="indexing" numbered="true" toc="default">anchor="indexing"> <name>Absolute Indexing</name> <t>Each entry possesses an absolute index that is fixed for the lifetime of that entry. The first entry inserted has an absolute index of 0; indices increase by one with each insertion.</t> </section> <sectionanchor="relative-indexing" numbered="true" toc="default">anchor="relative-indexing"> <name>Relative Indexing</name> <t>Relative indices begin at zero and increase in the opposite direction from the absolute index. Determining which entry has a relative index of 0 depends on the context of the reference.</t> <t>In encoder instructions (<xreftarget="encoder-instructions" format="default"/>),target="encoder-instructions"/>), a relative index of 0 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.</t> <figure> <name>Example Dynamic Table Indexing - Encoder Stream</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ +-----+---------------+-------+ | n-1 | ... | d | Absolute Index + - - +---------------+ - - - + | 0 | ... | n-d-1 | Relative Index +-----+---------------+-------+ ^ | | V Insertion Point Dropping Point n = count of entries inserted d = count of entries dropped ]]></artwork> </figure> <t>Unlike in encoder instructions, relative indices in field line representations are relative to the Base at the beginning of the encoded field section; see <xreftarget="header-prefix" format="default"/>.target="header-prefix"/>. This ensures that references are stable even if encoded field sections and dynamic table updates are processed out of order.</t> <t>In a field line representation, a relative index of 0 refers to the entry with absolute index equal to Base - 1.</t> <figure> <name>Example Dynamic Table Indexing - Relative Index in Representation</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ Base | V +-----+-----+-----+-----+-------+ | n-1 | n-2 | n-3 | ... | d | Absolute Index +-----+-----+ - +-----+ - + | 0 | ... | n-d-3 | Relative Index +-----+-----+-------+ n = count of entries inserted d = count of entries dropped In this example, Base = n - 2 ]]></artwork> </figure> </section> <sectionanchor="post-base" numbered="true" toc="default">anchor="post-base"> <name>Post-Base Indexing</name> <t>Post-Base indices are used in field line representations for entries with absolute indices greater than or equal to Base, starting at 0 for the entry with absolute index equal toBase,Base and increasing in the same direction as the absolute index.</t> <t>Post-Base indices allow an encoder to process a field section in a single pass and include references to entries added while processing this (or other) field sections.</t> <figure> <name>Example Dynamic Table Indexing - Post-Base Index in Representation</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ Base | V +-----+-----+-----+-----+-----+ | n-1 | n-2 | n-3 | ... | d | Absolute Index +-----+-----+-----+-----+-----+ | 1 | 0 | Post-Base Index +-----+-----+ n = count of entries inserted d = count of entries dropped In this example, Base = n - 2 ]]></artwork> </figure> </section> </section> </section> <sectionanchor="wire-format" numbered="true" toc="default">anchor="wire-format"> <name>Wire Format</name> <sectionanchor="primitives" numbered="true" toc="default">anchor="primitives"> <name>Primitives</name> <sectionanchor="prefixed-integers" numbered="true" toc="default">anchor="prefixed-integers"> <name>Prefixed Integers</name> <t>The prefixed integer from <xref section="5.1" sectionFormat="of"target="RFC7541" format="default"/>target="RFC7541"/> is used heavily throughout this document. The format from <xreftarget="RFC7541" format="default"/>target="RFC7541"/> is used unmodified. Note, however, that QPACK uses some prefix sizes not actually used in HPACK.</t> <t>QPACK implementationsMUST<bcp14>MUST</bcp14> be able to decode integers up to and including 62 bits long.</t> </section> <sectionanchor="string-literals" numbered="true" toc="default">anchor="string-literals"> <name>String Literals</name> <t>The string literal defined by <xref section="5.2" sectionFormat="of"target="RFC7541" format="default"/>target="RFC7541"/> is also used throughout. This string format includes optional Huffman encoding.</t> <t>HPACK defines string literals to begin on a byte boundary. They begin with a single bit flag, denoted as 'H' in this document (indicating whether the string isHuffman-coded),Huffman encoded), followed by theLengthstring length encoded as a 7-bit prefix integer, and finallyLengththe indicated number of bytes of data. When Huffman encoding is enabled, the Huffman table from <xref section="B" sectionFormat="of"target="RFC7541" format="default"/>target="RFC7541"/> is used without modification andLength indicatesthe indicated length is the size of the string after encoding.</t> <t>This document expands the definition of string literals by permitting them to begin other than on a byte boundary. An "N-bit prefix string literal" begins mid-byte, with the first (8-N) bits allocated to a previous field. The string uses one bit for the Huffman flag, followed by theLengthlength of the encoded string asana (N-1)-bit prefix integer. The prefix size, N, can have a value between 2 and88, inclusive. The remainder of the string literal is unmodified.</t> <t>A string literal without a prefix length noted is an 8-bit prefix string literal and follows the definitions in <xreftarget="RFC7541" format="default"/>target="RFC7541"/> without modification.</t> </section> </section> <sectionanchor="enc-dec-stream-def" numbered="true" toc="default">anchor="enc-dec-stream-def"> <name>Encoder and Decoder Streams</name> <t>QPACK defines two unidirectional stream types:</t> <ul spacing="normal"> <li>An encoder stream is a unidirectional stream of type 0x02. It carries an unframed sequence of encoder instructions from encoder to decoder.</li> <li>A decoder stream is a unidirectional stream of type 0x03. It carries an unframed sequence of decoder instructions from decoder to encoder.</li> </ul> <t>HTTP/3 endpoints contain a QPACK encoder and decoder. Each endpointMUST initiate<bcp14>MUST</bcp14> initiate, atmostmost, one encoder streamandand, atmostmost, one decoder stream. Receipt of a second instance of either stream typeMUST<bcp14>MUST</bcp14> be treated as a connection error of type H3_STREAM_CREATION_ERROR.</t><t>These streams MUST NOT be closed.<t>The sender <bcp14>MUST NOT</bcp14> close either of these streams, and the receiver <bcp14>MUST NOT</bcp14> request that the sender close either of these streams. Closure of either unidirectional stream typeMUST<bcp14>MUST</bcp14> be treated as a connection error of type H3_CLOSED_CRITICAL_STREAM.</t> <t>An endpointMAY<bcp14>MAY</bcp14> avoid creating an encoder stream if it will not be used (forexampleexample, if its encoder does not wish to use the dynamictable,table or if the maximum size of the dynamic table permitted by the peer is zero).</t> <t>An endpointMAY<bcp14>MAY</bcp14> avoid creating a decoder stream if its decoder sets the maximum capacity of the dynamic table to zero.</t> <t>An endpointMUST<bcp14>MUST</bcp14> allow its peer to create an encoder stream and a decoder stream even if the connection's settings prevent their use.</t> </section> <sectionanchor="encoder-instructions" numbered="true" toc="default">anchor="encoder-instructions"> <name>Encoder Instructions</name> <t>An encoder sends encoder instructions on the encoder stream to set the capacity of the dynamic table and add dynamic table entries. Instructions adding table entries can use existing entries to avoid transmitting redundant information. The name can be transmitted as a reference to an existing entry in the static or the dynamic table or as a string literal. For entries that already exist in the dynamic table, the full entry can also be used by reference, creating a duplicate entry.</t> <sectionanchor="set-dynamic-capacity" numbered="true" toc="default">anchor="set-dynamic-capacity"> <name>Set Dynamic Table Capacity</name> <t>An encoder informs the decoder of a change to the dynamic table capacity using an instruction that starts with the '001' 3-bit pattern. This is followed by the new dynamic table capacity represented as an integer with a 5-bit prefix; see <xreftarget="prefixed-integers" format="default"/>.</t>target="prefixed-integers"/>.</t> <figure anchor="fig-set-capacity"> <name>Set Dynamic Table Capacity</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | 1 | Capacity (5+) | +---+---+---+-------------------+ ]]></artwork> </figure> <t>The new capacityMUST<bcp14>MUST</bcp14> be lower than or equal to the limit described in <xreftarget="maximum-dynamic-table-capacity" format="default"/>.target="maximum-dynamic-table-capacity"/>. In HTTP/3, this limit is the value of the SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter (<xreftarget="configuration" format="default"/>)target="configuration"/>) received from the decoder. The decoderMUST<bcp14>MUST</bcp14> treat a new dynamic table capacity value that exceeds this limit as a connection error of type QPACK_ENCODER_STREAM_ERROR.</t> <t>Reducing the dynamic table capacity can cause entries to be evicted; see <xreftarget="eviction" format="default"/>.target="eviction"/>. ThisMUST NOT<bcp14>MUST NOT</bcp14> cause the eviction of entries that are not evictable; see <xreftarget="blocked-insertion" format="default"/>.target="blocked-insertion"/>. Changing the capacity of the dynamic table is not acknowledged as this instruction does not insert an entry.</t> </section> <sectionanchor="insert-with-name-reference" numbered="true" toc="default">anchor="insert-with-name-reference"> <name>InsertWithwith Name Reference</name> <t>An encoder adds an entry to the dynamic table where the field name matches the field name of an entry stored in the static or the dynamic table using an instruction that starts with the '1' 1-bit pattern. The second ('T') bit indicates whether the reference is to the static or dynamic table. The 6-bit prefix integer (<xreftarget="prefixed-integers" format="default"/>)target="prefixed-integers"/>) that follows is used to locate the table entry for the field name. When T=1, the number represents the static table index; when T=0, the number is the relative index of the entry in the dynamic table.</t> <t>The field name reference is followed by the field value represented as a string literal; see <xreftarget="string-literals" format="default"/>.</t>target="string-literals"/>.</t> <figure> <name>Insert Field Line -- Indexed Name</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 1 | T | Name Index (6+) | +---+---+-----------------------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length bytes) | +-------------------------------+ ]]></artwork> </figure> </section> <sectionanchor="insert-with-literal-name" numbered="true" toc="default">anchor="insert-with-literal-name"> <name>InsertWithwith Literal Name</name> <t>An encoder adds an entry to the dynamic table where both the field name and the field value are represented as string literals using an instruction that starts with the '01' 2-bit pattern.</t> <t>This is followed by the name represented as a 6-bit prefix stringliteral,literal and the value represented as an 8-bit prefix string literal; see <xreftarget="string-literals" format="default"/>.</t>target="string-literals"/>.</t> <figure> <name>Insert Field Line -- New Name</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 1 | H | Name Length (5+) | +---+---+---+-------------------+ | Name String (Length bytes) | +---+---------------------------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length bytes) | +-------------------------------+ ]]></artwork> </figure> </section> <sectionanchor="duplicate" numbered="true" toc="default">anchor="duplicate"> <name>Duplicate</name> <t>An encoder duplicates an existing entry in the dynamic table using an instruction that starts with the '000' 3-bit pattern. This is followed by the relative index of the existing entry represented as an integer with a 5-bit prefix; see <xreftarget="prefixed-integers" format="default"/>.</t>target="prefixed-integers"/>.</t> <figure anchor="fig-index-with-duplication"> <name>Duplicate</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | 0 | Index (5+) | +---+---+---+-------------------+ ]]></artwork> </figure> <t>The existing entry isre-insertedreinserted into the dynamic table without resending either the name or the value. This is useful to avoid adding a reference to an older entry, which might block inserting new entries.</t> </section> </section> <sectionanchor="decoder-instructions" numbered="true" toc="default">anchor="decoder-instructions"> <name>Decoder Instructions</name> <t>A decoder sends decoder instructions on the decoder stream to inform the encoder about the processing of field sections and table updates to ensure consistency of the dynamic table.</t> <sectionanchor="header-acknowledgment" numbered="true" toc="default">anchor="header-acknowledgment"> <name>Section Acknowledgment</name> <t>After processing an encoded field section whose declared Required Insert Count is not zero, the decoder emits a Section Acknowledgment instruction. The instruction starts with the '1' 1-bit pattern, followed by the field section's associated stream ID encoded as a 7-bit prefix integer; see <xreftarget="prefixed-integers" format="default"/>.</t>target="prefixed-integers"/>.</t> <t>This instruction is used as described in Sections <xreftarget="known-received-count" format="default"/>format="counter" target="known-received-count"/> andin<xreftarget="state-synchronization" format="default"/>.</t>format="counter" target="state-synchronization"/>.</t> <figure anchor="fig-header-ack"> <name>Section Acknowledgment</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 1 | Stream ID (7+) | +---+---------------------------+ ]]></artwork> </figure> <t>If an encoder receives a Section Acknowledgment instruction referring to a stream on which every encoded field section with a non-zero Required Insert Count has already been acknowledged, thisMUST<bcp14>MUST</bcp14> be treated as a connection error of type QPACK_DECODER_STREAM_ERROR.</t> <t>The Section Acknowledgment instruction might increase the Known Received Count; see <xreftarget="known-received-count" format="default"/>.</t>target="known-received-count"/>.</t> </section> <sectionanchor="stream-cancellation" numbered="true" toc="default">anchor="stream-cancellation"> <name>Stream Cancellation</name> <t>When a stream is reset or reading is abandoned, the decoder emits a Stream Cancellation instruction. The instruction starts with the '01' 2-bit pattern, followed by the stream ID of the affected stream encoded as a 6-bit prefix integer.</t> <t>This instruction is used as described in <xreftarget="state-synchronization" format="default"/>.</t>target="state-synchronization"/>.</t> <figure anchor="fig-stream-cancel"> <name>Stream Cancellation</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 1 | Stream ID (6+) | +---+---+-----------------------+ ]]></artwork> </figure> </section> <sectionanchor="insert-count-increment" numbered="true" toc="default">anchor="insert-count-increment"> <name>Insert Count Increment</name> <t>The Insert Count Increment instruction starts with the '00' 2-bit pattern, followed by the Increment encoded as a 6-bit prefix integer. This instruction increases the Known Received Count (<xreftarget="known-received-count" format="default"/>)target="known-received-count"/>) by the value of the Increment parameter. The decoder should send an Increment value that increases the Known Received Count to the total number of dynamic table insertions and duplications processed so far.</t> <figure anchor="fig-size-sync"> <name>Insert Count Increment</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | Increment (6+) | +---+---+-----------------------+ ]]></artwork> </figure> <t>An encoder that receives an Increment field equal to zero, or one that increases the Known Received Count beyond what the encoder hassent MUSTsent, <bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECODER_STREAM_ERROR.</t> </section> </section> <sectionanchor="field-line-representations" numbered="true" toc="default">anchor="field-line-representations"> <name>Field Line Representations</name> <t>An encoded field section consists of a prefix and a possibly empty sequence of representations defined in this section. Each representation corresponds to a single field line. These representations reference the static table or the dynamic table in a particular state, but they do not modify that state.</t> <t>Encoded field sections are carried in frames on streams defined by the enclosing protocol.</t> <sectionanchor="header-prefix" numbered="true" toc="default">anchor="header-prefix"> <name>Encoded Field Section Prefix</name> <t>Each encoded field section is prefixed with two integers. The Required Insert Count is encoded as an integer with an 8-bit prefix using the encoding described in <xreftarget="ric" format="default"/>.target="ric"/>. The Base is encoded as asignSign bit ('S') and a Delta Base value with a 7-bit prefix; see <xreftarget="base" format="default"/>.</t>target="base"/>.</t> <figure anchor="fig-base-index"> <name>Encoded Field Section</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | Required Insert Count (8+) | +---+---------------------------+ | S | Delta Base (7+) | +---+---------------------------+ | Encoded Field Lines ... +-------------------------------+ ]]></artwork> </figure> <sectionanchor="ric" numbered="true" toc="default">anchor="ric"> <name>Required Insert Count</name> <t>Required Insert Count identifies the state of the dynamic table needed to process the encoded field section. Blocking decoders use the Required Insert Count to determine when it is safe to process the rest of the field section.</t> <t>The encoder transforms the Required Insert Count as follows before encoding:</t><artwork name="" type="" align="left" alt=""><![CDATA[<sourcecode type="pseudocode"><![CDATA[ if ReqInsertCount == 0: EncInsertCount = 0 else: EncInsertCount = (ReqInsertCount mod (2 * MaxEntries)) + 1]]></artwork>]]></sourcecode> <t>Here <tt>MaxEntries</tt> 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.HenceHence, <tt>MaxEntries</tt> is calculatedas</t> <artwork name="" type="" align="left" alt=""><![CDATA[as:</t> <sourcecode type="pseudocode"><![CDATA[ MaxEntries = floor( MaxTableCapacity / 32 )]]></artwork>]]></sourcecode> <t><tt>MaxTableCapacity</tt> is the maximum capacity of the dynamic table as specified by the decoder; see <xreftarget="maximum-dynamic-table-capacity" format="default"/>.</t>target="maximum-dynamic-table-capacity"/>.</t> <t>This encoding limits the length of the prefix on long-lived connections.</t> <t>The decoder can reconstruct the Required Insert Count using an algorithm such as the following. If the decoder encounters a value of EncodedInsertCount that could not have been produced by a conformant encoder, itMUST<bcp14>MUST</bcp14> treat this as a connection error of type QPACK_DECOMPRESSION_FAILED.</t><t>TotalNumberOfInserts<t><tt>TotalNumberOfInserts</tt> is the total number of inserts into the decoder's dynamic table.</t><artwork name="" type="" align="left" alt=""><![CDATA[<sourcecode type="pseudocode"><![CDATA[ FullRange = 2 * MaxEntries if EncodedInsertCount == 0: ReqInsertCount = 0 else: if EncodedInsertCount > FullRange: Error MaxValue = TotalNumberOfInserts + MaxEntries # MaxWrapped is the largest possible value of # ReqInsertCount that is 0 mod 2 * MaxEntries MaxWrapped = floor(MaxValue / FullRange) * FullRange ReqInsertCount = MaxWrapped + EncodedInsertCount - 1 # If ReqInsertCount exceeds MaxValue, the Encoder's value # must have wrapped one fewer time if ReqInsertCount > MaxValue: if ReqInsertCount <= FullRange: Error ReqInsertCount -= FullRange # Value of 0 must be encoded as 0. if ReqInsertCount == 0: Error]]></artwork>]]></sourcecode> <t>For example, if the dynamic table is 100 bytes, then the Required Insert Count will be encoded modulo 6. If a decoder has received 10 inserts, then an encoded value of 4 indicates that the Required Insert Count is 9 for the field section.</t> </section> <sectionanchor="base" numbered="true" toc="default">anchor="base"> <name>Base</name> <t>The Base is used to resolve references in the dynamic table as described in <xreftarget="relative-indexing" format="default"/>.</t>target="relative-indexing"/>.</t> <t>To save space, the Base is encoded relative to the Required Insert Count using a one-bitsign ('S')Sign ('S' in <xref target="fig-base-index"/>) and the Delta Base value. AsignSign bit of 0 indicates that the Base is greater than or equal to the value of the Required Insert Count; the decoder adds the value of Delta Base to the Required Insert Count to determine the value of the Base. AsignSign bit of 1 indicates that the Base is less than the Required Insert Count; the decoder subtracts the value of Delta Base from the Required Insert Count and also subtracts one to determine the value of the Base. That is:</t><artwork name="" type="" align="left" alt=""><![CDATA[<sourcecode type="pseudocode"><![CDATA[ ifSSign == 0: Base = ReqInsertCount + DeltaBase else: Base = ReqInsertCount - DeltaBase - 1]]></artwork>]]></sourcecode> <t>A single-pass encoder determines the Base before encoding a field section. If the encoder inserted entries in the dynamic table while encoding the field section and is referencing them, Required Insert Count will be greater than the Base, so the encoded difference is negative and thesignSign bit is set to 1. If the field section was not encoded using representations that reference the most recent entry in the table and did not insert any new entries, the Base will be greater than the Required Insert Count, so thedeltaencoded difference will be positive and thesignSign bit is set to 0.</t> <t>The value of Base <bcp14>MUST NOT</bcp14> be negative. Though the protocol might operate correctly with a negative Base using post-Base indexing, it is unnecessary and inefficient. An endpoint <bcp14>MUST</bcp14> treat a field block with a Sign bit of 1 as invalid if the value of Required Insert Count is less than or equal to the value of Delta Base.</t> <t>An encoder that produces table updates before encoding a field section might set Base to the value of Required Insert Count. In such a case, both thesignSign bit and the Delta Base will be set to zero.</t> <t>A field section that was encoded without references to the dynamic table can use any value for the Base; setting Delta Base to zero is one of the most efficient encodings.</t> <t>For example, with a Required Insert Count of 9, a decoder receivesan Sa Sign bit of 1 and a Delta Base of 2. This sets the Base to 6 and enablespost-basepost-Base indexing for three entries. In this example, a relative index of 1 refers to the5thfifth entry that was added to the table; apost-basepost-Base index of 1 refers to the8theighth entry.</t> </section> </section> <sectionanchor="indexed-field-line" numbered="true" toc="default">anchor="indexed-field-line"> <name>Indexed Field Line</name> <t>An indexed field line representation identifies an entry in the statictable,table or an entry in the dynamic table with an absolute index less than the value of the Base.</t> <figure> <name>Indexed Field Line</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 1 | T | Index (6+) | +---+---+-----------------------+ ]]></artwork> </figure> <t>This representation starts with the '1' 1-bit pattern, followed by the 'T'bitbit, indicating whether the reference is into the static or dynamic table. The 6-bit prefix integer (<xreftarget="prefixed-integers" format="default"/>)target="prefixed-integers"/>) that follows is used to locate the table entry for the field line. When T=1, the number represents the static table index; when T=0, the number is the relative index of the entry in the dynamic table.</t> </section> <sectionanchor="indexed-field-line-with-post-base-index" numbered="true" toc="default">anchor="indexed-field-line-with-post-base-index"> <name>Indexed Field LineWithwith Post-Base Index</name> <t>An indexed field line withpost-basepost-Base index representation identifies an entry in the dynamic table with an absolute index greater than or equal to the value of the Base.</t> <figure> <name>Indexed Field Line with Post-Base Index</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | 0 | 1 | Index (4+) | +---+---+---+---+---------------+ ]]></artwork> </figure> <t>This representation starts with the '0001' 4-bit pattern. This is followed by thepost-basepost-Base index (<xreftarget="post-base" format="default"/>)target="post-base"/>) of the matching field line, represented as an integer with a 4-bit prefix; see <xreftarget="prefixed-integers" format="default"/>.</t>target="prefixed-integers"/>.</t> </section> <sectionanchor="literal-name-reference" numbered="true" toc="default">anchor="literal-name-reference"> <name>Literal Field LineWithwith Name Reference</name> <t>A literal field line with name reference representation encodes a field line where the field name matches the field name of an entry in the statictable,table or the field name of an entry in the dynamic table with an absolute index less than the value of the Base.</t> <figure> <name>Literal Field LineWithwith Name Reference</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 1 | N | T |Name Index (4+)| +---+---+---+---+---------------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length bytes) | +-------------------------------+ ]]></artwork> </figure> <t>This representation starts with the '01' 2-bit pattern. The following bit, 'N', indicates whether an intermediary is permitted to add this field line to the dynamic table on subsequent hops. When the 'N' bit is set, the encoded field lineMUST<bcp14>MUST</bcp14> always be encoded with a literal representation. In particular, when a peer sends a field line that it received represented as a literal field line with the 'N' bit set, itMUST<bcp14>MUST</bcp14> use a literal representation to forward this field line. This bit is intended for protecting field values that are not to be put at risk by compressing them; see <xreftarget="probing-dynamic-table-state" format="default"/>target="probing-dynamic-table-state"/> for more details.</t> <t>The fourth ('T') bit indicates whether the reference is to the static or dynamic table. The 4-bit prefix integer (<xreftarget="prefixed-integers" format="default"/>)target="prefixed-integers"/>) that follows is used to locate the table entry for the field name. When T=1, the number represents the static table index; when T=0, the number is the relative index of the entry in the dynamic table.</t> <t>Only the field name is taken from the dynamic table entry; the field value is encoded as an 8-bit prefix string literal; see <xreftarget="string-literals" format="default"/>.</t>target="string-literals"/>.</t> </section> <sectionanchor="literal-field-line-with-post-base-name-reference" numbered="true" toc="default">anchor="literal-field-line-with-post-base-name-reference"> <name>Literal Field LineWithwith Post-Base Name Reference</name> <t>A literal field line withpost-basepost-Base name reference representation encodes a field line where the field name matches the field name of a dynamic table entry with an absolute index greater than or equal to the value of the Base.</t> <figure> <name>Literal Field LineWithwith Post-Base Name Reference</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | 0 | 0 | N |NameIdx(3+)| +---+---+---+---+---+-----------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length bytes) | +-------------------------------+ ]]></artwork> </figure> <t>This representation starts with the '0000' 4-bit pattern. The fifth bit is the 'N' bit as described in <xreftarget="literal-name-reference" format="default"/>.target="literal-name-reference"/>. This is followed by apost-basepost-Base index of the dynamic table entry (<xreftarget="post-base" format="default"/>)target="post-base"/>) encoded as an integer with a 3-bit prefix; see <xreftarget="prefixed-integers" format="default"/>.</t>target="prefixed-integers"/>.</t> <t>Only the field name is taken from the dynamic table entry; the field value is encoded as an 8-bit prefix string literal; see <xreftarget="string-literals" format="default"/>.</t>target="string-literals"/>.</t> </section> <sectionanchor="literal-field-line-with-literal-name" numbered="true" toc="default">anchor="literal-field-line-with-literal-name"> <name>Literal Field LineWithwith Literal Name</name> <t>The literal field line with literal name representation encodes a field name and a field value as string literals.</t> <figure> <name>Literal Field LineWithwith Literal Name</name> <artworktype="drawing" name="" align="left" alt=""><![CDATA[type="ascii-art"><![CDATA[ 0 1 2 3 4 5 6 7 +---+---+---+---+---+---+---+---+ | 0 | 0 | 1 | N | H |NameLen(3+)| +---+---+---+---+---+-----------+ | Name String (Length bytes) | +---+---------------------------+ | H | Value Length (7+) | +---+---------------------------+ | Value String (Length bytes) | +-------------------------------+ ]]></artwork> </figure> <t>This representation starts with the '001' 3-bit pattern. The fourth bit is the 'N' bit as described in <xreftarget="literal-name-reference" format="default"/>.target="literal-name-reference"/>. The name follows, represented as a 4-bit prefix string literal, then the value, represented as an 8-bit prefix string literal; see <xreftarget="string-literals" format="default"/>.</t>target="string-literals"/>.</t> </section> </section> </section> <sectionanchor="configuration" numbered="true" toc="default">anchor="configuration"> <name>Configuration</name> <t>QPACK defines two settings for the HTTP/3 SETTINGS frame:</t> <dl><dt> SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x1): </dt><dt>SETTINGS_QPACK_MAX_TABLE_CAPACITY (0x01):</dt> <dd> <t>The default value is zero. See <xreftarget="header-table-dynamic" format="default"/>target="header-table-dynamic"/> for usage. This is the equivalent of the SETTINGS_HEADER_TABLE_SIZE from HTTP/2.</t> </dd><dt> SETTINGS_QPACK_BLOCKED_STREAMS (0x7): </dt><dt>SETTINGS_QPACK_BLOCKED_STREAMS (0x07):</dt> <dd> <t>The default value is zero. See <xreftarget="blocked-streams" format="default"/>.</t>target="blocked-streams"/>.</t> </dd> </dl> </section> <sectionanchor="error-handling" numbered="true" toc="default">anchor="error-handling"> <name>Error Handling</name> <t>The following error codes are defined for HTTP/3 to indicate failures of QPACK that prevent the stream or connection from continuing:</t> <dl><dt> QPACK_DECOMPRESSION_FAILED (0x200): </dt><dt>QPACK_DECOMPRESSION_FAILED (0x0200):</dt> <dd> <t>The decoder failed to interpret an encoded field section and is not able to continue decoding that field section.</t> </dd><dt> QPACK_ENCODER_STREAM_ERROR (0x201): </dt><dt>QPACK_ENCODER_STREAM_ERROR (0x0201):</dt> <dd> <t>The decoder failed to interpret an encoder instruction received on the encoder stream.</t> </dd><dt> QPACK_DECODER_STREAM_ERROR (0x202): </dt><dt>QPACK_DECODER_STREAM_ERROR (0x0202):</dt> <dd> <t>The encoder failed to interpret a decoder instruction received on the decoder stream.</t> </dd> </dl> </section> <sectionanchor="security-considerations" numbered="true" toc="default">anchor="security-considerations"> <name>Security Considerations</name> <t>This section describes potential areas of security concern with QPACK:</t> <ul spacing="normal"> <li>Use of compression as a length-based oracle for verifying guesses about secrets that are compressed into a shared compression context.</li> <li>Denial of service resulting from exhausting processing or memory capacity at a decoder.</li> </ul> <sectionanchor="probing-dynamic-table-state" numbered="true" toc="default">anchor="probing-dynamic-table-state"> <name>Probing Dynamic Table State</name> <t>QPACK reduces the encoded size of field sections by exploiting the redundancy inherent in protocols like HTTP. The ultimate goal of this is to reduce the amount of data that is required to send HTTP requests or responses.</t> <t>The compression context used to encode header and trailer fields can be probed by an attacker who can both define fields to be encoded and transmitted and observe the length of those fields once they are encoded. When an attacker can do both, they can adaptively modify requests in order to confirm guesses about the dynamic table state. If a guess is compressed into a shorter length, the attacker can observe the encoded length and infer that the guess was correct.</t> <t>This is possible even over the Transport Layer Security Protocol(TLS, see <xref target="TLS" format="default"/>)(<xref target="TLS"/>) and the QUIC Transport Protocol(see <xref target="QUIC-TRANSPORT" format="default"/>),(<xref target="QUIC-TRANSPORT"/>), because while TLS and QUIC provide confidentiality protection for content, they only provide a limited amount of protection for the length of that content.</t><dl> <dt> Note: </dt> <dd> <t>Padding<aside> <t>Note: Padding schemes only provide limited protection against an attacker with these capabilities, potentially only forcing an increased number of guesses to learn the length associated with a given guess. Padding schemes also work directly against compression by increasing the number of bits that are transmitted.</t></dd> </dl></aside> <t>Attacks like CRIME (<xreftarget="CRIME" format="default"/>)target="CRIME"/>) demonstrated the existence of these general attacker capabilities. The specific attack exploited the fact that DEFLATE (<xreftarget="RFC1951" format="default"/>)target="RFC1951"/>) removes redundancy based on prefix matching. This permitted the attacker to confirm guesses a character at a time, reducing an exponential-time attack into a linear-time attack.</t> <sectionanchor="applicability-to-qpack-and-http" numbered="true" toc="default">anchor="applicability-to-qpack-and-http"> <name>Applicability to QPACK and HTTP</name> <t>QPACKmitigatesmitigates, but does not completelypreventprevent, attacks modeled on CRIME (<xreftarget="CRIME" format="default"/>)target="CRIME"/>) by forcing a guess to match an entire fieldline,line rather than individual characters. An attacker can only learn whether a guess is correct or not, so the attacker is reduced to abrute forcebrute-force guess for the field values associated with a given field name.</t><t>The<t>Therefore, the viability of recovering specific field valuesthereforedepends on the entropy of values. As a result, values with high entropy are unlikely to be recovered successfully. However, values with low entropy remain vulnerable.</t> <t>Attacks of this nature are possible any time that two mutually distrustful entities control requests or responses that are placed onto a single HTTP/3 connection. If the shared QPACK compressor permits one entity to add entries to the dynamic table, and the other to refer to those entries while encoding chosen field lines, then the attacker (the second entity) can learn the state of the table by observing the length of the encoded output.</t> <t>For example, requests or responses from mutually distrustful entities can occur when an intermediary either:</t> <ul spacing="normal"> <li>sends requests from multiple clients on a single connection toward an origin server, or</li> <li>takes responses from multiple origin servers and places them on a shared connection toward a client.</li> </ul> <t>Web browsers also need to assume that requests made on the same connection by different web origins (<xreftarget="RFC6454" format="default"/>)target="RFC6454"/>) are made by mutually distrustful entities. Other scenarios involving mutually distrustful entities are also possible.</t> </section> <sectionanchor="mitigation" numbered="true" toc="default">anchor="mitigation"> <name>Mitigation</name> <t>Users of HTTP that require confidentiality for header or trailer fields can use values with entropy sufficient to make guessing infeasible. However, this is impractical as a general solution because it forces all users of HTTP to take steps to mitigate attacks. It would impose new constraints on how HTTP is used.</t> <t>Rather than impose constraints on users of HTTP, an implementation of QPACK can instead constrain how compression is applied in order to limit the potential for dynamic table probing.</t> <t>An ideal solution segregates access to the dynamic table based on the entity that is constructing the message. Field values that are added to the table are attributed to an entity, and only the entity that created a particular value can extract that value.</t> <t>To improve compression performance of this option, certain entries might be tagged as being public. For example, a web browser might make the values of the Accept-Encoding header field available in all requests.</t> <t>An encoder without good knowledge of the provenance of field values might instead introduce a penalty for many field lines with the same field name and different values. This penalty could cause a large number of attempts to guess a field value to result in the field not being compared to the dynamic table entries in future messages, effectively preventing further guesses.</t> <t>This response might be made inversely proportional to the length of the field value. Disabling access to the dynamic table for a given field name might occur for shorter values more quickly or with higher probability than for longer values.</t> <t>This mitigation is most effective between two endpoints. If messages are re-encoded by an intermediary without knowledge of which entity constructed a given message, the intermediary could inadvertently merge compression contexts that the original encoder had specifically kept separate.</t><dl> <dt> Note: </dt> <dd> <t>Simply<aside> <t>Note: Simply removing entries corresponding to the field from the dynamic table can be ineffectual if the attacker has a reliable way of causing values to be reinstalled. For example, a request to load an image in a web browser typically includes the Cookie header field (a potentially highly valued target for this sort of attack), andweb siteswebsites can easily force an image to be loaded, thereby refreshing the entry in the dynamic table.</t></dd> </dl></aside> </section> <sectionanchor="never-indexed-literals" numbered="true" toc="default">anchor="never-indexed-literals"> <name>Never-Indexed Literals</name> <t>Implementations can also choose to protect sensitive fields by not compressing them and instead encoding their value as literals.</t> <t>Refusing to insert a field line into the dynamic table is only effective if doing so is avoided on all hops. The never-indexed literal bit (see <xreftarget="literal-name-reference" format="default"/>)target="literal-name-reference"/>) can be used to signal to intermediaries that a particular value was intentionally sent as a literal.</t> <t>An intermediaryMUST NOT<bcp14>MUST NOT</bcp14> re-encode a value that uses a literal representation with the 'N' bit set with another representation that would index it. If QPACK is used for re-encoding, a literal representation with the 'N' bit setMUST<bcp14>MUST</bcp14> be used. If HPACK is used for re-encoding, the never-indexed literal representation (see <xref section="6.2.3" sectionFormat="of"target="RFC7541" format="default"/>) MUSTtarget="RFC7541"/>) <bcp14>MUST</bcp14> be used.</t> <t>The choice to mark that a field value should never be indexed depends on several factors. Since QPACK does not protect against guessing an entire field value, short or low-entropy values are more readily recovered by an adversary. Therefore, an encoder might choose not to index values with low entropy.</t> <t>An encoder might also choose not to index values for fields that are considered to be highly valuable or sensitive to recovery, such as the Cookie or Authorization header fields.</t> <t>On the contrary, an encoder might prefer indexing values for fields that have little or no value if they were exposed. For instance, a User-Agent header field does not commonly vary between requests and is sent to any server. In that case, confirmation that a particular User-Agent value has been used provides little value.</t> <t>Note that these criteria for deciding to use a never-indexed literal representation will evolve over time as new attacks are discovered.</t> </section> </section> <sectionanchor="static-huffman-encoding" numbered="true" toc="default">anchor="static-huffman-encoding"> <name>Static Huffman Encoding</name> <t>There is no currently known attack against a static Huffman encoding. A study has shown that using a static Huffman encoding table created an informationleakage, howeverleakage; however, this same study concluded that an attacker could not take advantage of this information leakage to recover any meaningful amount of information (see <xreftarget="PETAL" format="default"/>).</t>target="PETAL"/>).</t> </section> <sectionanchor="memory-consumption" numbered="true" toc="default">anchor="memory-consumption"> <name>Memory Consumption</name> <t>An attacker can try to cause an endpoint to exhaust its memory. QPACK is designed to limit both the peak and stable amounts of memory allocated by an endpoint.</t> <t>QPACK uses the definition of the maximum size of the dynamic table and the maximum number of blocking streams to limit the amount of memory the encoder can cause the decoder to consume. In HTTP/3, these values are controlled by the decoder through the settings parameters SETTINGS_QPACK_MAX_TABLE_CAPACITY and SETTINGS_QPACK_BLOCKED_STREAMS, respectively (see <xreftarget="maximum-dynamic-table-capacity" format="default"/>target="maximum-dynamic-table-capacity"/> and <xreftarget="blocked-streams" format="default"/>).target="blocked-streams"/>). The limit on the size of the dynamic table takes into account the size of the data stored in the dynamic table, plus a small allowance for overhead. The limit on the number of blocked streams is only a proxy for the maximum amount of memory required by the decoder. The actual maximum amount of memory will depend on how much memory the decoder uses to track each blocked stream.</t> <t>A decoder can limit the amount of state memory used for the dynamic table by setting an appropriate value for the maximum size of the dynamic table. In HTTP/3, this is realized by setting an appropriate value for the SETTINGS_QPACK_MAX_TABLE_CAPACITY parameter. An encoder can limit the amount of state memory it uses by choosing a smaller dynamic table size than the decoder allows and signaling this to the decoder (see <xreftarget="set-dynamic-capacity" format="default"/>).</t>target="set-dynamic-capacity"/>).</t> <t>A decoder can limit the amount of state memory used for blocked streams by setting an appropriate value for the maximum number of blocked streams. In HTTP/3, this is realized by setting an appropriate value for the SETTINGS_QPACK_BLOCKED_STREAMS parameter. Streamswhichthat risk becoming blocked consume no additional state memory on the encoder.</t> <t>An encoder allocates memory to track all dynamic table references in unacknowledged field sections. An implementation can directly limit the amount of state memory by only using as many references to the dynamic table as it wishes to track; no signaling to the decoder is required. However, limiting references to the dynamic table will reduce compression effectiveness.</t> <t>The amount of temporary memory consumed by an encoder or decoder can be limited by processing field lines sequentially. A decoder implementation does not need to retain a complete list of field lines while decoding a field section. An encoder implementation does not need to retain a complete list of field lines while encoding a field section if it is using a single-pass algorithm. Note that it might be necessary for an application to retain a complete list of field lines for other reasons; even if QPACK does not force this to occur, application constraints might make this necessary.</t> <t>While the negotiated limit on the dynamic table size accounts for much of the memory that can be consumed by a QPACK implementation, data that cannot be immediately sent due to flow control is not affected by this limit. Implementations should limit the size of unsent data, especially on the decoder stream where flexibility to choose what to send is limited. Possible responses to an excess of unsent data might include limiting the ability of the peer to open new streams, reading only from the encoder stream, or closing the connection.</t> </section> <sectionanchor="implementation-limits" numbered="true" toc="default">anchor="implementation-limits"> <name>Implementation Limits</name> <t>An implementation of QPACK needs to ensure that large values for integers, long encoding for integers, or long string literals do not create security weaknesses.</t> <t>An implementation has to set a limit for the values it accepts for integers, as well as for the encoded length; see <xreftarget="prefixed-integers" format="default"/>.target="prefixed-integers"/>. In the same way, it has to set a limit to the length it accepts for string literals; see <xreftarget="string-literals" format="default"/>.target="string-literals"/>. These limitsSHOULD<bcp14>SHOULD</bcp14> be large enough to process the largest individual field the HTTP implementation can be configured to accept.</t> <t>If an implementation encounters a value larger than it is able to decode, thisMUST<bcp14>MUST</bcp14> be treated as a stream error of type QPACK_DECOMPRESSION_FAILED if on a requeststream,stream or a connection error of the appropriate type if on the encoder or decoder stream.</t> </section> </section> <sectionanchor="iana-considerations" numbered="true" toc="default">anchor="iana-considerations"> <name>IANA Considerations</name> <t>This document makes multiple registrations in the registries defined by <xref target="HTTP3"/>. The allocations created by this document are all assigned permanent status and list a change controller of the IETF and a contact of the HTTP working group (ietf-http-wg@w3.org).</t> <sectionanchor="settings-registration" numbered="true" toc="default">anchor="settings-registration"> <name>Settings Registration</name> <t>This document specifies two settings. The entries in the following table are registered in the "HTTP/3 Settings" registry established in <xreftarget="HTTP3" format="default"/>.</t> <table align="center">target="HTTP3"/>.</t> <table> <name>Additions to the HTTP/3 Settings Registry</name> <thead> <tr> <th align="left">Setting Name</th> <th align="center">Code</th> <th align="left">Specification</th> <th align="left">Default</th> </tr> </thead> <tbody> <tr> <td align="left">QPACK_MAX_TABLE_CAPACITY</td> <tdalign="center">0x1</td>align="center">0x01</td> <tdalign="left"> <xref target="configuration" format="default"/></td>align="left"><xref target="configuration"/></td> <td align="left">0</td> </tr> <tr> <td align="left">QPACK_BLOCKED_STREAMS</td> <tdalign="center">0x7</td>align="center">0x07</td> <tdalign="left"> <xref target="configuration" format="default"/></td>align="left"><xref target="configuration"/></td> <td align="left">0</td> </tr> </tbody> </table> <t>Forfomattingformatting reasons, the setting names here are abbreviated by removing the'SETTING_''SETTINGS_' prefix.</t> </section> <sectionanchor="stream-type-registration" numbered="true" toc="default">anchor="stream-type-registration"> <name>Stream Type Registration</name> <t>This document specifies two stream types. The entries in the following table are registered in the "HTTP/3 StreamType"Types" registry established in <xreftarget="HTTP3" format="default"/>.</t> <table align="center">target="HTTP3"/>.</t> <table> <name>Additions to the HTTP/3 Stream Types Registry</name> <thead> <tr> <th align="left">Stream Type</th> <th align="center">Code</th> <th align="left">Specification</th> <th align="left">Sender</th> </tr> </thead> <tbody> <tr> <td align="left">QPACK Encoder Stream</td> <td align="center">0x02</td> <tdalign="left"> <xref target="enc-dec-stream-def" format="default"/></td>align="left"><xref target="enc-dec-stream-def"/></td> <td align="left">Both</td> </tr> <tr> <td align="left">QPACK Decoder Stream</td> <td align="center">0x03</td> <tdalign="left"> <xref target="enc-dec-stream-def" format="default"/></td>align="left"><xref target="enc-dec-stream-def"/></td> <td align="left">Both</td> </tr> </tbody> </table> </section> <sectionanchor="error-code-registration" numbered="true" toc="default">anchor="error-code-registration"> <name>Error Code Registration</name> <t>This document specifies three error codes. The entries in the following table are registered in the "HTTP/3 ErrorCode"Codes" registry established in <xreftarget="HTTP3" format="default"/>.</t> <table align="center">target="HTTP3"/>.</t> <table> <name>Additions to the HTTP/3 Error Codes Registry</name> <thead> <tr> <th align="left">Name</th> <th align="left">Code</th> <th align="left">Description</th> <th align="left">Specification</th> </tr> </thead> <tbody> <tr> <td align="left">QPACK_DECOMPRESSION_FAILED</td> <tdalign="left">0x200</td>align="left">0x0200</td> <td align="left">Decoding of a field section failed</td> <tdalign="left"> <xref target="error-handling" format="default"/></td>align="left"><xref target="error-handling"/></td> </tr> <tr> <td align="left">QPACK_ENCODER_STREAM_ERROR</td> <tdalign="left">0x201</td>align="left">0x0201</td> <td align="left">Error on the encoder stream</td> <tdalign="left"> <xref target="error-handling" format="default"/></td>align="left"><xref target="error-handling"/></td> </tr> <tr> <td align="left">QPACK_DECODER_STREAM_ERROR</td> <tdalign="left">0x202</td>align="left">0x0202</td> <td align="left">Error on the decoder stream</td> <tdalign="left"> <xref target="error-handling" format="default"/></td>align="left"><xref target="error-handling"/></td> </tr> </tbody> </table> </section> </section> </middle> <back> <displayreference target="HTTP2" to="HTTP/2"/> <displayreference target="HTTP3" to="HTTP/3"/> <references> <name>References</name> <references> <name>Normative References</name> <referenceanchor="HTTP3">anchor="HTTP3" target="https://www.rfc-editor.org/info/rfc9114"> <front><title>Hypertext Transfer Protocol Version 3 (HTTP/3)</title><title>HTTP/3</title> <author initials="M." surname="Bishop" fullname="Mike Bishop" role="editor"> <organization>Akamai Technologies</organization> </author> <dateyear="2021" month="February" day="02"/>year="2022" month="June"/> </front> <seriesInfoname="Internet-Draft" value="draft-ietf-quic-http-34"/> </reference> <reference anchor="QUIC-TRANSPORT"> <front> <title>QUIC: A UDP-Based Multiplexed and Secure Transport</title> <author initials="J." surname="Iyengar" fullname="Jana Iyengar" role="editor"> <organization>Fastly</organization> </author> <author initials="M." surname="Thomson" fullname="Martin Thomson" role="editor"> <organization>Mozilla</organization> </author> <date year="2021" month="February" day="02"/> </front>name="RFC" value="9114"/> <seriesInfoname="Internet-Draft" value="draft-ietf-quic-transport-34"/>name="DOI" value="10.17487/RFC9114"/> </reference> <referenceanchor="SEMANTICS" target="http://www.ietf.org/internet-drafts/draft-ietf-httpbis-semantics-14.txt">anchor="HTTP" target="https://www.rfc-editor.org/info/rfc9110"> <front> <title>HTTP Semantics</title> <author fullname="Roy T. Fielding" initials="R" surname="Fielding"fullname="Roy Fielding"> <organization/>role="editor"> <organization>Adobe</organization> </author> <author fullname="Mark Nottingham" initials="M" surname="Nottingham"fullname="Mark Nottingham"> <organization/>role="editor"> <organization>Fastly</organization> </author> <author fullname="Julian Reschke" initials="J" surname="Reschke"fullname="Julian Reschke"> <organization/>role="editor"> <organization>greenbytes GmbH</organization> </author> <datemonth="January" day="12" year="2021"/>month="June" year="2022"/> <abstract> <t>The Hypertext Transfer Protocol (HTTP) is a stateless application- level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes. This documentobsoletesupdates RFC 3864 and obsoletes RFCs 2818,RFC7231,RFC7232,RFC7233,RFC7235,RFC7538,RFC7615,RFC7694, and portions ofRFC7230.</t> </abstract> </front> <seriesInfoname="Internet-Draft" value="draft-ietf-httpbis-semantics-14"/>name="STD" value="97"/> <seriesInfo name="RFC" value="9110"/> <seriesInfo name="DOI" value="10.17487/RFC9110"/> </reference> <reference anchor="RFC2360" target="https://www.rfc-editor.org/info/rfc2360"> <front> <title>Guide for Internet Standards Writers</title> <authorinitials="G." surname="Scott"fullname="G.Scott">Scott" initials="G." surname="Scott"> <organization/> </author> <dateyear="1998" month="June"/>month="June" year="1998"/> <abstract> <t>This document is a guide for Internet standard writers. It defines those characteristics that make standards coherent, unambiguous, and easy to interpret. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t> </abstract> </front> <seriesInfo name="BCP" value="22"/> <seriesInfo name="RFC" value="2360"/> <seriesInfo name="DOI" value="10.17487/RFC2360"/> </reference> <reference anchor="QUIC-TRANSPORT" target="https://www.rfc-editor.org/info/rfc9000"> <front> <title>QUIC: A UDP-Based Multiplexed and Secure Transport</title> <author fullname="J. Iyengar" initials="J." role="editor" surname="Iyengar"> <organization/> </author> <author fullname="M. Thomson" initials="M." role="editor" surname="Thomson"> <organization/> </author> <date month="May" year="2021"/> <abstract> <t>This document defines the core of the QUIC transport protocol. QUIC provides applications with flow-controlled streams for structured communication, low-latency connection establishment, and network path migration. QUIC includes security measures that ensure confidentiality, integrity, and availability in a range of deployment circumstances. Accompanying documents describe the integration of TLS for key negotiation, loss detection, and an exemplary congestion control algorithm.</t> </abstract> </front> <seriesInfo name="RFC" value="9000"/> <seriesInfo name="DOI" value="10.17487/RFC9000"/> </reference> <reference anchor="RFC7541" target="https://www.rfc-editor.org/info/rfc7541"> <front> <title>HPACK: Header Compression for HTTP/2</title> <authorinitials="R." surname="Peon"fullname="R.Peon">Peon" initials="R." surname="Peon"> <organization/> </author> <authorinitials="H." surname="Ruellan"fullname="H.Ruellan">Ruellan" initials="H." surname="Ruellan"> <organization/> </author> <dateyear="2015" month="May"/>month="May" year="2015"/> <abstract> <t>This specification defines HPACK, a compression format for efficiently representing HTTP header fields, to be used in HTTP/2.</t> </abstract> </front> <seriesInfo name="RFC" value="7541"/> <seriesInfo name="DOI" value="10.17487/RFC7541"/> </reference> <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119"> <front> <title>Key words for use in RFCs to Indicate Requirement Levels</title> <authorinitials="S." surname="Bradner"fullname="S.Bradner">Bradner" initials="S." surname="Bradner"> <organization/> </author> <dateyear="1997" month="March"/>month="March" year="1997"/> <abstract> <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t> </abstract> </front> <seriesInfo name="BCP" value="14"/> <seriesInfo name="RFC" value="2119"/> <seriesInfo name="DOI" value="10.17487/RFC2119"/> </reference> <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174"> <front> <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title> <authorinitials="B." surname="Leiba"fullname="B.Leiba">Leiba" initials="B." surname="Leiba"> <organization/> </author> <dateyear="2017" month="May"/>month="May" year="2017"/> <abstract> <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t> </abstract> </front> <seriesInfo name="BCP" value="14"/> <seriesInfo name="RFC" value="8174"/> <seriesInfo name="DOI" value="10.17487/RFC8174"/> </reference> </references> <references> <name>Informative References</name> <reference anchor="CRIME" target="http://en.wikipedia.org/w/index.php?title=CRIME&oldid=660948120"> <front> <title>CRIME</title> <author> <organization>Wikipedia</organization> </author> <date year="2015" month="May"/> </front> </reference> <reference anchor="PETAL" target="http://www.pdl.cmu.edu/PDL-FTP/associated/CMU-PDL-13-106.pdf"> <front> <title>PETAL: Preset Encoding Table Information Leakage</title> <author initials="J." surname="Tan" fullname="Jiaqi Tan"> <organization/> </author> <author initials="J." surname="Nahata" fullname="Jayvardhan Nahata"> <organization/> </author> <date year="2013" month="April"/> </front> </reference> <referenceanchor="RFC7540" target="https://www.rfc-editor.org/info/rfc7540">anchor="HTTP2" target="https://www.rfc-editor.org/info/rfc9113"> <front><title>Hypertext Transfer Protocol Version 2 (HTTP/2)</title> <author initials="M." surname="Belshe" fullname="M. Belshe"> <organization/> </author> <author initials="R." surname="Peon" fullname="R. Peon"> <organization/> </author><title>HTTP/2</title> <author initials="M." surname="Thomson"fullname="M.fullname="Martin Thomson"role="editor"> <organization/> </author>role="editor"/> <author initials="C." surname="Benfield" fullname="Cory Benfield" role="editor"/> <dateyear="2015" month="May"/> <abstract> <t>This specification describes an optimized expression of the semantics of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTTP/2). HTTP/2 enables a more efficient use of network resources and a reduced perception of latency by introducing header field compression and allowing multiple concurrent exchanges on the same connection. It also introduces unsolicited push of representations from servers to clients.</t> <t>This specification is an alternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's existing semantics remain unchanged.</t> </abstract>year="2022" month="June"/> </front> <seriesInfo name="RFC"value="7540"/>value="9113"/> <seriesInfo name="DOI"value="10.17487/RFC7540"/>value="10.17487/RFC9113"/> </reference> <reference anchor="TLS" target="https://www.rfc-editor.org/info/rfc8446"> <front> <title>The Transport Layer Security (TLS) Protocol Version 1.3</title> <authorinitials="E." surname="Rescorla"fullname="E.Rescorla">Rescorla" initials="E." surname="Rescorla"> <organization/> </author> <dateyear="2018" month="August"/>month="August" year="2018"/> <abstract> <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t> <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.</t> </abstract> </front> <seriesInfo name="RFC" value="8446"/> <seriesInfo name="DOI" value="10.17487/RFC8446"/> </reference> <reference anchor="RFC1951" target="https://www.rfc-editor.org/info/rfc1951"> <front> <title>DEFLATE Compressed Data Format Specification version 1.3</title> <authorinitials="P." surname="Deutsch"fullname="P.Deutsch">Deutsch" initials="P." surname="Deutsch"> <organization/> </author> <dateyear="1996" month="May"/>month="May" year="1996"/> <abstract> <t>This specification defines a lossless compressed data format that compresses data using a combination of the LZ77 algorithm and Huffman coding, with efficiency comparable to the best currently available general-purpose compression methods. This memo provides information for the Internet community. This memo does not specify an Internet standard of any kind.</t> </abstract> </front> <seriesInfo name="RFC" value="1951"/> <seriesInfo name="DOI" value="10.17487/RFC1951"/> </reference> <reference anchor="RFC6454" target="https://www.rfc-editor.org/info/rfc6454"> <front> <title>The Web Origin Concept</title> <authorinitials="A." surname="Barth"fullname="A.Barth">Barth" initials="A." surname="Barth"> <organization/> </author> <dateyear="2011" month="December"/>month="December" year="2011"/> <abstract> <t>This document defines the concept of an "origin", which is often used as the scope of authority or privilege by user agents. Typically, user agents isolate content retrieved from different origins to prevent malicious web site operators from interfering with the operation of benign web sites. In addition to outlining the principles that underlie the concept of origin, this document details how to determine the origin of a URI and how to serialize an origin into a string. It also defines an HTTP header field, named "Origin", that indicates which origins are associated with an HTTP request. [STANDARDS-TRACK]</t> </abstract> </front> <seriesInfo name="RFC" value="6454"/> <seriesInfo name="DOI" value="10.17487/RFC6454"/> </reference> </references> </references> <sectionanchor="static-table" numbered="true" toc="default">anchor="static-table"> <name>Static Table</name> <t>This table was generated by analyzing actual Internet traffic in 2018 and including the most common header fields, after filtering out some unsupported and non-standard values. Due to this methodology, some of the entries may be inconsistent or appear multiple times with similar but not identical values. The order of the entries is optimized to encode the most common header fields with the smallest number of bytes.</t><table align="center"><table> <name>Static Table</name> <thead> <tr> <th align="left">Index</th> <th align="left">Name</th> <th align="left">Value</th> </tr> </thead> <tbody> <tr> <td align="left">0</td> <td align="left">:authority</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">1</td> <td align="left">:path</td> <td align="left">/</td> </tr> <tr> <td align="left">2</td> <td align="left">age</td> <td align="left">0</td> </tr> <tr> <td align="left">3</td> <td align="left">content-disposition</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">4</td> <td align="left">content-length</td> <td align="left">0</td> </tr> <tr> <td align="left">5</td> <td align="left">cookie</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">6</td> <td align="left">date</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">7</td> <td align="left">etag</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">8</td> <td align="left">if-modified-since</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">9</td> <td align="left">if-none-match</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">10</td> <td align="left">last-modified</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">11</td> <td align="left">link</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">12</td> <td align="left">location</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">13</td> <td align="left">referer</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">14</td> <td align="left">set-cookie</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">15</td> <td align="left">:method</td> <td align="left">CONNECT</td> </tr> <tr> <td align="left">16</td> <td align="left">:method</td> <td align="left">DELETE</td> </tr> <tr> <td align="left">17</td> <td align="left">:method</td> <td align="left">GET</td> </tr> <tr> <td align="left">18</td> <td align="left">:method</td> <td align="left">HEAD</td> </tr> <tr> <td align="left">19</td> <td align="left">:method</td> <td align="left">OPTIONS</td> </tr> <tr> <td align="left">20</td> <td align="left">:method</td> <td align="left">POST</td> </tr> <tr> <td align="left">21</td> <td align="left">:method</td> <td align="left">PUT</td> </tr> <tr> <td align="left">22</td> <td align="left">:scheme</td> <td align="left">http</td> </tr> <tr> <td align="left">23</td> <td align="left">:scheme</td> <td align="left">https</td> </tr> <tr> <td align="left">24</td> <td align="left">:status</td> <td align="left">103</td> </tr> <tr> <td align="left">25</td> <td align="left">:status</td> <td align="left">200</td> </tr> <tr> <td align="left">26</td> <td align="left">:status</td> <td align="left">304</td> </tr> <tr> <td align="left">27</td> <td align="left">:status</td> <td align="left">404</td> </tr> <tr> <td align="left">28</td> <td align="left">:status</td> <td align="left">503</td> </tr> <tr> <td align="left">29</td> <td align="left">accept</td> <td align="left">*/*</td> </tr> <tr> <td align="left">30</td> <td align="left">accept</td> <td align="left">application/dns-message</td> </tr> <tr> <td align="left">31</td> <td align="left">accept-encoding</td> <td align="left">gzip, deflate, br</td> </tr> <tr> <td align="left">32</td> <td align="left">accept-ranges</td> <td align="left">bytes</td> </tr> <tr> <td align="left">33</td> <td align="left">access-control-allow-headers</td> <td align="left">cache-control</td> </tr> <tr> <td align="left">34</td> <td align="left">access-control-allow-headers</td> <td align="left">content-type</td> </tr> <tr> <td align="left">35</td> <td align="left">access-control-allow-origin</td> <td align="left">*</td> </tr> <tr> <td align="left">36</td> <td align="left">cache-control</td> <td align="left">max-age=0</td> </tr> <tr> <td align="left">37</td> <td align="left">cache-control</td> <td align="left">max-age=2592000</td> </tr> <tr> <td align="left">38</td> <td align="left">cache-control</td> <td align="left">max-age=604800</td> </tr> <tr> <td align="left">39</td> <td align="left">cache-control</td> <td align="left">no-cache</td> </tr> <tr> <td align="left">40</td> <td align="left">cache-control</td> <td align="left">no-store</td> </tr> <tr> <td align="left">41</td> <td align="left">cache-control</td> <td align="left">public, max-age=31536000</td> </tr> <tr> <td align="left">42</td> <td align="left">content-encoding</td> <td align="left">br</td> </tr> <tr> <td align="left">43</td> <td align="left">content-encoding</td> <td align="left">gzip</td> </tr> <tr> <td align="left">44</td> <td align="left">content-type</td> <td align="left">application/dns-message</td> </tr> <tr> <td align="left">45</td> <td align="left">content-type</td> <td align="left">application/javascript</td> </tr> <tr> <td align="left">46</td> <td align="left">content-type</td> <td align="left">application/json</td> </tr> <tr> <td align="left">47</td> <td align="left">content-type</td> <td align="left">application/x-www-form-urlencoded</td> </tr> <tr> <td align="left">48</td> <td align="left">content-type</td> <td align="left">image/gif</td> </tr> <tr> <td align="left">49</td> <td align="left">content-type</td> <td align="left">image/jpeg</td> </tr> <tr> <td align="left">50</td> <td align="left">content-type</td> <td align="left">image/png</td> </tr> <tr> <td align="left">51</td> <td align="left">content-type</td> <td align="left">text/css</td> </tr> <tr> <td align="left">52</td> <td align="left">content-type</td> <td align="left">text/html; charset=utf-8</td> </tr> <tr> <td align="left">53</td> <td align="left">content-type</td> <td align="left">text/plain</td> </tr> <tr> <td align="left">54</td> <td align="left">content-type</td> <td align="left">text/plain;charset=utf-8</td> </tr> <tr> <td align="left">55</td> <td align="left">range</td> <td align="left">bytes=0-</td> </tr> <tr> <td align="left">56</td> <td align="left">strict-transport-security</td> <td align="left">max-age=31536000</td> </tr> <tr> <td align="left">57</td> <td align="left">strict-transport-security</td> <td align="left">max-age=31536000; includesubdomains</td> </tr> <tr> <td align="left">58</td> <td align="left">strict-transport-security</td> <td align="left">max-age=31536000; includesubdomains; preload</td> </tr> <tr> <td align="left">59</td> <td align="left">vary</td> <td align="left">accept-encoding</td> </tr> <tr> <td align="left">60</td> <td align="left">vary</td> <td align="left">origin</td> </tr> <tr> <td align="left">61</td> <td align="left">x-content-type-options</td> <td align="left">nosniff</td> </tr> <tr> <td align="left">62</td> <td align="left">x-xss-protection</td> <td align="left">1; mode=block</td> </tr> <tr> <td align="left">63</td> <td align="left">:status</td> <td align="left">100</td> </tr> <tr> <td align="left">64</td> <td align="left">:status</td> <td align="left">204</td> </tr> <tr> <td align="left">65</td> <td align="left">:status</td> <td align="left">206</td> </tr> <tr> <td align="left">66</td> <td align="left">:status</td> <td align="left">302</td> </tr> <tr> <td align="left">67</td> <td align="left">:status</td> <td align="left">400</td> </tr> <tr> <td align="left">68</td> <td align="left">:status</td> <td align="left">403</td> </tr> <tr> <td align="left">69</td> <td align="left">:status</td> <td align="left">421</td> </tr> <tr> <td align="left">70</td> <td align="left">:status</td> <td align="left">425</td> </tr> <tr> <td align="left">71</td> <td align="left">:status</td> <td align="left">500</td> </tr> <tr> <td align="left">72</td> <td align="left">accept-language</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">73</td> <td align="left">access-control-allow-credentials</td> <td align="left">FALSE</td> </tr> <tr> <td align="left">74</td> <td align="left">access-control-allow-credentials</td> <td align="left">TRUE</td> </tr> <tr> <td align="left">75</td> <td align="left">access-control-allow-headers</td> <td align="left">*</td> </tr> <tr> <td align="left">76</td> <td align="left">access-control-allow-methods</td> <td align="left">get</td> </tr> <tr> <td align="left">77</td> <td align="left">access-control-allow-methods</td> <td align="left">get, post, options</td> </tr> <tr> <td align="left">78</td> <td align="left">access-control-allow-methods</td> <td align="left">options</td> </tr> <tr> <td align="left">79</td> <td align="left">access-control-expose-headers</td> <td align="left">content-length</td> </tr> <tr> <td align="left">80</td> <td align="left">access-control-request-headers</td> <td align="left">content-type</td> </tr> <tr> <td align="left">81</td> <td align="left">access-control-request-method</td> <td align="left">get</td> </tr> <tr> <td align="left">82</td> <td align="left">access-control-request-method</td> <td align="left">post</td> </tr> <tr> <td align="left">83</td> <td align="left">alt-svc</td> <td align="left">clear</td> </tr> <tr> <td align="left">84</td> <td align="left">authorization</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">85</td> <td align="left">content-security-policy</td> <td align="left">script-src 'none'; object-src 'none'; base-uri 'none'</td> </tr> <tr> <td align="left">86</td> <td align="left">early-data</td> <td align="left">1</td> </tr> <tr> <td align="left">87</td> <td align="left">expect-ct</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">88</td> <td align="left">forwarded</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">89</td> <td align="left">if-range</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">90</td> <td align="left">origin</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">91</td> <td align="left">purpose</td> <td align="left">prefetch</td> </tr> <tr> <td align="left">92</td> <td align="left">server</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">93</td> <td align="left">timing-allow-origin</td> <td align="left">*</td> </tr> <tr> <td align="left">94</td> <td align="left">upgrade-insecure-requests</td> <td align="left">1</td> </tr> <tr> <td align="left">95</td> <td align="left">user-agent</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">96</td> <td align="left">x-forwarded-for</td> <tdalign="left"> </td>align="left"/> </tr> <tr> <td align="left">97</td> <td align="left">x-frame-options</td> <td align="left">deny</td> </tr> <tr> <td align="left">98</td> <td align="left">x-frame-options</td> <td align="left">sameorigin</td> </tr> </tbody> </table> <t>Any line breaks that appear within field names or values are due to formatting.</t> </section> <sectionanchor="encoding-and-decoding-examples" numbered="true" toc="default">anchor="encoding-and-decoding-examples"> <name>Encoding and Decoding Examples</name> <t>The following examples represent a series of exchanges between an encoder and a decoder. The exchanges are designed to exercise most QPACKinstructions,instructions and highlight potentially common patterns and their impact on dynamic table state. The encoder sends three encoded field sections containing one field line each, as well as two speculative inserts that are not referenced.</t> <t>The state of the encoder's dynamic table is shown, along with its current size. Each entry is shown with the Absolute Index of the entry (Abs), the current number of outstanding encoded field sections with references to that entry (Ref), along with the name and value. Entries above the 'acknowledged' line have been acknowledged by the decoder.</t> <sectionanchor="literal-field-line-with-name-reference" numbered="true" toc="default">anchor="literal-field-line-with-name-reference"> <name>Literal Field LineWithwith Name Reference</name> <t>The encoder sends an encoded field section containing a literal representation of a field with a static name reference.</t><artwork name="" type="" align="left" alt=""><![CDATA[<artwork><![CDATA[ Data | Interpretation | Encoder's Dynamic Table Stream: 0 0000 | Required Insert Count = 0, Base = 0 510b 2f69 6e64 6578 | Literal Field Line with Name Reference 2e68 746d 6c | Static Table, Index=1 | (:path=/index.html) Abs Ref Name Value ^-- acknowledged --^ Size=0 ]]></artwork> </section> <sectionanchor="dynamic-table" numbered="true" toc="default">anchor="dynamic-table"> <name>Dynamic Table</name> <t>The encoder sets the dynamic table capacity, inserts a header with a dynamic name reference, then sends a potentially blocking, encoded field section referencing this new entry. The decoder acknowledges processing the encoded field section, which implicitly acknowledges all dynamic table insertions up to the Required Insert Count.</t><artwork name="" type="" align="left" alt=""><![CDATA[<artwork><![CDATA[ Stream: Encoder 3fbd01 | Set Dynamic Table Capacity=220 c00f 7777 772e 6578 | Insert With Name Reference 616d 706c 652e 636f | Static Table, Index=0 6d | (:authority=www.example.com) c10c 2f73 616d 706c | Insert With Name Reference 652f 7061 7468 | Static Table, Index=1 | (:path=/sample/path) Abs Ref Name Value ^-- acknowledged --^ 0 0 :authority www.example.com 1 0 :path /sample/path Size=106 Stream: 4 0381 | Required Insert Count = 2, Base = 0 10 | Indexed Field Line With Post-Base Index | Absolute Index = Base(0) + Index(0) = 0 | (:authority=www.example.com) 11 | Indexed Field Line With Post-Base Index | Absolute Index = Base(0) + Index(1) = 1 | (:path=/sample/path) Abs Ref Name Value ^-- acknowledged --^ 0 1 :authority www.example.com 1 1 :path /sample/path Size=106 Stream: Decoder 84 | Section Acknowledgment (stream=4) Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path ^-- acknowledged --^ Size=106 ]]></artwork> </section> <sectionanchor="speculative-insert" numbered="true" toc="default">anchor="speculative-insert"> <name>Speculative Insert</name> <t>The encoder inserts a header into the dynamic table with a literal name. The decoder acknowledges receipt of the entry. The encoder does not send any encoded field sections.</t><artwork name="" type="" align="left" alt=""><![CDATA[<artwork><![CDATA[ Stream: Encoder 4a63 7573 746f 6d2d | Insert With Literal Name 6b65 790c 6375 7374 | (custom-key=custom-value) 6f6d 2d76 616c 7565 | Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path ^-- acknowledged --^ 2 0 custom-key custom-value Size=160 Stream: Decoder 01 | Insert Count Increment (1) Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path 2 0 custom-key custom-value ^-- acknowledged --^ Size=160 ]]></artwork> </section> <sectionanchor="duplicate-instruction-stream-cancellation" numbered="true" toc="default">anchor="duplicate-instruction-stream-cancellation"> <name>Duplicate Instruction, Stream Cancellation</name> <t>The encoder duplicates an existing entry in the dynamic table, then sends an encoded field section referencing the dynamic table entries including the duplicated entry. The packet containing the encoder stream data is delayed. Before the packet arrives, the decoder cancels the stream and notifies the encoder that the encoded field section was not processed.</t><artwork name="" type="" align="left" alt=""><![CDATA[<artwork><![CDATA[ Stream: Encoder 02 | Duplicate (Relative Index = 2) | Absolute Index = | InsertCount(4)Count(3) - Index(2) - 1 =10 Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path 2 0 custom-key custom-value ^-- acknowledged --^ 3 0 :authority www.example.com Size=217 Stream: 8 0500 | Required Insert Count = 4, Base = 4 80 | Indexed Field Line, Dynamic Table | Absolute Index = Base(4) - Index(0) - 1 = 3 | (:authority=www.example.com) c1 | Indexed Field Line, Static Table Index = 1 | (:path=/) 81 | Indexed Field Line, Dynamic Table | Absolute Index = Base(4) - Index(1) - 1 = 2 | (custom-key=custom-value) Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path 2 1 custom-key custom-value ^-- acknowledged --^ 3 1 :authority www.example.com Size=217 Stream: Decoder 48 | Stream Cancellation (Stream=8) Abs Ref Name Value 0 0 :authority www.example.com 1 0 :path /sample/path 2 0 custom-key custom-value ^-- acknowledged --^43 0 :authority www.example.com Size=217 ]]></artwork> </section> <sectionanchor="dynamic-table-insert-eviction" numbered="true" toc="default">anchor="dynamic-table-insert-eviction"> <name>Dynamic Table Insert, Eviction</name> <t>The encoder inserts another header into the dynamic table, which evicts the oldest entry. The encoder does not send any encoded field sections.</t><artwork name="" type="" align="left" alt=""><![CDATA[<artwork><![CDATA[ Stream: Encoder 810d 6375 7374 6f6d | Insert With Name Reference 2d76 616c 7565 32 | Dynamic Table, Relative Index = 1 | Absolute Index = | Insert Count(4) - Index(1) - 1 = 2 | (custom-key=custom-value2) Abs Ref Name Value 1 0 :path /sample/path 2 0 custom-key custom-value ^-- acknowledged --^ 3 0 :authority www.example.com 4 0 custom-key custom-value2 Size=215 ]]></artwork> </section> </section> <sectionanchor="sample-one-pass-encoding-algorithm" numbered="true" toc="default">anchor="sample-single-pass-encoding-algorithm"> <name>SampleOne PassSingle-Pass Encoding Algorithm</name><t>Pseudo-code<t>Pseudocode forsingle passsingle-pass encoding, excluding handling of duplicates, non-blocking mode, available encoder stream flow control and reference tracking.</t><artwork name="" type="" align="left" alt=""><![CDATA[<sourcecode type="pseudocode"><![CDATA[ # Helper functions: # ==== # Encode anintergerinteger with the specified prefix and length encodeInteger(buffer, prefix, value, prefixLength) # Encode a dynamic table insert instruction with optional static # or dynamic name index (but not both) encodeInsert(buffer, staticNameIndex, dynamicNameIndex, fieldLine) # Encode a static index reference encodeStaticIndexReference(buffer, staticIndex) # Encode a dynamic index reference relative tobaseBase encodeDynamicIndexReference(buffer, dynamicIndex, base) # Encode a literal with an optional static name index encodeLiteral(buffer, staticNameIndex, fieldLine) # Encode a literal with a dynamic name index relative tobaseBase encodeDynamicLiteral(buffer, dynamicNameIndex, base, fieldLine) # Encoding Algorithm # ==== base = dynamicTable.getInsertCount() requiredInsertCount = 0 for line in fieldLines: staticIndex = staticTable.findIndex(line) if staticIndex is not None: encodeStaticIndexReference(streamBuffer, staticIndex) continue dynamicIndex = dynamicTable.findIndex(line) if dynamicIndex is None: # No matching entry. Either insert+index or encode literal staticNameIndex = staticTable.findName(line.name) if staticNameIndex is None: dynamicNameIndex = dynamicTable.findName(line.name) if shouldIndex(line) and dynamicTable.canIndex(line): encodeInsert(encoderBuffer, staticNameIndex, dynamicNameIndex, line) dynamicIndex = dynamicTable.add(line) if dynamicIndex is None: # Could not index it, literal if dynamicNameIndex is not None: # Encode literal with dynamic name, possibly abovebaseBase encodeDynamicLiteral(streamBuffer, dynamicNameIndex, base, line) requiredInsertCount = max(requiredInsertCount, dynamicNameIndex) else: # Encodes a literal with a static name or literal name encodeLiteral(streamBuffer, staticNameIndex, line) else: # Dynamic index reference assert(dynamicIndex is not None) requiredInsertCount = max(requiredInsertCount, dynamicIndex) # Encode dynamicIndex, possibly abovebaseBase encodeDynamicIndexReference(streamBuffer, dynamicIndex, base) # encode the prefix if requiredInsertCount == 0: encodeInteger(prefixBuffer, 0x00, 0, 8) encodeInteger(prefixBuffer, 0x00, 0, 7) else: wireRIC = ( requiredInsertCount % (2 * getMaxEntries(maxTableCapacity)) ) + 1; encodeInteger(prefixBuffer, 0x00, wireRIC, 8) if base >= requiredInsertCount: encodeInteger(prefixBuffer, 0x00, base - requiredInsertCount, 7) else: encodeInteger(prefixBuffer, 0x80, requiredInsertCount - base - 1, 7) return encoderBuffer, prefixBuffer + streamBuffer]]></artwork> </section> <section anchor="change-log" numbered="true" toc="default"> <name>Change Log</name> <ul empty="true" spacing="normal"> <li> <strong>RFC Editor's Note:</strong> Please remove this section prior to publication of a final version of this document.</li> </ul> <section anchor="since-draft-ietf-quic-qpack-19" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-19</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-18" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-18</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-17" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-17</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-16" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-16</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-15" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-15</name> <t>No changes</t> </section> <section anchor="since-draft-ietf-quic-qpack-14" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-14</name> <t>Added security considerations</t> </section> <section anchor="since-draft-ietf-quic-qpack-13" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-13</name> <t>No changes</t> </section> <section anchor="since-draft-ietf-quic-qpack-12" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-12</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-11" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-11</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-10" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-10</name> <t>Editorial changes only</t> </section> <section anchor="since-draft-ietf-quic-qpack-09" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-09</name> <ul spacing="normal"> <li>Decoders MUST emit Header Acknowledgments (#2939)</li> <li>Updated error code for multiple encoder or decoder streams (#2970)</li> <li>Added explicit defaults for new SETTINGS (#2974)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-08" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-08</name> <ul spacing="normal"> <li>Endpoints are permitted to create encoder and decoder streams even if they can't use them (#2100, #2529)</li> <li>Maximum values for settings removed (#2766, #2767)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-06" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-06</name> <ul spacing="normal"> <li>Clarify initial dynamic table capacity maximums (#2276, #2330, #2330)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-05" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-05</name> <ul spacing="normal"> <li>Introduced the terms dynamic table capacity and maximum dynamic table capacity.</li> <li>Renamed SETTINGS_HEADER_TABLE_SIZE to SETTINGS_QPACK_MAX_TABLE_CAPACITY.</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-04" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-04</name> <ul spacing="normal"> <li>Changed calculation of Delta Base Index to avoid an illegal value (#2002, #2005)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-03" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-03</name> <ul spacing="normal"> <li>Change HTTP settings defaults (#2038)</li> <li>Substantial editorial reorganization</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-02" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-02</name> <ul spacing="normal"> <li>Largest Reference encoded modulo MaxEntries (#1763)</li> <li>New Static Table (#1355)</li> <li>Table Size Update with Insert Count=0 is a connection error (#1762)</li> <li>Stream Cancellations are optional when SETTINGS_HEADER_TABLE_SIZE=0 (#1761)</li> <li>Implementations must handle 62 bit integers (#1760)</li> <li>Different error types for each QPACK stream, other changes to error handling (#1726)</li> <li>Preserve header field order (#1725)</li> <li>Initial table size is the maximum permitted when table is first usable (#1642)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-01" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-01</name> <ul spacing="normal"> <li>Only header blocks that reference the dynamic table are acknowledged (#1603, #1605)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qpack-00" numbered="true" toc="default"> <name>Since draft-ietf-quic-qpack-00</name> <ul spacing="normal"> <li>Renumbered instructions for consistency (#1471, #1472)</li> <li>Decoder is allowed to validate largest reference (#1404, #1469)</li> <li>Header block acknowledgments also acknowledge the associated largest reference (#1370, #1400)</li> <li>Added an acknowledgment for unread streams (#1371, #1400)</li> <li>Removed framing from encoder stream (#1361,#1467)</li> <li>Control streams use typed unidirectional streams rather than fixed stream IDs (#910,#1359)</li> </ul> </section> <section anchor="since-draft-ietf-quic-qcram-00" numbered="true" toc="default"> <name>Since draft-ietf-quic-qcram-00</name> <ul spacing="normal"> <li>Separate instruction sets for table updates and header blocks (#1235, #1142, #1141)</li> <li>Reworked indexing scheme (#1176, #1145, #1136, #1130, #1125, #1314)</li> <li>Added mechanisms that support one-pass encoding (#1138, #1320)</li> <li>Added a setting to control the number of blocked decoders (#238, #1140, #1143)</li> <li>Moved table updates and acknowledgments to dedicated streams (#1121, #1122, #1238)</li> </ul> </section>]]></sourcecode> </section> <section numbered="false"anchor="acknowledgments" toc="default">anchor="acknowledgments"> <name>Acknowledgments</name> <t>The IETF QUIC Working Group received an enormous amount of support from many people.</t> <t>The compression design team did substantial work exploring the problem space and influencing the initialdraft.draft version of this document. The contributions of design team membersRoberto Peon, Martin Thomson,<contact fullname="Roberto Peon"/>, <contact fullname="Martin Thomson"/>, andDmitri Tikhonov<contact fullname="Dmitri Tikhonov"/> are gratefully acknowledged.</t> <t>The following people also provided substantial contributions to this document:</t> <ulspacing="normal"> <li>Bence Beky</li> <li>Alessandro Ghedini</li> <li>Ryan Hamilton</li> <li>Robin Marx</li> <li>Patrick McManus</li>spacing="compact"> <li><t> <contact<t><contact fullname="Bence Beky"/></t> </li> <li> <t><contact fullname="Alessandro Ghedini"/></t> </li> <li> <t><contact fullname="Ryan Hamilton"/></t> </li> <li> <t><contact fullname="Robin Marx"/></t> </li> <li> <t><contact fullname="Patrick McManus"/></t> </li> <li> <t><contact asciiFullname="Kazuho Oku" fullname="奥一穂"/> </t>一穂"/></t> </li> <li> <t><contact fullname="Lucas Pardue"/></t> </li> <li> <t><contact fullname="Biren Roy"/></t> </li> <li> <t><contact fullname="Ian Swett"/></t> </li><li>Lucas Pardue</li> <li>Biren Roy</li> <li>Ian Swett</li></ul> <t>Thisdraftdocument draws heavily on the text of <xreftarget="RFC7541" format="default"/>.target="RFC7541"/>. The indirect input of those authors is also gratefully acknowledged.</t><t>Buck's<t><contact fullname="Buck Krasic"/>'s contribution was supported by Google during his employment there.</t> <t>A portion ofMike's<contact fullname="Mike Bishop"/>'s contribution was supported by Microsoft during his employment there.</t> </section> </back><!-- ##markdown-source: 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 QZLh7GnexWVKqkGJbXVR3aVidV/O4yUnkfo5j4U2sbExejHNyG7+QKq6kqpb b0aHqq5SRG5GFIadatGwWtj3KVZYWszy1GuzxMWhxmh2Rn2FclcijfLGgi4X TFc5XwlXNsf7fJbzqisRKCluBCdCyBHP1edGHV40jKpQzxxVy5JeHrbLPadX YTR9advktWy7dSvwYiOmxeycLRCdC162dv3ExZyyURf1qKqKgfxhv/ecH0BP KRMvfU+qyagQmU3C4ljZxOSn1JGEttCPc8TEUBkkF3/2Nbd84sEGto23nQeG nk5ymkaPn6fKVpN4gfo4SMUS1m93CYt8FlJDmur8FPMaYjdFZU4H4DgkepZ7 fTdxPS9Qq+Ql9fgovYlG/rp1f2T9XEF3qs5vfIIhoauS8iTGlVe0wYbgUW23 XHtuneBGL2AW0bv4GutWKjH4JBgZbZy8O+5JNupv4fdXn9/sP9vZ2UVlROMU /v6no31vKPcuCxz4df/k896H408fP59gDwyj/eg5/AKGpbFoHG3wTXs9YWqF M1K7FjIp5llIyvgMTY76jL4Zc1gs4o69F7W364gEOygDSo9ZIH0vok+SEl6O zxNO2PCgKAxv5PgsRhIe4r0IlxQmg8TnNIXlUNiEJcazax4aZja2JTo4S2ji hZgq1qGLL4mLzET+OrxEY1EHucMHvTVorIXCha7y4kIKrM+uYThdgE8GTq/9 yuyeKQtmdJr6xNy7tRjXQDsgFG3/89H7Q1Rm6RfEnQmQY2R3XM/2XHL/te4n bVh0lmRcptXdCbd/UvCWI6rHsuFKb2XMaTyWoNKDwzfv9k4OsWfcbwGDR8+f jLhO1zzHoARHlyPhZ5kK0epuksIBnonbv61txAFr02EwFlJLZPMY5dljsq0J 71+A+jIO9CkGVFYh9AG12rigb2R9kga0t6AEPNoKqh7DrEnbNSmrwgLlZxwE Q2lLUt/K6zin8mAshwXEL5nx8umkjH9kpx6GCrEB0LQ/4j7CGumBVy6utDwy ecnh4qDdzO4LHOJeSJv5IhB6O0eDT0OJsKELC1ZCAURef0DatNMCzXY4UaWI oVVXzOGN62L4unimX2aJl6nuM+AlxsijfIMXSTGvZmWXLrpeEyHCFLSe5Asa RNreRntc9hHFF9s5m+Zynp5xkyJ8gTo4ULuVmbTjNDILFDyWYxRxsE7j9aDR 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 ta4SHt6gCPBXj6m62AC9Eptm9Y4gruMkguB7irK/4b1/6fdDtOr3/+WGV47h 6r0a0lEiztUOIEStqmwtk8plXnqWYsSacCDoo32EQ/yRsv3a6dmnjlq0qteO xbaEhy1Gg7n2dFeFaGuejLcXpV9dw0sZN8HQPSnOgtnSKawKCyb5YzSrqPCi iYosF9rqoBUv5cIoTgvSm+3p6WRYE5EoN7fWBmtf9vnV1tbQjIfDafQUfuB/ W4kitUBrIxK7I8Dhp0PA4t0n+ML27hShtODx0Oy2aBOExzZp4tXV1dVAOO0A eNmmGY+GY7hlT7cjB2n1hJ5sTfGxEV6vZxbInW5WSRN5jP/47+lqUVoC/PGT TWobd9MIIxnByyHxV7vO3R4Ndx0h3THD7WcNebybkG55hHTUYmKVPCF4sbs5 MD3RdYQ1rv6KwG0MN6Mf+RP8FYF3vL4SJ0ctisevP+ERTvivGmVH90bZ0XdE WclbNs9a3FlIJ1mw2bPrpFzhDc6QfLXzq23uf/PLfVdej5ur3P7Yk/f55ocs v8HRO2pcC6P3uz+zqtLKiKm55qIKRHjVtgSwLa+E4oHBSmHtknsHT92Jd7ej p0+AGwFzmUa7k61JjRsFLa13T3efRE+fAwfb3X4Kv20/3aG7Ol6WVT7vXyTX r+RXkvU3ze4UeNzW5OkucrsxQIL3v/5PTPN+thii20H7++UaS2ZE3R02qUBd UsKfryHXOsJ+eUwFRv9+r/89d/jO1AMPxSoLS46+I+Khdo+eVpjYx4qls5mt 5eDdbn2PNVVsPaitGtqbA4S6QmbaldtQLajTKFcdwksaN3Yqk4AOLbBecOWr yy0J/+RMwAoVySy+RovIa+49V7kB4qIA2ipVXLzCf7AxrEvJUJx7Xml5i8SW 3LMtMdqXjAn0Uqp9TM1NOwhiW9TEV+/8Nj4nlg2wWLO1ua4E1PVccCs3djaj vkhIW/jriKSk/3k7W3/uQnG377tkut9bo6eO6D4zw5bAim5tYcdqCzvm2Zra Qq9mcmibWafY7SHVUJFq+066wnhNXaEXaKh2NjfK+5umqXb9uhsy0g3Z6pxb p3zz7/pajv7i1/JeClXzWqostNMS+fu1jftGG/zhq2f/zo/2L0txd+67ZHu0 rdZXoa696PAyHTeFKKubSXOclRqa2jUTHIoljHw2wdovN2pf0a21r2ej4cTT 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 kPNIcMD8FxHV93TIzX2p4yO1KJtIGI+HNKOtES9TtmsLmQWoHDXJy/zyQu/Z qwdTQO7kwTf2tR0dnryJ/v4nUB7/CBuMa/pdkS8XHMF4yeibZHkxz7Fbs+tk K3tGaIl9Ts0iydHlwaP6XUU5oQyEAownAsZZeowMD5UEuLzQCKRFkcNmzKMS qEQiPTCmwF9d0JOVaBAPxa9Hp5CeLpl6oKPCgzpPcOll9DmHv6rcfEowhut9 XMAZwtv5vMR/U+4d0NYijU7Si/M8yy+JzJ0hPk+XszBRQrPDXFoebwBTDljE ZUqag7fYcI7abkNVtRd4fV4TqXr9f//Xi2vEthkWy8smRR797hxOP0vxJlzD ibwFojCrgOH3cVGwCljMF+QyMdZtuojej9/H2bKET/6m+g3+R2Fe4wpI2DhN 38BiULh69eD38Z+X53n08WL5IJraT//f//Jfov/n//zP/99//d8fPP7N3zyu 6A/KDctxXAKMYrJMcLJAUTKAj1M9gkkdX8Gt0JZGeDb4/yts5hVfpq7BJdb4 whP65Zf/AIrw0yc7I+0iSO0AkUrBL4slNXuuzjF1md1rJRN72N7uI3m9HF88 KoOtpggy2wMF09B+l+fo8JosCelwugkIC/k1EWekiAl1c8YXRAx8n14kNw77 Ph0XeZnjuu3Ipjny/w8eAmJzo1sBAA== --></rfc>