draft-ietf-httpbis-header-compression-09.txt | draft-ietf-httpbis-header-compression-latest.txt | |||
---|---|---|---|---|
HTTPbis Working Group R. Peon | HTTPbis Working Group R. Peon | |||
Internet-Draft Google, Inc | Internet-Draft Google, Inc | |||
Intended status: Standards Track H. Ruellan | Intended status: Standards Track H. Ruellan | |||
Expires: February 1, 2015 Canon CRF | Expires: January 7, 2025 Canon CRF | |||
July 31, 2014 | July 6, 2024 | |||
HPACK - Header Compression for HTTP/2 | HPACK: Header Compression for HTTP/2 | |||
draft-ietf-httpbis-header-compression-09 | draft-ietf-httpbis-header-compression-latest | |||
Abstract | Abstract | |||
This specification defines HPACK, a compression format for | This specification defines HPACK, a compression format for | |||
efficiently representing HTTP header fields in the context of HTTP/2. | efficiently representing HTTP header fields, to be used in HTTP/2. | |||
Editorial Note (To be removed by RFC Editor) | Editorial Note (To be removed by RFC Editor) | |||
Discussion of this draft takes place on the HTTPBIS working group | Discussion of this draft takes place on the HTTPBIS working group | |||
mailing list (ietf-http-wg@w3.org), which is archived at | mailing list (ietf-http-wg@w3.org), which is archived at | |||
<https://lists.w3.org/Archives/Public/ietf-http-wg/>. | <https://lists.w3.org/Archives/Public/ietf-http-wg/>. | |||
Working Group information can be found at | Working Group information can be found at <http://tools.ietf.org/wg/ | |||
<http://tools.ietf.org/wg/httpbis/>; that specific to HTTP/2 are at | httpbis/>; that specific to HTTP/2 are at <http://http2.github.io/>. | |||
<http://http2.github.io/>. | ||||
The changes in this draft are summarized in Appendix A.1. | ||||
Status of This Memo | Status of This Memo | |||
This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on February 1, 2015. | This Internet-Draft will expire on January 7, 2025. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2014 IETF Trust and the persons identified as the | Copyright (c) 2024 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(http://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
described in the Simplified BSD License. | described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
2. HPACK Overview . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
2.1. Outline . . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1.2. Conventions . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
2.2. Conventions . . . . . . . . . . . . . . . . . . . . . . . 5 | 1.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 | |||
2.3. Terminology . . . . . . . . . . . . . . . . . . . . . . . 5 | 2. Compression Process Overview . . . . . . . . . . . . . . . . 5 | |||
3. Compression Process Overview . . . . . . . . . . . . . . . . . 5 | 2.1. Header List Ordering . . . . . . . . . . . . . . . . . . 5 | |||
3.1. Header List Ordering . . . . . . . . . . . . . . . . . . . 6 | 2.2. Encoding and Decoding Contexts . . . . . . . . . . . . . 6 | |||
3.2. Encoding and Decoding Contexts . . . . . . . . . . . . . . 6 | 2.3. Indexing Tables . . . . . . . . . . . . . . . . . . . . . 6 | |||
3.3. Header Table . . . . . . . . . . . . . . . . . . . . . . . 6 | 2.3.1. Static Table . . . . . . . . . . . . . . . . . . . . 6 | |||
3.4. Header Field Representation . . . . . . . . . . . . . . . 7 | 2.3.2. Dynamic Table . . . . . . . . . . . . . . . . . . . . 6 | |||
4. Header Block Decoding . . . . . . . . . . . . . . . . . . . . 8 | 2.3.3. Index Address Space . . . . . . . . . . . . . . . . . 7 | |||
4.1. Header Block Processing . . . . . . . . . . . . . . . . . 8 | 2.4. Header Field Representation . . . . . . . . . . . . . . . 7 | |||
4.2. Header Field Representation Processing . . . . . . . . . . 8 | 3. Header Block Decoding . . . . . . . . . . . . . . . . . . . . 8 | |||
5. Header Table Management . . . . . . . . . . . . . . . . . . . 9 | 3.1. Header Block Processing . . . . . . . . . . . . . . . . . 8 | |||
5.1. Maximum Table Size . . . . . . . . . . . . . . . . . . . . 9 | 3.2. Header Field Representation Processing . . . . . . . . . 8 | |||
5.2. Entry Eviction when Header Table Size Changes . . . . . . 10 | 4. Dynamic Table Management . . . . . . . . . . . . . . . . . . 9 | |||
5.3. Entry Eviction when Adding New Entries . . . . . . . . . . 10 | 4.1. Calculating Table Size . . . . . . . . . . . . . . . . . 9 | |||
6. Primitive Type Representations . . . . . . . . . . . . . . . . 10 | 4.2. Maximum Table Size . . . . . . . . . . . . . . . . . . . 9 | |||
6.1. Integer Representation . . . . . . . . . . . . . . . . . . 11 | 4.3. Entry Eviction When Dynamic Table Size Changes . . . . . 10 | |||
6.2. String Literal Representation . . . . . . . . . . . . . . 12 | 4.4. Entry Eviction When Adding New Entries . . . . . . . . . 10 | |||
7. Binary Format . . . . . . . . . . . . . . . . . . . . . . . . 13 | 5. Primitive Type Representations . . . . . . . . . . . . . . . 11 | |||
7.1. Indexed Header Field Representation . . . . . . . . . . . 13 | 5.1. Integer Representation . . . . . . . . . . . . . . . . . 11 | |||
7.2. Literal Header Field Representation . . . . . . . . . . . 13 | 5.2. String Literal Representation . . . . . . . . . . . . . . 13 | |||
7.2.1. Literal Header Field with Incremental Indexing . . . . 14 | 6. Binary Format . . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
7.2.2. Literal Header Field without Indexing . . . . . . . . 15 | 6.1. Indexed Header Field Representation . . . . . . . . . . . 14 | |||
7.2.3. Literal Header Field never Indexed . . . . . . . . . . 16 | 6.2. Literal Header Field Representation . . . . . . . . . . . 14 | |||
7.3. Header Table Size Update . . . . . . . . . . . . . . . . . 17 | 6.2.1. Literal Header Field with Incremental Indexing . . . 14 | |||
8. Security Considerations . . . . . . . . . . . . . . . . . . . 17 | 6.2.2. Literal Header Field without Indexing . . . . . . . . 15 | |||
8.1. Probing Header Table State . . . . . . . . . . . . . . . . 17 | 6.2.3. Literal Header Field Never Indexed . . . . . . . . . 16 | |||
8.1.1. Applicability to HPACK and HTTP . . . . . . . . . . . 18 | 6.3. Dynamic Table Size Update . . . . . . . . . . . . . . . . 17 | |||
8.1.2. Mitigation . . . . . . . . . . . . . . . . . . . . . . 19 | 7. Security Considerations . . . . . . . . . . . . . . . . . . . 18 | |||
8.1.3. Never Indexed Literals . . . . . . . . . . . . . . . . 20 | 7.1. Probing Dynamic Table State . . . . . . . . . . . . . . . 18 | |||
8.2. Static Huffman Encoding . . . . . . . . . . . . . . . . . 20 | 7.1.1. Applicability to HPACK and HTTP . . . . . . . . . . . 19 | |||
8.3. Memory Consumption . . . . . . . . . . . . . . . . . . . . 20 | 7.1.2. Mitigation . . . . . . . . . . . . . . . . . . . . . 20 | |||
8.4. Implementation Limits . . . . . . . . . . . . . . . . . . 21 | 7.1.3. Never-Indexed Literals . . . . . . . . . . . . . . . 21 | |||
9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 21 | 7.2. Static Huffman Encoding . . . . . . . . . . . . . . . . . 21 | |||
10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21 | 7.3. Memory Consumption . . . . . . . . . . . . . . . . . . . 21 | |||
10.1. Normative References . . . . . . . . . . . . . . . . . . . 21 | 7.4. Implementation Limits . . . . . . . . . . . . . . . . . . 22 | |||
10.2. Informative References . . . . . . . . . . . . . . . . . . 21 | ||||
Appendix A. Change Log (to be removed by RFC Editor before | ||||
publication) . . . . . . . . . . . . . . . . . . . . 22 | ||||
A.1. Since draft-ietf-httpbis-header-compression-08 . . . . . . 22 | ||||
A.2. Since draft-ietf-httpbis-header-compression-07 . . . . . . 23 | ||||
A.3. Since draft-ietf-httpbis-header-compression-06 . . . . . . 23 | ||||
A.4. Since draft-ietf-httpbis-header-compression-05 . . . . . . 23 | ||||
A.5. Since draft-ietf-httpbis-header-compression-04 . . . . . . 24 | ||||
A.6. Since draft-ietf-httpbis-header-compression-03 . . . . . . 24 | ||||
A.7. Since draft-ietf-httpbis-header-compression-02 . . . . . . 24 | ||||
A.8. Since draft-ietf-httpbis-header-compression-01 . . . . . . 24 | ||||
A.9. Since draft-ietf-httpbis-header-compression-00 . . . . . . 25 | ||||
Appendix B. Static Table . . . . . . . . . . . . . . . . . . . . 25 | ||||
Appendix C. Huffman Code . . . . . . . . . . . . . . . . . . . . 27 | ||||
Appendix D. Examples . . . . . . . . . . . . . . . . . . . . . . 33 | ||||
D.1. Integer Representation Examples . . . . . . . . . . . . . 33 | ||||
D.1.1. Example 1: Encoding 10 Using a 5-bit Prefix . . . . . 33 | ||||
D.1.2. Example 2: Encoding 1337 Using a 5-bit Prefix . . . . 34 | ||||
D.1.3. Example 3: Encoding 42 Starting at an Octet | ||||
Boundary . . . . . . . . . . . . . . . . . . . . . . . 35 | ||||
D.2. Header Field Representation Examples . . . . . . . . . . . 35 | ||||
D.2.1. Literal Header Field with Indexing . . . . . . . . . . 35 | ||||
D.2.2. Literal Header Field without Indexing . . . . . . . . 36 | ||||
D.2.3. Literal Header Field never Indexed . . . . . . . . . . 37 | ||||
D.2.4. Indexed Header Field . . . . . . . . . . . . . . . . . 37 | ||||
D.3. Request Examples without Huffman Coding . . . . . . . . . 38 | ||||
D.3.1. First Request . . . . . . . . . . . . . . . . . . . . 38 | ||||
D.3.2. Second Request . . . . . . . . . . . . . . . . . . . . 39 | ||||
D.3.3. Third Request . . . . . . . . . . . . . . . . . . . . 40 | ||||
D.4. Request Examples with Huffman Coding . . . . . . . . . . . 41 | ||||
D.4.1. First Request . . . . . . . . . . . . . . . . . . . . 42 | ||||
D.4.2. Second Request . . . . . . . . . . . . . . . . . . . . 43 | ||||
D.4.3. Third Request . . . . . . . . . . . . . . . . . . . . 44 | ||||
D.5. Response Examples without Huffman Coding . . . . . . . . . 45 | ||||
D.5.1. First Response . . . . . . . . . . . . . . . . . . . . 46 | ||||
D.5.2. Second Response . . . . . . . . . . . . . . . . . . . 48 | ||||
D.5.3. Third Response . . . . . . . . . . . . . . . . . . . . 49 | ||||
D.6. Response Examples with Huffman Coding . . . . . . . . . . 51 | ||||
D.6.1. First Response . . . . . . . . . . . . . . . . . . . . 51 | ||||
D.6.2. Second Response . . . . . . . . . . . . . . . . . . . 53 | ||||
D.6.3. Third Response . . . . . . . . . . . . . . . . . . . . 54 | ||||
1. Introduction | ||||
This specification defines HPACK, a compression format for | 8. References . . . . . . . . . . . . . . . . . . . . . . . . . 22 | |||
efficiently representing HTTP header fields in the context of HTTP/2 | 8.1. Normative References . . . . . . . . . . . . . . . . . . 22 | |||
[HTTP2]. | 8.2. Informative References . . . . . . . . . . . . . . . . . 23 | |||
Appendix A. Static Table Definition . . . . . . . . . . . . . . 24 | ||||
Appendix B. Huffman Code . . . . . . . . . . . . . . . . . . . . 25 | ||||
Appendix C. Examples . . . . . . . . . . . . . . . . . . . . . . 31 | ||||
C.1. Integer Representation Examples . . . . . . . . . . . . . 32 | ||||
C.1.1. Example 1: Encoding 10 Using a 5-Bit Prefix . . . . . 32 | ||||
C.1.2. Example 2: Encoding 1337 Using a 5-Bit Prefix . . . . 32 | ||||
C.1.3. Example 3: Encoding 42 Starting at an Octet Boundary 33 | ||||
C.2. Header Field Representation Examples . . . . . . . . . . 33 | ||||
C.2.1. Literal Header Field with Indexing . . . . . . . . . 33 | ||||
C.2.2. Literal Header Field without Indexing . . . . . . . . 34 | ||||
C.2.3. Literal Header Field Never Indexed . . . . . . . . . 35 | ||||
C.2.4. Indexed Header Field . . . . . . . . . . . . . . . . 35 | ||||
C.3. Request Examples without Huffman Coding . . . . . . . . . 36 | ||||
C.3.1. First Request . . . . . . . . . . . . . . . . . . . . 36 | ||||
C.3.2. Second Request . . . . . . . . . . . . . . . . . . . 37 | ||||
C.3.3. Third Request . . . . . . . . . . . . . . . . . . . . 38 | ||||
C.4. Request Examples with Huffman Coding . . . . . . . . . . 39 | ||||
C.4.1. First Request . . . . . . . . . . . . . . . . . . . . 39 | ||||
C.4.2. Second Request . . . . . . . . . . . . . . . . . . . 40 | ||||
C.4.3. Third Request . . . . . . . . . . . . . . . . . . . . 41 | ||||
C.5. Response Examples without Huffman Coding . . . . . . . . 43 | ||||
C.5.1. First Response . . . . . . . . . . . . . . . . . . . 43 | ||||
C.5.2. Second Response . . . . . . . . . . . . . . . . . . . 45 | ||||
C.5.3. Third Response . . . . . . . . . . . . . . . . . . . 46 | ||||
C.6. Response Examples with Huffman Coding . . . . . . . . . . 48 | ||||
C.6.1. First Response . . . . . . . . . . . . . . . . . . . 48 | ||||
C.6.2. Second Response . . . . . . . . . . . . . . . . . . . 50 | ||||
C.6.3. Third Response . . . . . . . . . . . . . . . . . . . 51 | ||||
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 53 | ||||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 54 | ||||
2. HPACK Overview | 1. Introduction | |||
In HTTP/1.1 (see [RFC7230]), header fields are encoded without any | In HTTP/1.1 (see [RFC7230]), header fields are not compressed. As | |||
form of compression. As web pages have grown to include dozens to | web pages have grown to require dozens to hundreds of requests, the | |||
hundreds of requests, the redundant header fields in these requests | redundant header fields in these requests unnecessarily consume | |||
now measurably increase latency and unnecessarily consume bandwidth | bandwidth, measurably increasing latency. | |||
(see [SPDY-DESC-1] and [SPDY-DESC-2]). | ||||
SPDY [SPDY] initially addressed this redundancy by compressing header | SPDY [SPDY] initially addressed this redundancy by compressing header | |||
fields using the DEFLATE [DEFLATE] format, which proved very | fields using the DEFLATE [DEFLATE] format, which proved very | |||
effective at efficiently representing the redundant header fields. | effective at efficiently representing the redundant header fields. | |||
However, that approach exposed a security risk as demonstrated by the | However, that approach exposed a security risk as demonstrated by the | |||
CRIME attack (see [CRIME]). | CRIME (Compression Ratio Info-leak Made Easy) attack (see [CRIME]). | |||
This document describes HPACK, a new compressor for header fields | This specification defines HPACK, a new compressor that eliminates | |||
which eliminates redundant header fields, limits vulnerability to | redundant header fields, limits vulnerability to known security | |||
known security attacks, and which has a bounded memory requirement | attacks, and has a bounded memory requirement for use in constrained | |||
for use in constrained environments. | environments. Potential security concerns for HPACK are described in | |||
Section 7. | ||||
2.1. Outline | The HPACK format is intentionally simple and inflexible. Both | |||
characteristics reduce the risk of interoperability or security | ||||
issues due to implementation error. No extensibility mechanisms are | ||||
defined; changes to the format are only possible by defining a | ||||
complete replacement. | ||||
The HTTP header field encoding defined in this document is based on a | 1.1. Overview | |||
header table that maps name-value pairs to index values. The header | ||||
table is incrementally updated as new values are encoded or decoded. | ||||
A list of header fields is treated as an ordered collection of name- | The format defined in this specification treats a list of header | |||
value pairs that can include duplicates. Names and values are | fields as an ordered collection of name-value pairs that can include | |||
considered to be opaque sequences of octets. The order of header | duplicate pairs. Names and values are considered to be opaque | |||
fields is preserved after being compressed and decompressed. | sequences of octets, and the order of header fields is preserved | |||
after being compressed and decompressed. | ||||
Encoding is informed by header field tables that map header fields to | ||||
indexed values. These header field tables can be incrementally | ||||
updated as new header fields are encoded or decoded. | ||||
In the encoded form, a header field is represented either literally | In the encoded form, a header field is represented either literally | |||
or as a reference to a name-value pair in a header table. A list of | or as a reference to a header field in one of the header field | |||
header fields can therefore be encoded using a mixture of references | tables. Therefore, a list of header fields can be encoded using a | |||
and literal values. | mixture of references and literal values. | |||
Literal values are either encoded directly or use a static Huffman | ||||
code. | ||||
The encoder is responsible for deciding which header fields to insert | The encoder is responsible for deciding which header fields to insert | |||
as new entries in the header table. The decoder executes the | as new entries in the header field tables. The decoder executes the | |||
modifications to the header table prescribed by the encoder, | modifications to the header field tables prescribed by the encoder, | |||
reconstructing the list of header fields in the process. This | reconstructing the list of header fields in the process. This | |||
enables decoders to remain simple and understand a wide variety of | enables decoders to remain simple and interoperate with a wide | |||
encoders. | variety of encoders. | |||
Examples illustrating the use of these different mechanisms to | Examples illustrating the use of these different mechanisms to | |||
represent header fields are available in Appendix D. | represent header fields are available in Appendix C. | |||
2.2. Conventions | 1.2. Conventions | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | |||
document are to be interpreted as described in RFC 2119 [RFC2119]. | document are to be interpreted as described in RFC 2119 [RFC2119]. | |||
All numeric values are in network byte order. Values are unsigned | All numeric values are in network byte order. Values are unsigned | |||
unless otherwise indicated. Literal values are provided in decimal | unless otherwise indicated. Literal values are provided in decimal | |||
or hexadecimal as appropriate. Hexadecimal literals are prefixed | or hexadecimal as appropriate. | |||
with "0x" to distinguish them from decimal literals. | ||||
2.3. Terminology | 1.3. Terminology | |||
This document uses the following terms: | This specification uses the following terms: | |||
Header Field: A name-value pair. Both the name and value are | Header Field: A name-value pair. Both the name and value are | |||
treated as opaque sequences of octets. | treated as opaque sequences of octets. | |||
Header Table: The header table (see Section 3.3) is a component used | Dynamic Table: The dynamic table (see Section 2.3.2) is a table that | |||
to associate stored header fields to index values. | associates stored header fields with index values. This table is | |||
dynamic and specific to an encoding or decoding context. | ||||
Static Table: The static table (see Appendix B) is a component used | Static Table: The static table (see Section 2.3.1) is a table that | |||
to associate static header fields to index values. This data is | statically associates header fields that occur frequently with | |||
ordered, read-only, always accessible, and may be shared amongst | index values. This table is ordered, read-only, always | |||
all encoding or decoding contexts. | accessible, and it may be shared amongst all encoding or decoding | |||
contexts. | ||||
Header List: A header list is an ordered collection of header fields | Header List: A header list is an ordered collection of header fields | |||
that are encoded jointly. It can contain duplicate header fields. | that are encoded jointly and can contain duplicate header fields. | |||
A complete list of key-value pairs contained in a HTTP request or | A complete list of header fields contained in an HTTP/2 header | |||
response is a header list. | block is a header list. | |||
Header Field Representation: A header field can be represented in | Header Field Representation: A header field can be represented in | |||
encoded form either as a literal or as an index (see Section 3.4). | encoded form either as a literal or as an index (see Section 2.4). | |||
Header Block: An ordered list of encoded header field | Header Block: An ordered list of header field representations, | |||
representations which, when decoded, yields a complete header | which, when decoded, yields a complete header list. | |||
list. | ||||
3. Compression Process Overview | 2. Compression Process Overview | |||
This specification does not describe a specific algorithm for an | This specification does not describe a specific algorithm for an | |||
encoder. Instead, it defines precisely how a decoder is expected to | encoder. Instead, it defines precisely how a decoder is expected to | |||
operate, allowing encoders to produce any encoding that this | operate, allowing encoders to produce any encoding that this | |||
definition permits. | definition permits. | |||
3.1. Header List Ordering | 2.1. Header List Ordering | |||
The compression and decompression process preserve the ordering of | ||||
header fields inside the header list. An encoder SHOULD order header | ||||
field representations in the header block according to their ordering | ||||
in the original header list. A decoder SHOULD order header fields in | ||||
the decoded header list according to their ordering in the header | ||||
block. | ||||
In particular, representations for pseudo-header fields MUST appear | ||||
before representations for regular header fields in a header block. | ||||
In a decoded header list, pseudo-header fields MUST appear before | ||||
regular header fields. | ||||
3.2. Encoding and Decoding Contexts | HPACK preserves the ordering of header fields inside the header list. | |||
An encoder MUST order header field representations in the header | ||||
block according to their ordering in the original header list. A | ||||
decoder MUST order header fields in the decoded header list according | ||||
to their ordering in the header block. | ||||
To decode header blocks, a decoder only needs to maintain a header | 2.2. Encoding and Decoding Contexts | |||
table (see Section 3.3) as a decoding context. No other state | ||||
information is needed. | ||||
An encoder that wishes to reference entries in the header table needs | To decompress header blocks, a decoder only needs to maintain a | |||
to maintain a copy of the header table used by the decoder. | dynamic table (see Section 2.3.2) as a decoding context. No other | |||
dynamic state is needed. | ||||
When used for bidirectional communication, such as in HTTP, the | When used for bidirectional communication, such as in HTTP, the | |||
encoding and decoding header tables maintained by an endpoint are | encoding and decoding dynamic tables maintained by an endpoint are | |||
completely independent. Header fields are encoded without any | completely independent, i.e., the request and response dynamic tables | |||
reference to the local decoding header table; and header fields are | are separate. | |||
decoded without reference to the local encoding header table. | ||||
3.3. Header Table | ||||
A header table consists of a list of header fields maintained in | 2.3. Indexing Tables | |||
first-in, first-out order. The first and newest entry in a header | ||||
table is always at index 1, and the oldest entry of a header table is | ||||
at the index corresponding to the number of entries in the header | ||||
table. | ||||
The header table is initially empty. | HPACK uses two tables for associating header fields to indexes. The | |||
static table (see Section 2.3.1) is predefined and contains common | ||||
header fields (most of them with an empty value). The dynamic table | ||||
(see Section 2.3.2) is dynamic and can be used by the encoder to | ||||
index header fields repeated in the encoded header lists. | ||||
The header table can contain duplicate entries. Therefore, duplicate | These two tables are combined into a single address space for | |||
entries MUST NOT be treated as an error by a decoder. | defining index values (see Section 2.3.3). | |||
The encoder decides how to update the header table and as such can | 2.3.1. Static Table | |||
control how much memory is used by the header table. To limit the | ||||
memory requirements of the decoder, the header table size is strictly | ||||
bounded (see Section 5.1). | ||||
The header table is updated during the processing of a list of header | The static table consists of a predefined static list of header | |||
field representations (see Section 4.2). | fields. Its entries are defined in Appendix A. | |||
3.4. Header Field Representation | 2.3.2. Dynamic Table | |||
An encoded header field can be represented either as a literal or as | The dynamic table consists of a list of header fields maintained in | |||
an index. | first-in, first-out order. The first and newest entry in a dynamic | |||
table is at the lowest index, and the oldest entry of a dynamic table | ||||
is at the highest index. | ||||
A literal representation defines a new header field. The header | The dynamic table is initially empty. Entries are added as each | |||
field name can be represented literally or as a reference to an entry | header block is decompressed. | |||
of the header table. The header field value is represented | ||||
literally. | ||||
Three different literal representations are provided: | The dynamic table can contain duplicate entries (i.e., entries with | |||
the same name and same value). Therefore, duplicate entries MUST NOT | ||||
be treated as an error by a decoder. | ||||
o A literal representation that does not add the header field to the | The encoder decides how to update the dynamic table and as such can | |||
header table (see Section 7.2.2). | control how much memory is used by the dynamic table. To limit the | |||
memory requirements of the decoder, the dynamic table size is | ||||
strictly bounded (see Section 4.2). | ||||
o A literal representation that does not add the header field to the | The decoder updates the dynamic table during the processing of a list | |||
header table, with the additional stipulation that this header | of header field representations (see Section 3.2). | |||
field always use a literal representation, in particular when re- | ||||
encoded by an intermediary (see Section 7.2.3). | ||||
o A literal representation that adds the header field as a new entry | 2.3.3. Index Address Space | |||
at the beginning of the header table (see Section 7.2.1). | ||||
An indexed representation defines a header field as a reference to an | The static table and the dynamic table are combined into a single | |||
entry in either the static table or the header table (see | index address space. | |||
Section 7.1). | ||||
Indices between 1 and the length of the static table (inclusive) | Indices between 1 and the length of the static table (inclusive) | |||
refer to elements in the static table (see Appendix B). | refer to elements in the static table (see Section 2.3.1). | |||
Indices strictly greater than the length of the static table refer to | Indices strictly greater than the length of the static table refer to | |||
elements in the header table (see Section 3.3). The length of the | elements in the dynamic table (see Section 2.3.2). The length of the | |||
static table is subtracted to find the index into the header table. | static table is subtracted to find the index into the dynamic table. | |||
Indices strictly greater than the sum of the lengths of both tables | Indices strictly greater than the sum of the lengths of both tables | |||
MUST be treated as a decoding error. | MUST be treated as a decoding error. | |||
For a static table size of s and a header table size of k, the | For a static table size of s and a dynamic table size of k, the | |||
following diagram shows the entire valid index address space. | following diagram shows the entire valid index address space. | |||
<---------- Index Address Space ----------> | <---------- Index Address Space ----------> | |||
<-- Static Table --> <-- Header Table --> | <-- Static Table --> <-- Dynamic Table --> | |||
+---+-----------+---+ +---+-----------+---+ | +---+-----------+---+ +---+-----------+---+ | |||
| 1 | ... | s | |s+1| ... |s+k| | | 1 | ... | s | |s+1| ... |s+k| | |||
+---+-----------+---+ +---+-----------+---+ | +---+-----------+---+ +---+-----------+---+ | |||
^ | | ^ | | |||
| V | | V | |||
Insertion Point Dropping Point | Insertion Point Dropping Point | |||
Index Address Space | Figure 1: Index Address Space | |||
4. Header Block Decoding | 2.4. Header Field Representation | |||
4.1. Header Block Processing | An encoded header field can be represented either as an index or as a | |||
literal. | ||||
A decoder processes an encoded header block sequentially to | An indexed representation defines a header field as a reference to an | |||
reconstruct the original header list. | entry in either the static table or the dynamic table (see | |||
Section 6.1). | ||||
A literal representation defines a header field by specifying its | ||||
name and value. The header field name can be represented literally | ||||
or as a reference to an entry in either the static table or the | ||||
dynamic table. The header field value is represented literally. | ||||
Three different literal representations are defined: | ||||
o A literal representation that adds the header field as a new entry | ||||
at the beginning of the dynamic table (see Section 6.2.1). | ||||
o A literal representation that does not add the header field to the | ||||
dynamic table (see Section 6.2.2). | ||||
o A literal representation that does not add the header field to the | ||||
dynamic table, with the additional stipulation that this header | ||||
field always use a literal representation, in particular when re- | ||||
encoded by an intermediary (see Section 6.2.3). This | ||||
representation is intended for protecting header field values that | ||||
are not to be put at risk by compressing them (see Section 7.1.3 | ||||
for more details). | ||||
The selection of one of these literal representations can be guided | ||||
by security considerations, in order to protect sensitive header | ||||
field values (see Section 7.1). | ||||
The literal representation of a header field name or of a header | ||||
field value can encode the sequence of octets either directly or | ||||
using a static Huffman code (see Section 5.2). | ||||
3. Header Block Decoding | ||||
3.1. Header Block Processing | ||||
A decoder processes a header block sequentially to reconstruct the | ||||
original header list. | ||||
A header block is the concatenation of header field representations. | ||||
The different possible header field representations are described in | ||||
Section 6. | ||||
Once a header field is decoded and added to the reconstructed header | Once a header field is decoded and added to the reconstructed header | |||
list, it cannot be removed from it. A header field added to the | list, the header field cannot be removed. A header field added to | |||
header list can be safely passed to the upper processing layer. | the header list can be safely passed to the application. | |||
By passing decoded header fields to the upper processing layer, a | By passing the resulting header fields to the application, a decoder | |||
decoder can be implemented with minimal transitory memory commitment | can be implemented with minimal transitory memory commitment in | |||
in addition to the header table. The management of memory for | addition to the memory required for the dynamic table. | |||
handling very large lists of header fields can therefore be deferred | ||||
to the upper processing layers. | ||||
4.2. Header Field Representation Processing | 3.2. Header Field Representation Processing | |||
The processing of a header block to obtain a header list is defined | The processing of a header block to obtain a header list is defined | |||
in this section. To ensure that the decoding will successfully | in this section. To ensure that the decoding will successfully | |||
produce a header list, a decoder MUST obey the following rules. | produce a header list, a decoder MUST obey the following rules. | |||
All the header field representations contained in a header block are | All the header field representations contained in a header block are | |||
processed in the order in which they appear, as specified below. | processed in the order in which they appear, as specified below. | |||
Details on the formatting of the various header field | Details on the formatting of the various header field representations | |||
representations, and some additional processing instructions are | and some additional processing instructions are found in Section 6. | |||
found in Section 7. | ||||
An _indexed representation_ entails the following actions: | An _indexed representation_ entails the following actions: | |||
o The header field corresponding to the referenced entry in either | o The header field corresponding to the referenced entry in either | |||
the static table or header table is added to the decoded header | the static table or dynamic table is appended to the decoded | |||
list. | header list. | |||
A _literal representation_ that is _not added_ to the header table | A _literal representation_ that is _not added_ to the dynamic table | |||
entails the following action: | entails the following action: | |||
o The header field is added to the decoded header list. | o The header field is appended to the decoded header list. | |||
A _literal representation_ that is _added_ to the header table | A _literal representation_ that is _added_ to the dynamic table | |||
entails the following actions: | entails the following actions: | |||
o The header field is added to the decoded header list. | o The header field is appended to the decoded header list. | |||
o The header field is inserted at the beginning of the header table. | ||||
5. Header Table Management | o The header field is inserted at the beginning of the dynamic | |||
table. This insertion could result in the eviction of previous | ||||
entries in the dynamic table (see Section 4.4). | ||||
5.1. Maximum Table Size | 4. Dynamic Table Management | |||
To limit the memory requirements on the decoder side, the header | To limit the memory requirements on the decoder side, the dynamic | |||
table is constrained in size. | table is constrained in size. | |||
The size of the header table is bounded by a maximum size defined by | 4.1. Calculating Table Size | |||
the decoder. The size of the header table MUST always be lower than | ||||
or equal to this maximum size. | ||||
By default, the maximum size of the header table is equal to the | The size of the dynamic table is the sum of the size of its entries. | |||
value of the HTTP/2 setting parameter SETTINGS_HEADER_TABLE_SIZE | ||||
defined by the decoder (see Section 6.5.2 of [HTTP2]). The encoder | ||||
can change this maximum size (see Section 7.3), but it MUST stay | ||||
lower than or equal to the value of SETTINGS_HEADER_TABLE_SIZE. | ||||
After applying an updated value of the SETTINGS_HEADER_TABLE_SIZE | The size of an entry is the sum of its name's length in octets (as | |||
parameter that changes the maximum size of the header table used by | defined in Section 5.2), its value's length in octets, and 32. | |||
the encoder, the encoder MUST signal this change via an encoding | ||||
context update (see Section 7.3). This encoding context update MUST | ||||
occur at the beginning of the first header block following the | ||||
SETTINGS frame sent to acknowledge the application of the updated | ||||
settings. | ||||
Several updated values for the SETTINGS_HEADER_TABLE_SIZE parameter | The size of an entry is calculated using the length of its name and | |||
can be acknowledged between the sending of two header blocks. In the | value without any Huffman encoding applied. | |||
case that the value is changed more that once, if a change causes the | ||||
SETTINGS_HEADER_TABLE_SIZE parameter to be less than the new maximum | ||||
size, the smallest value for this parameter MUST be sent before the | ||||
new maximum size, using two encoding context updates. This ensures | ||||
that the receiver is able to perform eviction based on the lower | ||||
table size. | ||||
This mechanism can be used in combination with a | Note: The additional 32 octets account for an estimated overhead | |||
SETTINGS_HEADER_TABLE_SIZE parameter value of 0 to completely clear | associated with an entry. For example, an entry structure using | |||
entries from the header table. | two 64-bit pointers to reference the name and the value of the | |||
entry and two 64-bit integers for counting the number of | ||||
references to the name and value would have 32 octets of overhead. | ||||
The size of the header table is the sum of the size of its entries. | 4.2. Maximum Table Size | |||
The size of an entry is the sum of its name's length in octets (as | Protocols that use HPACK determine the maximum size that the encoder | |||
defined in Section 6.2), its value's length in octets (Section 6.2), | is permitted to use for the dynamic table. In HTTP/2, this value is | |||
plus 32. | determined by the SETTINGS_HEADER_TABLE_SIZE setting (see | |||
Section 6.5.2 of [HTTP2]). | ||||
The size of an entry is calculated using the length of the name and | An encoder can choose to use less capacity than this maximum size | |||
value without any Huffman encoding applied. | (see Section 6.3), but the chosen size MUST stay lower than or equal | |||
to the maximum set by the protocol. | ||||
The additional 32 octets account for overhead associated with an | A change in the maximum size of the dynamic table is signaled via a | |||
entry. For example, an entry structure using two 64-bit pointers to | dynamic table size update (see Section 6.3). This dynamic table size | |||
reference the name and the value of the entry, and two 64-bit | update MUST occur at the beginning of the first header block | |||
integers for counting the number of references to the name and value | following the change to the dynamic table size. In HTTP/2, this | |||
would have 32 octets of overhead. | follows a settings acknowledgment (see Section 6.5.3 of [HTTP2]). | |||
5.2. Entry Eviction when Header Table Size Changes | Multiple updates to the maximum table size can occur between the | |||
transmission of two header blocks. In the case that this size is | ||||
changed more than once in this interval, the smallest maximum table | ||||
size that occurs in that interval MUST be signaled in a dynamic table | ||||
size update. The final maximum size is always signaled, resulting in | ||||
at most two dynamic table size updates. This ensures that the | ||||
decoder is able to perform eviction based on reductions in dynamic | ||||
table size (see Section 4.3). | ||||
Whenever the maximum size for the header table is reduced, entries | This mechanism can be used to completely clear entries from the | |||
are evicted from the end of the header table until the size of the | dynamic table by setting a maximum size of 0, which can subsequently | |||
header table is less than or equal to the maximum size. | be restored. | |||
5.3. Entry Eviction when Adding New Entries | 4.3. Entry Eviction When Dynamic Table Size Changes | |||
Whenever a new entry is to be added to the header table entries are | Whenever the maximum size for the dynamic table is reduced, entries | |||
evicted from the end of the header table until the size of the header | are evicted from the end of the dynamic table until the size of the | |||
table is less than or equal to (maximum size - new entry size), or | dynamic table is less than or equal to the maximum size. | |||
until the table is empty. | ||||
If the representation of the added entry references the name of an | 4.4. Entry Eviction When Adding New Entries | |||
entry in the header table, the referenced name is cached prior to | ||||
performing eviction to avoid having the name inadvertently evicted. | Before a new entry is added to the dynamic table, entries are evicted | |||
from the end of the dynamic table until the size of the dynamic table | ||||
is less than or equal to (maximum size - new entry size) or until the | ||||
table is empty. | ||||
If the size of the new entry is less than or equal to the maximum | If the size of the new entry is less than or equal to the maximum | |||
size, that entry is added to the table. It is not an error to | size, that entry is added to the table. It is not an error to | |||
attempt to add an entry that is larger than the maximum size; an | attempt to add an entry that is larger than the maximum size; an | |||
attempt to add an entry larger than the entire table causes the table | attempt to add an entry larger than the maximum size causes the table | |||
to be emptied of all existing entries. | to be emptied of all existing entries and results in an empty table. | |||
6. Primitive Type Representations | A new entry can reference the name of an entry in the dynamic table | |||
that will be evicted when adding this new entry into the dynamic | ||||
table. Implementations are cautioned to avoid deleting the | ||||
referenced name if the referenced entry is evicted from the dynamic | ||||
table prior to inserting the new entry. | ||||
HPACK encoding uses two primitive types: unsigned variable length | 5. Primitive Type Representations | |||
integers, and strings of octets. | ||||
6.1. Integer Representation | HPACK encoding uses two primitive types: unsigned variable-length | |||
integers and strings of octets. | ||||
Integers are used to represent name indexes, pair indexes or string | 5.1. Integer Representation | |||
lengths. To allow for optimized processing, an integer | ||||
Integers are used to represent name indexes, header field indexes, or | ||||
string lengths. An integer representation can start anywhere within | ||||
an octet. To allow for optimized processing, an integer | ||||
representation always finishes at the end of an octet. | representation always finishes at the end of an octet. | |||
An integer is represented in two parts: a prefix that fills the | An integer is represented in two parts: a prefix that fills the | |||
current octet and an optional list of octets that are used if the | current octet and an optional list of octets that are used if the | |||
integer value does not fit within the prefix. The number of bits of | integer value does not fit within the prefix. The number of bits of | |||
the prefix (called N) is a parameter of the integer representation. | the prefix (called N) is a parameter of the integer representation. | |||
The N-bit prefix allows filling the current octet. If the value is | If the integer value is small enough, i.e., strictly less than 2^N-1, | |||
small enough (strictly less than 2^N-1), it is encoded within the | it is encoded within the N-bit prefix. | |||
N-bit prefix. Otherwise all the bits of the prefix are set to 1 and | ||||
the value is encoded using an unsigned variable length integer | ||||
representation (see | ||||
<http://en.wikipedia.org/wiki/Variable-length_quantity>). N is | ||||
always between 1 and 8 bits. An integer starting at an octet- | ||||
boundary will have an 8-bit prefix. | ||||
The algorithm to represent an integer I is as follows: | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | ||||
| ? | ? | ? | Value | | ||||
+---+---+---+-------------------+ | ||||
Figure 2: Integer Value Encoded within the Prefix (Shown for N = 5) | ||||
Otherwise, all the bits of the prefix are set to 1, and the value, | ||||
decreased by 2^N-1, is encoded using a list of one or more octets. | ||||
The most significant bit of each octet is used as a continuation | ||||
flag: its value is set to 1 except for the last octet in the list. | ||||
The remaining bits of the octets are used to encode the decreased | ||||
value. | ||||
0 1 2 3 4 5 6 7 | ||||
+---+---+---+---+---+---+---+---+ | ||||
| ? | ? | ? | 1 1 1 1 1 | | ||||
+---+---+---+-------------------+ | ||||
| 1 | Value-(2^N-1) LSB | | ||||
+---+---------------------------+ | ||||
... | ||||
+---+---------------------------+ | ||||
| 0 | Value-(2^N-1) MSB | | ||||
+---+---------------------------+ | ||||
Figure 3: Integer Value Encoded after the Prefix (Shown for N = 5) | ||||
Decoding the integer value from the list of octets starts by | ||||
reversing the order of the octets in the list. Then, for each octet, | ||||
its most significant bit is removed. The remaining bits of the | ||||
octets are concatenated, and the resulting value is increased by | ||||
2^N-1 to obtain the integer value. | ||||
The prefix size, N, is always between 1 and 8 bits. An integer | ||||
starting at an octet boundary will have an 8-bit prefix. | ||||
Pseudocode to represent an integer I is as follows: | ||||
if I < 2^N - 1, encode I on N bits | if I < 2^N - 1, encode I on N bits | |||
else | else | |||
encode (2^N - 1) on N bits | encode (2^N - 1) on N bits | |||
I = I - (2^N - 1) | I = I - (2^N - 1) | |||
while I >= 128 | while I >= 128 | |||
encode (I % 128 + 128) on 8 bits | encode (I % 128 + 128) on 8 bits | |||
I = I / 128 | I = I / 128 | |||
encode I on 8 bits | encode I on 8 bits | |||
For informational purpose, the algorithm to decode an integer I is as | Pseudocode to decode an integer I is as follows: | |||
follows: | ||||
decode I from the next N bits | decode I from the next N bits | |||
if I < 2^N - 1, return I | if I < 2^N - 1, return I | |||
else | else | |||
M = 0 | M = 0 | |||
repeat | repeat | |||
B = next octet | B = next octet | |||
I = I + (B & 127) * 2^M | I = I + (B & 127) * 2^M | |||
M = M + 7 | M = M + 7 | |||
while B & 128 == 128 | while B & 128 == 128 | |||
return I | return I | |||
Examples illustrating the encoding of integers are available in | Examples illustrating the encoding of integers are available in | |||
Appendix D.1. | Appendix C.1. | |||
This integer representation allows for values of indefinite size. It | This integer representation allows for values of indefinite size. It | |||
is also possible for an encoder to send a large number of zero | is also possible for an encoder to send a large number of zero | |||
values, which can waste octets and could be used to overflow integer | values, which can waste octets and could be used to overflow integer | |||
values. Excessively large integer encodings - in value or octet | values. Integer encodings that exceed implementation limits -- in | |||
length - MUST be treated as a decoding error. Different limits can | value or octet length -- MUST be treated as decoding errors. | |||
be set for each of the different uses of integers, based on | Different limits can be set for each of the different uses of | |||
implementation constraints. | integers, based on implementation constraints. | |||
6.2. String Literal Representation | 5.2. String Literal Representation | |||
Header field names and header field values can be represented as | Header field names and header field values can be represented as | |||
literal string. A literal string is encoded as a sequence of octets, | string literals. A string literal is encoded as a sequence of | |||
either by directly encoding the literal string's octets, or by using | octets, either by directly encoding the string literal's octets or by | |||
a Huffman code (see [HUFFMAN]). | using a Huffman code (see [HUFFMAN]). | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| H | String Length (7+) | | | H | String Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| String Data (Length octets) | | | String Data (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
String Literal Representation | Figure 4: String Literal Representation | |||
A literal string representation contains the following fields: | A string literal representation contains the following fields: | |||
H: A one bit flag, H, indicating whether or not the octets of the | H: A one-bit flag, H, indicating whether or not the octets of the | |||
string are Huffman encoded. | string are Huffman encoded. | |||
String Length: The number of octets used to encode the string | String Length: The number of octets used to encode the string | |||
literal, encoded as an integer with 7-bit prefix (see | literal, encoded as an integer with a 7-bit prefix (see | |||
Section 6.1). | Section 5.1). | |||
String Data: The encoded data of the string literal. If H is '0', | String Data: The encoded data of the string literal. If H is '0', | |||
then the encoded data is the raw octets of the string literal. If | then the encoded data is the raw octets of the string literal. If | |||
H is '1', then the encoded data is the Huffman encoding of the | H is '1', then the encoded data is the Huffman encoding of the | |||
string literal. | string literal. | |||
String literals which use Huffman encoding are encoded with the | String literals that use Huffman encoding are encoded with the | |||
Huffman code defined in Appendix C (see examples in Request Examples | Huffman code defined in Appendix B (see examples for requests in | |||
with Huffman Coding (Appendix D.4) and in Response Examples with | Appendix C.4 and for responses in Appendix C.6). The encoded data is | |||
Huffman Coding (Appendix D.6)). The encoded data is the bitwise | the bitwise concatenation of the codes corresponding to each octet of | |||
concatenation of the codes corresponding to each octet of the string | the string literal. | |||
literal. | ||||
As the Huffman encoded data doesn't always end at an octet boundary, | As the Huffman-encoded data doesn't always end at an octet boundary, | |||
some padding is inserted after it up to the next octet boundary. To | some padding is inserted after it, up to the next octet boundary. To | |||
prevent this padding to be misinterpreted as part of the string | prevent this padding from being misinterpreted as part of the string | |||
literal, the most significant bits of code corresponding to the EOS | literal, the most significant bits of the code corresponding to the | |||
(end-of-string) symbol are used. | EOS (end-of-string) symbol are used. | |||
Upon decoding, an incomplete code at the end of the encoded data is | Upon decoding, an incomplete code at the end of the encoded data is | |||
to be considered as padding and discarded. A padding strictly longer | to be considered as padding and discarded. A padding strictly longer | |||
than 7 bits MUST be treated as a decoding error. A padding not | than 7 bits MUST be treated as a decoding error. A padding not | |||
corresponding to the most significant bits of the code for the EOS | corresponding to the most significant bits of the code for the EOS | |||
symbol MUST be treated as a decoding error. A Huffman encoded string | symbol MUST be treated as a decoding error. A Huffman-encoded string | |||
literal containing the EOS symbol MUST be treated as a decoding | literal containing the EOS symbol MUST be treated as a decoding | |||
error. | error. | |||
7. Binary Format | 6. Binary Format | |||
This section describes the detailed format of each of the different | This section describes the detailed format of each of the different | |||
header field representations, plus the encoding context update | header field representations and the dynamic table size update | |||
instruction. | instruction. | |||
7.1. Indexed Header Field Representation | 6.1. Indexed Header Field Representation | |||
An indexed header field representation identifies an entry in either | An indexed header field representation identifies an entry in either | |||
the static table or the header table. | the static table or the dynamic table (see Section 2.3). | |||
An indexed header field representation causes a header field to be | An indexed header field representation causes a header field to be | |||
added to the decoded header list, as described in Section 4.2. | added to the decoded header list, as described in Section 3.2. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 1 | Index (7+) | | | 1 | Index (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
Indexed Header Field | Figure 5: Indexed Header Field | |||
An indexed header field starts with the '1' 1-bit pattern, followed | An indexed header field starts with the '1' 1-bit pattern, followed | |||
by the index of the matching pair, represented as an integer with a | by the index of the matching header field, represented as an integer | |||
7-bit prefix (see Section 6.1). | with a 7-bit prefix (see Section 5.1). | |||
The index value of 0 is not used. It MUST be treated as a decoding | The index value of 0 is not used. It MUST be treated as a decoding | |||
error if found in an indexed header field representation. | error if found in an indexed header field representation. | |||
7.2. Literal Header Field Representation | 6.2. Literal Header Field Representation | |||
A literal header field representation contains a literal header field | A literal header field representation contains a literal header field | |||
value. Header field names are either provided as a literal or by | value. Header field names are provided either as a literal or by | |||
reference to an existing table entry, either from the static table or | reference to an existing table entry, either from the static table or | |||
the header table. | the dynamic table (see Section 2.3). | |||
A literal representation causes a header field to be added to the | This specification defines three forms of literal header field | |||
decoded header list, as described in Section 4.2. | representations: with indexing, without indexing, and never indexed. | |||
7.2.1. Literal Header Field with Incremental Indexing | 6.2.1. Literal Header Field with Incremental Indexing | |||
A literal header field with incremental indexing representation | A literal header field with incremental indexing representation | |||
results in adding a header field to the decoded header list and | results in appending a header field to the decoded header list and | |||
inserting it as a new entry into the header table. | inserting it as a new entry into the dynamic table. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 1 | Index (6+) | | | 0 | 1 | Index (6+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field with Incremental Indexing - | Figure 6: Literal Header Field with Incremental Indexing -- Indexed | |||
Indexed Name | Name | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 1 | 0 | | | 0 | 1 | 0 | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Name Length (7+) | | | H | Name Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Name String (Length octets) | | | Name String (Length octets) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field with Incremental Indexing - | Figure 7: Literal Header Field with Incremental Indexing -- New Name | |||
New Name | ||||
A literal header field with incremental indexing representation | A literal header field with incremental indexing representation | |||
starts with the '01' 2-bit pattern. | starts with the '01' 2-bit pattern. | |||
If the header field name matches the header field name of an entry | If the header field name matches the header field name of an entry | |||
stored in the static table or the header table, the header field name | stored in the static table or the dynamic table, the header field | |||
can be represented using the index of that entry. In this case, the | name can be represented using the index of that entry. In this case, | |||
index of the entry is represented as an integer with a 6-bit prefix | the index of the entry is represented as an integer with a 6-bit | |||
(see Section 6.1). This value is always non-zero. | prefix (see Section 5.1). This value is always non-zero. | |||
Otherwise, the header field name is represented as a literal. A | Otherwise, the header field name is represented as a string literal | |||
value 0 is used in place of the 6-bit index, followed by the header | (see Section 5.2). A value 0 is used in place of the 6-bit index, | |||
field name (see Section 6.2). | followed by the header field name. | |||
Either form of header field name representation is followed by the | Either form of header field name representation is followed by the | |||
header field value represented as a literal string as described in | header field value represented as a string literal (see Section 5.2). | |||
Section 6.2. | ||||
7.2.2. Literal Header Field without Indexing | 6.2.2. Literal Header Field without Indexing | |||
A literal header field without indexing representation results in | A literal header field without indexing representation results in | |||
adding a header field to the decoded header list without altering the | appending a header field to the decoded header list without altering | |||
header table. | the dynamic table. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 0 | 0 | Index (4+) | | | 0 | 0 | 0 | 0 | Index (4+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field without Indexing - Indexed Name | Figure 8: Literal Header Field without Indexing -- Indexed Name | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 0 | 0 | 0 | | | 0 | 0 | 0 | 0 | 0 | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Name Length (7+) | | | H | Name Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Name String (Length octets) | | | Name String (Length octets) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field without Indexing - New Name | Figure 9: Literal Header Field without Indexing -- New Name | |||
A literal header field without indexing representation starts with | A literal header field without indexing representation starts with | |||
the '0000' 4-bit pattern. | the '0000' 4-bit pattern. | |||
If the header field name matches the header field name of an entry | If the header field name matches the header field name of an entry | |||
stored in the static table or the header table, the header field name | stored in the static table or the dynamic table, the header field | |||
can be represented using the index of that entry. In this case, the | name can be represented using the index of that entry. In this case, | |||
index of the entry is represented as an integer with a 4-bit prefix | the index of the entry is represented as an integer with a 4-bit | |||
(see Section 6.1). This value is always non-zero. | prefix (see Section 5.1). This value is always non-zero. | |||
Otherwise, the header field name is represented as a literal. A | Otherwise, the header field name is represented as a string literal | |||
value 0 is used in place of the 4-bit index, followed by the header | (see Section 5.2). A value 0 is used in place of the 4-bit index, | |||
field name (see Section 6.2). | followed by the header field name. | |||
Either form of header field name representation is followed by the | Either form of header field name representation is followed by the | |||
header field value represented as a literal string as described in | header field value represented as a string literal (see Section 5.2). | |||
Section 6.2. | ||||
7.2.3. Literal Header Field never Indexed | 6.2.3. Literal Header Field Never Indexed | |||
A literal header field never indexed representation results in adding | A literal header field never-indexed representation results in | |||
a header field to the decoded header list without altering the header | appending a header field to the decoded header list without altering | |||
table. Intermediaries MUST use the same representation for encoding | the dynamic table. Intermediaries MUST use the same representation | |||
this header field. | for encoding this header field. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 0 | 1 | Index (4+) | | | 0 | 0 | 0 | 1 | Index (4+) | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field never Indexed - Indexed Name | Figure 10: Literal Header Field Never Indexed -- Indexed Name | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 0 | 1 | 0 | | | 0 | 0 | 0 | 1 | 0 | | |||
+---+---+-----------------------+ | +---+---+-----------------------+ | |||
| H | Name Length (7+) | | | H | Name Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Name String (Length octets) | | | Name String (Length octets) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| H | Value Length (7+) | | | H | Value Length (7+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
| Value String (Length octets) | | | Value String (Length octets) | | |||
+-------------------------------+ | +-------------------------------+ | |||
Literal Header Field never Indexed - New Name | Figure 11: Literal Header Field Never Indexed -- New Name | |||
A literal header field never indexed representation starts with the | A literal header field never-indexed representation starts with the | |||
'0001' 4-bit pattern. | '0001' 4-bit pattern. | |||
When a header field is represented as a literal header field never | When a header field is represented as a literal header field never | |||
indexed, it MUST always be encoded with this specific literal | indexed, it MUST always be encoded with this specific literal | |||
representation. In particular, when a peer sends a header field that | representation. In particular, when a peer sends a header field that | |||
it received represented as a literal header field never indexed, it | it received represented as a literal header field never indexed, it | |||
MUST use the same representation to forward this header field. | MUST use the same representation to forward this header field. | |||
This representation is intended for protecting header field values | This representation is intended for protecting header field values | |||
that are not to be put at risk by compressing them (see Section 8.1 | that are not to be put at risk by compressing them (see Section 7.1 | |||
for more details). | for more details). | |||
The encoding of the representation is identical to the literal header | The encoding of the representation is identical to the literal header | |||
field without indexing (see Section 7.2.2). | field without indexing (see Section 6.2.2). | |||
7.3. Header Table Size Update | 6.3. Dynamic Table Size Update | |||
A header table size update signals a change to the size of the header | A dynamic table size update signals a change to the size of the | |||
table. | dynamic table. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 1 | Max size (5+) | | | 0 | 0 | 1 | Max size (5+) | | |||
+---+---------------------------+ | +---+---------------------------+ | |||
Maximum Header Table Size Change | Figure 12: Maximum Dynamic Table Size Change | |||
A header table size update starts with the '001' 3-bit pattern, | A dynamic table size update starts with the '001' 3-bit pattern, | |||
followed by the new maximum size, represented as an integer with a | followed by the new maximum size, represented as an integer with a | |||
5-bit prefix (see Section 6.1). | 5-bit prefix (see Section 5.1). | |||
The new maximum size MUST be lower than or equal to the maximum set | The new maximum size MUST be lower than or equal to the limit | |||
by the decoder. That is, the value of the HTTP/2 setting parameter | determined by the protocol using HPACK. A value that exceeds this | |||
SETTINGS_HEADER_TABLE_SIZE, defined in Section 6.5.2 of [HTTP2]. | limit MUST be treated as a decoding error. In HTTP/2, this limit is | |||
the last value of the SETTINGS_HEADER_TABLE_SIZE parameter (see | ||||
Section 6.5.2 of [HTTP2]) received from the decoder and acknowledged | ||||
by the encoder (see Section 6.5.3 of [HTTP2]). | ||||
Reducing the maximum size of the header table causes entries to be | Reducing the maximum size of the dynamic table can cause entries to | |||
evicted (see Section 5.2). | be evicted (see Section 4.3). | |||
8. Security Considerations | 7. Security Considerations | |||
This section describes potential areas of security concern with | This section describes potential areas of security concern with | |||
HPACK: | HPACK: | |||
o Use of compression as a length-based oracle for verifying guesses | o Use of compression as a length-based oracle for verifying guesses | |||
about secrets that are compressed into a shared compression | about secrets that are compressed into a shared compression | |||
context. | context. | |||
o Denial of service resulting from exhausting processing or memory | o Denial of service resulting from exhausting processing or memory | |||
capacity at a decoder. | capacity at a decoder. | |||
8.1. Probing Header Table State | 7.1. Probing Dynamic Table State | |||
HPACK reduces the length of header field encodings by exploiting the | HPACK reduces the length of header field encodings by exploiting the | |||
redundancy inherent in protocols like HTTP. The ultimate goal of | redundancy inherent in protocols like HTTP. The ultimate goal of | |||
this is to reduce the amount of data that is required to send HTTP | this is to reduce the amount of data that is required to send HTTP | |||
requests or responses. | requests or responses. | |||
The compression context used to encode header fields can be probed by | The compression context used to encode header fields can be probed by | |||
an attacker that has the following capabilities: to define header | an attacker who can both define header fields to be encoded and | |||
fields to be encoded and transmitted; and to observe the length of | transmitted and observe the length of those fields once they are | |||
those fields once they are encoded. This allows an attacker to | encoded. When an attacker can do both, they can adaptively modify | |||
adaptively modify requests in order to confirm guesses about the | requests in order to confirm guesses about the dynamic table state. | |||
header table state. If a guess is compressed into a shorter length, | If a guess is compressed into a shorter length, the attacker can | |||
the attacker can observe the encoded length and infer that the guess | observe the encoded length and infer that the guess was correct. | |||
was correct. | ||||
This is possible because while TLS provides confidentiality | This is possible even over the Transport Layer Security (TLS) | |||
protocol (see [TLS12]), because while TLS provides confidentiality | ||||
protection for content, it only provides a limited amount of | protection for content, it only provides a limited amount of | |||
protection for the length of that content. | protection for the length of that content. | |||
Note: Padding schemes only provide limited protection against an | Note: Padding schemes only provide limited protection against an | |||
attacker with these capabilities, potentially only forcing an | attacker with these capabilities, potentially only forcing an | |||
increased number of guesses to learn the length associated with a | increased number of guesses to learn the length associated with a | |||
given guess. Padding schemes also work directly against | given guess. Padding schemes also work directly against | |||
compression by increasing the number of bits that are transmitted. | compression by increasing the number of bits that are transmitted. | |||
Attacks like CRIME [CRIME] demonstrated the existence of these | Attacks like CRIME [CRIME] demonstrated the existence of these | |||
general attacker capabilities. The specific attack exploited the | general attacker capabilities. The specific attack exploited the | |||
fact that DEFLATE [DEFLATE] removes redundancy based on prefix | fact that DEFLATE [DEFLATE] removes redundancy based on prefix | |||
matching. This permitted the attacker to confirm guesses a character | matching. This permitted the attacker to confirm guesses a character | |||
at a time, reducing an exponential-time attack into a constant time | at a time, reducing an exponential-time attack into a linear-time | |||
attack. | attack. | |||
8.1.1. Applicability to HPACK and HTTP | 7.1.1. Applicability to HPACK and HTTP | |||
HPACK mitigates but does not completely prevent attacks modelled on | HPACK mitigates but does not completely prevent attacks modeled on | |||
CRIME [CRIME] by forcing a guess to match an entire header field | CRIME [CRIME] by forcing a guess to match an entire header field | |||
value, rather than individual characters. An attacker can only learn | value rather than individual characters. Attackers can only learn | |||
whether a guess is correct or not, so is reduced to a brute force | whether a guess is correct or not, so they are reduced to brute-force | |||
guess for the header field values. | guesses for the header field values. | |||
The viability of recovering specific header field values therefore | The viability of recovering specific header field values therefore | |||
depends on the entropy of values. As a result, values with high | depends on the entropy of values. As a result, values with high | |||
entropy are unlikely to be recovered successfully. However, values | entropy are unlikely to be recovered successfully. However, values | |||
with low entropy remain vulnerable. | with low entropy remain vulnerable. | |||
Attacks of this nature are possible any time that two mutually | Attacks of this nature are possible any time that two mutually | |||
distrustful entities control requests or responses that are placed | distrustful entities control requests or responses that are placed | |||
onto a single HTTP/2 connection. If the shared HPACK compressor | onto a single HTTP/2 connection. If the shared HPACK compressor | |||
permits one entity to add entries to the header table, and the other | permits one entity to add entries to the dynamic table and the other | |||
to access those entries, then the state of the table can be learned. | to access those entries, then the state of the table can be learned. | |||
Having requests or responses from mutually distrustful entities | Having requests or responses from mutually distrustful entities | |||
occurs when an intermediary either: | occurs when an intermediary either: | |||
o sends requests from multiple clients on a single connection toward | o sends requests from multiple clients on a single connection toward | |||
an origin server, or | an origin server, or | |||
o takes responses from multiple origin servers and places them on a | o takes responses from multiple origin servers and places them on a | |||
shared connection toward a client. | shared connection toward a client. | |||
Web browsers also need to assume that requests made on the same | Web browsers also need to assume that requests made on the same | |||
connection by different web origins [ORIGIN] are made by mutually | connection by different web origins [ORIGIN] are made by mutually | |||
distrustful entities. | distrustful entities. | |||
8.1.2. Mitigation | 7.1.2. Mitigation | |||
Users of HTTP that require confidentiality for header fields can use | Users of HTTP that require confidentiality for header fields can use | |||
values with entropy sufficient to make guessing infeasible. However, | values with entropy sufficient to make guessing infeasible. However, | |||
this is impractical as a general solution because it forces all users | this is impractical as a general solution because it forces all users | |||
of HTTP to take steps to mitigate attacks. It would impose new | of HTTP to take steps to mitigate attacks. It would impose new | |||
constraints on how HTTP is used. | constraints on how HTTP is used. | |||
Rather than impose constraints on users of HTTP, an implementation of | Rather than impose constraints on users of HTTP, an implementation of | |||
HPACK can instead constrain how compression is applied in order to | HPACK can instead constrain how compression is applied in order to | |||
limit the potential for header table probing. | limit the potential for dynamic table probing. | |||
An ideal solution segregates access to the header table based on the | An ideal solution segregates access to the dynamic table based on the | |||
entity that is constructing header fields. Header field values that | entity that is constructing header fields. Header field values that | |||
are added to the table are attributed to an entity, and only the | are added to the table are attributed to an entity, and only the | |||
entity that created an particular value can extract that value. | entity that created a particular value can extract that value. | |||
To improve compression performance of this option, certain entries | To improve compression performance of this option, certain entries | |||
might be tagged as being public. For example, a web browser might | might be tagged as being public. For example, a web browser might | |||
make the values of the Accept-Encoding header field available in all | make the values of the Accept-Encoding header field available in all | |||
requests. | requests. | |||
An encoder without good knowledge of the provenance of header fields | An encoder without good knowledge of the provenance of header fields | |||
might instead introduce a penalty for bad guesses, such that attempts | might instead introduce a penalty for a header field with many | |||
to guess a header field value results in all values being removed | different values, such that a large number of attempts to guess a | |||
from consideration in all future requests, effectively preventing | header field value results in the header field no longer being | |||
further guesses. | compared to the dynamic table entries in future messages, effectively | |||
preventing further guesses. | ||||
Note: Simply removing values from the header table can be | Note: Simply removing entries corresponding to the header field | |||
ineffectual if the attacker has a reliable way of causing values | from the dynamic table can be ineffectual if the attacker has a | |||
to be reinstalled. For example, a request to load an image in a | reliable way of causing values to be reinstalled. For example, a | |||
web browser typically includes the Cookie header field (a | request to load an image in a web browser typically includes the | |||
potentially highly valued target for this sort of attack), and web | Cookie header field (a potentially highly valued target for this | |||
sites can easily force an image to be loaded, thereby refreshing | sort of attack), and web sites can easily force an image to be | |||
the entry in the header table. | loaded, thereby refreshing the entry in the dynamic table. | |||
This response might be made inversely proportional to the length of | This response might be made inversely proportional to the length of | |||
the header field. Marking as inaccessible might occur for shorter | the header field value. Marking a header field as not using the | |||
values more quickly or with higher probability than for longer | dynamic table anymore might occur for shorter values more quickly or | |||
values. | with higher probability than for longer values. | |||
Implementations might also choose to protect certain header fields | 7.1.3. Never-Indexed Literals | |||
that are known to be highly valued, such as the Authorization or | ||||
Cookie header fields, by disabling or further limiting compression. | ||||
8.1.3. Never Indexed Literals | Implementations can also choose to protect sensitive header fields by | |||
not compressing them and instead encoding their value as literals. | ||||
Refusing to generate an indexed representation for a header field is | Refusing to generate an indexed representation for a header field is | |||
only effective if compression is avoided on all hops. The new | only effective if compression is avoided on all hops. The never- | |||
indexed literal (see Section 7.2.3) can be used to signal to | indexed literal (see Section 6.2.3) can be used to signal to | |||
intermediaries that a particular value was intentionally sent as a | intermediaries that a particular value was intentionally sent as a | |||
literal. An intermediary MUST NOT re-encode a value that uses the | literal. | |||
never indexed literal as an indexed representation. | ||||
8.2. Static Huffman Encoding | An intermediary MUST NOT re-encode a value that uses the never- | |||
indexed literal representation with another representation that would | ||||
index it. If HPACK is used for re-encoding, the never-indexed | ||||
literal representation MUST be used. | ||||
There is currently no known threat taking advantage of the use of a | The choice to use a never-indexed literal representation for a header | |||
fixed Huffman encoding. A study has shown that using a fixed Huffman | field depends on several factors. Since HPACK doesn't protect | |||
encoding table created an information leakage, however this same | against guessing an entire header field value, short or low-entropy | |||
study concluded that an attacker could not take advantage of this | values are more readily recovered by an adversary. Therefore, an | |||
information leakage to recover any meaningful amount of information | encoder might choose not to index values with low entropy. | |||
(see [PETAL]). | ||||
8.3. Memory Consumption | An encoder might also choose not to index values for header fields | |||
that are considered to be highly valuable or sensitive to recovery, | ||||
such as the Cookie or Authorization header fields. | ||||
On the contrary, an encoder might prefer indexing values for header | ||||
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. | ||||
Note that these criteria for deciding to use a never-indexed literal | ||||
representation will evolve over time as new attacks are discovered. | ||||
7.2. Static Huffman Encoding | ||||
There is no currently known attack against a static Huffman encoding. | ||||
A study has shown that using a static Huffman encoding table created | ||||
an information leakage; however, this same study concluded that an | ||||
attacker could not take advantage of this information leakage to | ||||
recover any meaningful amount of information (see [PETAL]). | ||||
7.3. Memory Consumption | ||||
An attacker can try to cause an endpoint to exhaust its memory. | An attacker can try to cause an endpoint to exhaust its memory. | |||
HPACK is designed to limit both the peak and state amounts of memory | HPACK is designed to limit both the peak and state amounts of memory | |||
allocated by an endpoint. | allocated by an endpoint. | |||
The amount of memory used by the compressor state is limited by the | The amount of memory used by the compressor is limited by the | |||
decoder using the value of the HTTP/2 setting parameter | protocol using HPACK through the definition of the maximum size of | |||
SETTINGS_HEADER_TABLE_SIZE (see Section 6.5.2 of [HTTP2]). This | the dynamic table. In HTTP/2, this value is controlled by the | |||
limit takes into account both the size of the data stored in the | decoder through the setting parameter SETTINGS_HEADER_TABLE_SIZE (see | |||
header table, plus a small allowance for overhead. | Section 6.5.2 of [HTTP2]). This limit takes into account both the | |||
size of the data stored in the dynamic table, plus a small allowance | ||||
for overhead. | ||||
A decoder can limit the amount of state memory used by setting an | A decoder can limit the amount of state memory used by setting an | |||
appropriate value for the SETTINGS_HEADER_TABLE_SIZE parameter. An | appropriate value for the maximum size of the dynamic table. In | |||
encoder can limit the amount of state memory it uses by signalling | HTTP/2, this is realized by setting an appropriate value for the | |||
lower header table size than the decoder allows (see Section 7.3). | SETTINGS_HEADER_TABLE_SIZE parameter. An encoder can limit the | |||
amount of state memory it uses by signaling a lower dynamic table | ||||
size than the decoder allows (see Section 6.3). | ||||
The amount of temporary memory consumed by an encoder or decoder can | The amount of temporary memory consumed by an encoder or decoder can | |||
be limited by processing header fields sequentially. An | be limited by processing header fields sequentially. An | |||
implementation does not need to retain a complete list of header | implementation does not need to retain a complete list of header | |||
fields. Note however that it might be necessary for an application | fields. Note, however, that it might be necessary for an application | |||
to retain a complete header list for other reasons; even though HPACK | to retain a complete header list for other reasons; even though HPACK | |||
does not force this to occur, application constraints might make this | does not force this to occur, application constraints might make this | |||
necessary. | necessary. | |||
8.4. Implementation Limits | 7.4. Implementation Limits | |||
An implementation of HPACK needs to ensure that large values for | An implementation of HPACK needs to ensure that large values for | |||
integers, long encoding for integers, or long string literals do not | integers, long encoding for integers, or long string literals do not | |||
create security weaknesses. | create security weaknesses. | |||
An implementation has to set a limit for the values it accepts for | An implementation has to set a limit for the values it accepts for | |||
integers, as well as for the encoded length (see Section 6.1). In | integers, as well as for the encoded length (see Section 5.1). In | |||
the same way, it has to set a limit to the length it accepts for | the same way, it has to set a limit to the length it accepts for | |||
string literals (see Section 6.2). | string literals (see Section 5.2). | |||
9. Acknowledgements | ||||
This document includes substantial input from the following | ||||
individuals: | ||||
o Mike Bishop, Jeff Pinner, Julian Reschke, Martin Thomson | ||||
(substantial editorial contributions). | ||||
o Johnny Graettinger (Huffman code statistics). | ||||
10. References | ||||
10.1. Normative References | ||||
[HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | ||||
Transfer Protocol version 2", | ||||
draft-ietf-httpbis-http2-14 (work in progress), | ||||
July 2014. | ||||
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | ||||
Requirement Levels", BCP 14, RFC 2119, March 1997. | ||||
[RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext | ||||
Transfer Protocol (HTTP/1.1): Message Syntax and | ||||
Routing", RFC 7230, June 2014. | ||||
10.2. Informative References | ||||
[CANONICAL] Schwartz, E. and B. Kallick, "Generating a canonical | ||||
prefix encoding", Communications of the ACM Volume 7 | ||||
Issue 3, pp. 166-169, March 1964, | ||||
<https://dl.acm.org/citation.cfm?id=363991>. | ||||
[CRIME] Rizzo, J. and T. Duong, "The CRIME Attack", | ||||
September 2012, <https://docs.google.com/a/twist.com/ | ||||
presentation/d/ | ||||
11eBmGiHbYcHR9gL5nDyZChu_-lCa2GizeuOfaLU2HOU/ | ||||
edit#slide=id.g1eb6c1b5_3_6>. | ||||
[DEFLATE] Deutsch, P., "DEFLATE Compressed Data Format | ||||
Specification version 1.3", RFC 1951, May 1996. | ||||
[HUFFMAN] Huffman, D., "A Method for the Construction of Minimum | ||||
Redundancy Codes", Proceedings of the Institute of | ||||
Radio Engineers Volume 40, Number 9, pp. 1098-1101, | ||||
September 1952, <https://ieeexplore.ieee.org/xpl/ | ||||
articleDetails.jsp?arnumber=4051119>. | ||||
[ORIGIN] Barth, A., "The Web Origin Concept", RFC 6454, | ||||
December 2011. | ||||
[PETAL] Tan, J. and J. Nahata, "PETAL: Preset Encoding Table | ||||
Information Leakage", April 2013, <http:// | ||||
www.pdl.cmu.edu/PDL-FTP/associated/ | ||||
CMU-PDL-13-106.pdf>. | ||||
[SPDY] Belshe, M. and R. Peon, "SPDY Protocol", | ||||
draft-mbelshe-httpbis-spdy-00 (work in progress), | ||||
February 2012. | ||||
[SPDY-DESC-1] Belshe, M., "IETF83: SPDY and What to Consider for | ||||
HTTP/2.0", March 2012, <https://www.ietf.org/ | ||||
proceedings/83/slides/slides-83-httpbis-3>. | ||||
[SPDY-DESC-2] McManus, P., "SPDY: What I Like About You", | ||||
September 2011, <https://bitsup.blogspot.com/2011/09/ | ||||
spdy-what-i-like-about-you.html>. | ||||
Appendix A. Change Log (to be removed by RFC Editor before publication) | ||||
A.1. Since draft-ietf-httpbis-header-compression-08 | ||||
o Removed the reference set. | ||||
o Removed header emission. | ||||
o Explicit handling of several SETTINGS_HEADER_TABLE_SIZE parameter | ||||
changes. | ||||
o Changed header set to header list, and forced ordering. | ||||
o Updated examples. | ||||
o Exchanged header and static table positions. | ||||
A.2. Since draft-ietf-httpbis-header-compression-07 | ||||
o Removed old text on index value of 0. | ||||
o Added clarification for signalling of maximum table size after a | ||||
SETTINGS_HEADER_TABLE_SIZE update. | ||||
o Rewrote security considerations. | ||||
o Many editorial clarifications or improvements. | ||||
o Added convention section. | ||||
o Reworked document's outline. | ||||
o Updated static table. Entry 16 has now "gzip, deflate" for value. | ||||
o Updated Huffman table, using data set provided by Google. | ||||
A.3. Since draft-ietf-httpbis-header-compression-06 | ||||
o Updated format to include literal headers that must never be | ||||
compressed. | ||||
o Updated security considerations. | ||||
o Moved integer encoding examples to the appendix. | ||||
o Updated Huffman table. | ||||
o Updated static header table (adding and removing status values). | ||||
o Updated examples. | ||||
A.4. Since draft-ietf-httpbis-header-compression-05 | ||||
o Regenerated examples. | ||||
o Only one Huffman table for requests and responses. | ||||
o Added maximum size for header table, independent of | ||||
SETTINGS_HEADER_TABLE_SIZE. | ||||
o Added pseudo-code for integer decoding. | ||||
o Improved examples (removing unnecessary removals). | ||||
A.5. Since draft-ietf-httpbis-header-compression-04 | ||||
o Updated examples: take into account changes in the spec, and show | ||||
more features. | ||||
o Use 'octet' everywhere instead of having both 'byte' and 'octet'. | ||||
o Added reference set emptying. | ||||
o Editorial changes and clarifications. | ||||
o Added "host" header to the static table. | ||||
o Ordering for list of values (either NULL- or comma-separated). | ||||
A.6. Since draft-ietf-httpbis-header-compression-03 | ||||
o A large number of editorial changes; changed the description of | ||||
evicting/adding new entries. | ||||
o Removed substitution indexing | ||||
o Changed 'initial headers' to 'static headers', as per issue #258 | ||||
o Merged 'request' and 'response' static headers, as per issue #259 | ||||
o Changed text to indicate that new headers are added at index 0 and | ||||
expire from the largest index, as per issue #233 | ||||
A.7. Since draft-ietf-httpbis-header-compression-02 | ||||
o Corrected error in integer encoding pseudocode. | ||||
A.8. Since draft-ietf-httpbis-header-compression-01 | ||||
o Refactored of Header Encoding Section: split definitions and | ||||
processing rule. | ||||
o Backward incompatible change: Updated reference set management as | 8. References | |||
per issue #214. This changes how the interaction between the | ||||
reference set and eviction works. This also changes the working | ||||
of the reference set in some specific cases. | ||||
o Backward incompatible change: modified initial header list, as per | 8.1. Normative References | |||
issue #188. | ||||
o Added example of 32 octets entry structure (issue #191). | [HTTP2] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | |||
Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | ||||
DOI 10.17487/RFC7540, May 2015, | ||||
<https://www.rfc-editor.org/info/rfc7540>. | ||||
o Added Header Set Completion section. Reflowed some text. | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
Clarified some writing which was akward. Added text about | Requirement Levels", BCP 14, RFC 2119, | |||
duplicate header entry encoding. Clarified some language w.r.t | DOI 10.17487/RFC2119, March 1997, | |||
Header Set. Changed x-my-header to mynewheader. Added text in the | <https://www.rfc-editor.org/info/rfc2119>. | |||
HeaderEmission section indicating that the application may also be | ||||
able to free up memory more quickly. Added information in | ||||
Security Considerations section. | ||||
A.9. Since draft-ietf-httpbis-header-compression-00 | [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
Protocol (HTTP/1.1): Message Syntax and Routing", | ||||
RFC 7230, DOI 10.17487/RFC7230, June 2014, | ||||
<https://www.rfc-editor.org/info/rfc7230>. | ||||
Fixed bug/omission in integer representation algorithm. | 8.2. Informative References | |||
Changed the document title. | [CANONICAL] | |||
Schwartz, E. and B. Kallick, "Generating a canonical | ||||
prefix encoding", Communications of the ACM, Volume 7 | ||||
Issue 3, pp. 166-169, March 1964, | ||||
<https://dl.acm.org/citation.cfm?id=363991>. | ||||
Header matching text rewritten. | [CRIME] Wikipedia, "CRIME", May 2015, <http://en.wikipedia.org/w/ | |||
index.php?title=CRIME&oldid=660948120>. | ||||
Changed the definition of header emission. | [DEFLATE] Deutsch, P., "DEFLATE Compressed Data Format Specification | |||
version 1.3", RFC 1951, DOI 10.17487/RFC1951, May 1996, | ||||
<https://www.rfc-editor.org/info/rfc1951>. | ||||
Changed the name of the setting which dictates how much memory the | [HUFFMAN] Huffman, D., "A Method for the Construction of Minimum- | |||
compression context should use. | Redundancy Codes", Proceedings of the Institute of Radio | |||
Engineers, Volume 40, Number 9, pp. 1098-1101, September | ||||
1952, <http://ieeexplore.ieee.org/xpl/ | ||||
articleDetails.jsp?arnumber=4051119>. | ||||
Removed "specific use cases" section | [ORIGIN] Barth, A., "The Web Origin Concept", RFC 6454, | |||
DOI 10.17487/RFC6454, December 2011, | ||||
<https://www.rfc-editor.org/info/rfc6454>. | ||||
Corrected erroneous statement about what index can be contained in | [PETAL] Tan, J. and J. Nahata, "PETAL: Preset Encoding | |||
one octet | Table Information Leakage", April 2013, | |||
<http://www.pdl.cmu.edu/PDL-FTP/associated/CMU-PDL- | ||||
13-106.pdf>. | ||||
Added descriptions of opcodes | [SPDY] Belshe, M. and R. Peon, "SPDY Protocol", draft-mbelshe- | |||
httpbis-spdy-00 (work in progress), February 2012. | ||||
Removed security claims from introduction. | [TLS12] Dierks, T. and E. Rescorla, "The Transport Layer Security | |||
(TLS) Protocol Version 1.2", RFC 5246, | ||||
DOI 10.17487/RFC5246, August 2008, | ||||
<https://www.rfc-editor.org/info/rfc5246>. | ||||
Appendix B. Static Table | Appendix A. Static Table Definition | |||
The static table consists of an unchangeable ordered list of (name, | The static table (see Section 2.3.1) consists in a predefined and | |||
value) pairs. The first entry in the table is always represented by | unchangeable list of header fields. | |||
the index len(header table) + 1, and the last entry in the table is | ||||
represented by the index len(header table) + len(static table). | ||||
The static table was created by listing the most common header fields | The static table was created from the most frequent header fields | |||
that are valid for messages exchanged inside a HTTP/2 connection. | used by popular web sites, with the addition of HTTP/2-specific | |||
For header fields with a few frequent values, an entry was added for | pseudo-header fields (see Section 8.1.2.1 of [HTTP2]). For header | |||
each of these frequent values. For other header fields, an entry was | fields with a few frequent values, an entry was added for each of | |||
added with an empty value. | these frequent values. For other header fields, an entry was added | |||
with an empty value. | ||||
The following table lists the pre-defined header fields that make-up | Table 1 lists the predefined header fields that make up the static | |||
the static table. | table and gives the index of each entry. | |||
+-------+-----------------------------+---------------+ | +-------+-----------------------------+---------------+ | |||
| Index | Header Name | Header Value | | | Index | Header Name | Header Value | | |||
+-------+-----------------------------+---------------+ | +-------+-----------------------------+---------------+ | |||
| 1 | :authority | | | | 1 | :authority | | | |||
| 2 | :method | GET | | | 2 | :method | GET | | |||
| 3 | :method | POST | | | 3 | :method | POST | | |||
| 4 | :path | / | | | 4 | :path | / | | |||
| 5 | :path | /index.html | | | 5 | :path | /index.html | | |||
| 6 | :scheme | http | | | 6 | :scheme | http | | |||
skipping to change at page 27, line 24 ¶ | skipping to change at page 25, line 39 ¶ | |||
| 56 | strict-transport-security | | | | 56 | strict-transport-security | | | |||
| 57 | transfer-encoding | | | | 57 | transfer-encoding | | | |||
| 58 | user-agent | | | | 58 | user-agent | | | |||
| 59 | vary | | | | 59 | vary | | | |||
| 60 | via | | | | 60 | via | | | |||
| 61 | www-authenticate | | | | 61 | www-authenticate | | | |||
+-------+-----------------------------+---------------+ | +-------+-----------------------------+---------------+ | |||
Table 1: Static Table Entries | Table 1: Static Table Entries | |||
Table 1 gives the index of each entry in the static table. The full | Appendix B. Huffman Code | |||
index of each entry, to be used for encoding a reference to this | ||||
entry, is computed by adding the number of entries in the header | ||||
table to this index. | ||||
Appendix C. Huffman Code | ||||
The following Huffman code is used when encoding string literals with | The following Huffman code is used when encoding string literals with | |||
a Huffman coding (see Section 6.2). | a Huffman coding (see Section 5.2). | |||
This Huffman code was generated from statistics obtained on a large | This Huffman code was generated from statistics obtained on a large | |||
sample of HTTP headers. It is a canonical Huffman code (see | sample of HTTP headers. It is a canonical Huffman code (see | |||
[CANONICAL]) with some tweaking to ensure that no symbol has a unique | [CANONICAL]) with some tweaking to ensure that no symbol has a unique | |||
code length. | code length. | |||
Each row in the table defines the code used to represent a symbol: | Each row in the table defines the code used to represent a symbol: | |||
sym: The symbol to be represented. It is the decimal value of an | sym: The symbol to be represented. It is the decimal value of an | |||
octet, possibly prepended with its ASCII representation. A | octet, possibly prepended with its ASCII representation. A | |||
skipping to change at page 28, line 12 ¶ | skipping to change at page 26, line 20 ¶ | |||
code as bits: The Huffman code for the symbol represented as a | code as bits: The Huffman code for the symbol represented as a | |||
base-2 integer, aligned on the most significant bit (MSB). | base-2 integer, aligned on the most significant bit (MSB). | |||
code as hex: The Huffman code for the symbol, represented as a | code as hex: The Huffman code for the symbol, represented as a | |||
hexadecimal integer, aligned on the least significant bit (LSB). | hexadecimal integer, aligned on the least significant bit (LSB). | |||
len: The number of bits for the code representing the symbol. | len: The number of bits for the code representing the symbol. | |||
As an example, the code for the symbol 47 (corresponding to the ASCII | As an example, the code for the symbol 47 (corresponding to the ASCII | |||
character "/") consists in the 6 bits "0", "1", "1", "0", "0", "0". | character "/") consists in the 6 bits "0", "1", "1", "0", "0", "0". | |||
This corresponds to the value 0x18 (in hexadecimal) encoded on 6 | This corresponds to the value 0x18 (in hexadecimal) encoded in 6 | |||
bits. | bits. | |||
code | code | |||
code as bits as hex len | code as bits as hex len | |||
sym aligned to MSB aligned in | sym aligned to MSB aligned in | |||
to LSB bits | to LSB bits | |||
( 0) |11111111|11000 1ff8 [13] | ( 0) |11111111|11000 1ff8 [13] | |||
( 1) |11111111|11111111|1011000 7fffd8 [23] | ( 1) |11111111|11111111|1011000 7fffd8 [23] | |||
( 2) |11111111|11111111|11111110|0010 fffffe2 [28] | ( 2) |11111111|11111111|11111110|0010 fffffe2 [28] | |||
( 3) |11111111|11111111|11111110|0011 fffffe3 [28] | ( 3) |11111111|11111111|11111110|0011 fffffe3 [28] | |||
( 4) |11111111|11111111|11111110|0100 fffffe4 [28] | ( 4) |11111111|11111111|11111110|0100 fffffe4 [28] | |||
( 5) |11111111|11111111|11111110|0101 fffffe5 [28] | ( 5) |11111111|11111111|11111110|0101 fffffe5 [28] | |||
( 6) |11111111|11111111|11111110|0110 fffffe6 [28] | ( 6) |11111111|11111111|11111110|0110 fffffe6 [28] | |||
( 7) |11111111|11111111|11111110|0111 fffffe7 [28] | ( 7) |11111111|11111111|11111110|0111 fffffe7 [28] | |||
( 8) |11111111|11111111|11111110|1000 fffffe8 [28] | ( 8) |11111111|11111111|11111110|1000 fffffe8 [28] | |||
( 9) |11111111|11111111|11101010 ffffea [24] | ( 9) |11111111|11111111|11101010 ffffea [24] | |||
skipping to change at page 33, line 36 ¶ | skipping to change at page 31, line 44 ¶ | |||
(248) |11111111|11111111|11111101|011 7ffffeb [27] | (248) |11111111|11111111|11111101|011 7ffffeb [27] | |||
(249) |11111111|11111111|11111111|1110 ffffffe [28] | (249) |11111111|11111111|11111111|1110 ffffffe [28] | |||
(250) |11111111|11111111|11111101|100 7ffffec [27] | (250) |11111111|11111111|11111101|100 7ffffec [27] | |||
(251) |11111111|11111111|11111101|101 7ffffed [27] | (251) |11111111|11111111|11111101|101 7ffffed [27] | |||
(252) |11111111|11111111|11111101|110 7ffffee [27] | (252) |11111111|11111111|11111101|110 7ffffee [27] | |||
(253) |11111111|11111111|11111101|111 7ffffef [27] | (253) |11111111|11111111|11111101|111 7ffffef [27] | |||
(254) |11111111|11111111|11111110|000 7fffff0 [27] | (254) |11111111|11111111|11111110|000 7fffff0 [27] | |||
(255) |11111111|11111111|11111011|10 3ffffee [26] | (255) |11111111|11111111|11111011|10 3ffffee [26] | |||
EOS (256) |11111111|11111111|11111111|111111 3fffffff [30] | EOS (256) |11111111|11111111|11111111|111111 3fffffff [30] | |||
Appendix D. Examples | Appendix C. Examples | |||
A number of examples are worked through here, covering integer | This appendix contains examples covering integer encoding, header | |||
encoding, header field representation, and the encoding of whole | field representation, and the encoding of whole lists of header | |||
lists of header fields, for both requests and responses, and with and | fields for both requests and responses, with and without Huffman | |||
without Huffman coding. | coding. | |||
D.1. Integer Representation Examples | C.1. Integer Representation Examples | |||
This section shows the representation of integer values in details | This section shows the representation of integer values in detail | |||
(see Section 6.1). | (see Section 5.1). | |||
D.1.1. Example 1: Encoding 10 Using a 5-bit Prefix | C.1.1. Example 1: Encoding 10 Using a 5-Bit Prefix | |||
The value 10 is to be encoded with a 5-bit prefix. | The value 10 is to be encoded with a 5-bit prefix. | |||
o 10 is less than 31 (2^5 - 1) and is represented using the 5-bit | o 10 is less than 31 (2^5 - 1) and is represented using the 5-bit | |||
prefix. | prefix. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| X | X | X | 0 | 1 | 0 | 1 | 0 | 10 stored on 5 bits | | X | X | X | 0 | 1 | 0 | 1 | 0 | 10 stored on 5 bits | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
D.1.2. Example 2: Encoding 1337 Using a 5-bit Prefix | C.1.2. Example 2: Encoding 1337 Using a 5-Bit Prefix | |||
The value I=1337 is to be encoded with a 5-bit prefix. | The value I=1337 is to be encoded with a 5-bit prefix. | |||
1337 is greater than 31 (2^5 - 1). | 1337 is greater than 31 (2^5 - 1). | |||
The 5-bit prefix is filled with its max value (31). | The 5-bit prefix is filled with its max value (31). | |||
I = 1337 - (2^5 - 1) = 1306. | I = 1337 - (2^5 - 1) = 1306. | |||
I (1306) is greater than or equal to 128, the while loop body | I (1306) is greater than or equal to 128, so the while loop | |||
executes: | body executes: | |||
I % 128 == 26 | I % 128 == 26 | |||
26 + 128 == 154 | 26 + 128 == 154 | |||
154 is encoded in 8 bits as: 10011010 | 154 is encoded in 8 bits as: 10011010 | |||
I is set to 10 (1306 / 128 == 10) | I is set to 10 (1306 / 128 == 10) | |||
I is no longer greater than or equal to 128, the while loop | I is no longer greater than or equal to 128, so the while | |||
terminates. | loop terminates. | |||
I, now 10, is encoded on 8 bits as: 00001010. | I, now 10, is encoded in 8 bits as: 00001010. | |||
The process ends. | The process ends. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| X | X | X | 1 | 1 | 1 | 1 | 1 | Prefix = 31, I = 1306 | | X | X | X | 1 | 1 | 1 | 1 | 1 | Prefix = 31, I = 1306 | |||
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1306>=128, encode(154), I=1306/128 | | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1306>=128, encode(154), I=1306/128 | |||
| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 10<128, encode(10), done | | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 10<128, encode(10), done | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
D.1.3. Example 3: Encoding 42 Starting at an Octet Boundary | C.1.3. Example 3: Encoding 42 Starting at an Octet Boundary | |||
The value 42 is to be encoded starting at an octet-boundary. This | The value 42 is to be encoded starting at an octet boundary. This | |||
implies that a 8-bit prefix is used. | implies that a 8-bit prefix is used. | |||
o 42 is less than 255 (2^8 - 1) and is represented using the 8-bit | o 42 is less than 255 (2^8 - 1) and is represented using the 8-bit | |||
prefix. | prefix. | |||
0 1 2 3 4 5 6 7 | 0 1 2 3 4 5 6 7 | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
| 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 42 stored on 8 bits | | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 42 stored on 8 bits | |||
+---+---+---+---+---+---+---+---+ | +---+---+---+---+---+---+---+---+ | |||
D.2. Header Field Representation Examples | C.2. Header Field Representation Examples | |||
This section shows several independent representation examples. | This section shows several independent representation examples. | |||
D.2.1. Literal Header Field with Indexing | C.2.1. Literal Header Field with Indexing | |||
The header field representation uses a literal name and a literal | The header field representation uses a literal name and a literal | |||
value. The header field is added to the header table. | value. The header field is added to the dynamic table. | |||
Header list to encode: | Header list to encode: | |||
custom-key: custom-header | custom-key: custom-header | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
400a 6375 7374 6f6d 2d6b 6579 0d63 7573 | @.custom-key.cus | 400a 6375 7374 6f6d 2d6b 6579 0d63 7573 | @.custom-key.cus | |||
746f 6d2d 6865 6164 6572 | tom-header | 746f 6d2d 6865 6164 6572 | tom-header | |||
Decoding process: | Decoding process: | |||
40 | == Literal indexed == | 40 | == Literal indexed == | |||
0a | Literal name (len = 10) | 0a | Literal name (len = 10) | |||
6375 7374 6f6d 2d6b 6579 | custom-key | 6375 7374 6f6d 2d6b 6579 | custom-key | |||
0d | Literal value (len = 13) | 0d | Literal value (len = 13) | |||
6375 7374 6f6d 2d68 6561 6465 72 | custom-header | 6375 7374 6f6d 2d68 6561 6465 72 | custom-header | |||
| -> custom-key: custom-head\ | | -> custom-key: | |||
| er | | custom-header | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 55) custom-key: custom-header | [ 1] (s = 55) custom-key: custom-header | |||
Table size: 55 | Table size: 55 | |||
Decoded header list: | Decoded header list: | |||
custom-key: custom-header | custom-key: custom-header | |||
D.2.2. Literal Header Field without Indexing | C.2.2. Literal Header Field without Indexing | |||
The header field representation uses an indexed name and a literal | The header field representation uses an indexed name and a literal | |||
value. The header field is not added to the header table. | value. The header field is not added to the dynamic table. | |||
Header list to encode: | Header list to encode: | |||
:path: /sample/path | :path: /sample/path | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
040c 2f73 616d 706c 652f 7061 7468 | ../sample/path | 040c 2f73 616d 706c 652f 7061 7468 | ../sample/path | |||
Decoding process: | Decoding process: | |||
04 | == Literal not indexed == | 04 | == Literal not indexed == | |||
| Indexed name (idx = 4) | | Indexed name (idx = 4) | |||
| :path | | :path | |||
0c | Literal value (len = 12) | 0c | Literal value (len = 12) | |||
2f73 616d 706c 652f 7061 7468 | /sample/path | 2f73 616d 706c 652f 7061 7468 | /sample/path | |||
| -> :path: /sample/path | | -> :path: /sample/path | |||
Header table (after decoding): empty. | Dynamic table (after decoding): empty. | |||
Decoded header list: | Decoded header list: | |||
:path: /sample/path | :path: /sample/path | |||
D.2.3. Literal Header Field never Indexed | C.2.3. Literal Header Field Never Indexed | |||
The header field representation uses a literal name and a literal | The header field representation uses a literal name and a literal | |||
value. The header field is not added to the header table, and must | value. The header field is not added to the dynamic table and must | |||
use the same representation if re-encoded by an intermediary. | use the same representation if re-encoded by an intermediary. | |||
Header list to encode: | Header list to encode: | |||
password: secret | password: secret | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
1008 7061 7373 776f 7264 0673 6563 7265 | ..password.secre | 1008 7061 7373 776f 7264 0673 6563 7265 | ..password.secre | |||
74 | t | 74 | t | |||
Decoding process: | Decoding process: | |||
10 | == Literal never indexed == | 10 | == Literal never indexed == | |||
08 | Literal name (len = 8) | 08 | Literal name (len = 8) | |||
7061 7373 776f 7264 | password | 7061 7373 776f 7264 | password | |||
06 | Literal value (len = 6) | 06 | Literal value (len = 6) | |||
7365 6372 6574 | secret | 7365 6372 6574 | secret | |||
| -> password: secret | | -> password: secret | |||
Header table (after decoding): empty. | Dynamic table (after decoding): empty. | |||
Decoded header list: | Decoded header list: | |||
password: secret | password: secret | |||
D.2.4. Indexed Header Field | C.2.4. Indexed Header Field | |||
The header field representation uses an indexed header field, from | The header field representation uses an indexed header field from the | |||
the static table. | static table. | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
82 | . | 82 | . | |||
Decoding process: | Decoding process: | |||
82 | == Indexed - Add == | 82 | == Indexed - Add == | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
Header table (after decoding): empty. | Dynamic table (after decoding): empty. | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
D.3. Request Examples without Huffman Coding | C.3. Request Examples without Huffman Coding | |||
This section shows several consecutive header lists, corresponding to | This section shows several consecutive header lists, corresponding to | |||
HTTP requests, on the same connection. | HTTP requests, on the same connection. | |||
D.3.1. First Request | C.3.1. First Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 39, line 4 ¶ | skipping to change at page 36, line 29 ¶ | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
8286 8441 0f77 7777 2e65 7861 6d70 6c65 | ...A.www.example | 8286 8441 0f77 7777 2e65 7861 6d70 6c65 | ...A.www.example | |||
2e63 6f6d | .com | 2e63 6f6d | .com | |||
Decoding process: | Decoding process: | |||
82 | == Indexed - Add == | 82 | == Indexed - Add == | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
86 | == Indexed - Add == | 86 | == Indexed - Add == | |||
| idx = 6 | | idx = 6 | |||
| -> :scheme: http | | -> :scheme: http | |||
84 | == Indexed - Add == | 84 | == Indexed - Add == | |||
| idx = 4 | | idx = 4 | |||
| -> :path: / | | -> :path: / | |||
41 | == Literal indexed == | 41 | == Literal indexed == | |||
| Indexed name (idx = 1) | | Indexed name (idx = 1) | |||
| :authority | | :authority | |||
0f | Literal value (len = 15) | 0f | Literal value (len = 15) | |||
7777 772e 6578 616d 706c 652e 636f 6d | www.example.com | 7777 772e 6578 616d 706c 652e 636f 6d | www.example.com | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 57) :authority: www.example.com | [ 1] (s = 57) :authority: www.example.com | |||
Table size: 57 | Table size: 57 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
D.3.2. Second Request | C.3.2. Second Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
cache-control: no-cache | cache-control: no-cache | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 40, line 4 ¶ | skipping to change at page 37, line 25 ¶ | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
cache-control: no-cache | cache-control: no-cache | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
8286 84be 5808 6e6f 2d63 6163 6865 | ....X.no-cache | 8286 84be 5808 6e6f 2d63 6163 6865 | ....X.no-cache | |||
Decoding process: | Decoding process: | |||
82 | == Indexed - Add == | 82 | == Indexed - Add == | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
86 | == Indexed - Add == | 86 | == Indexed - Add == | |||
| idx = 6 | | idx = 6 | |||
| -> :scheme: http | | -> :scheme: http | |||
84 | == Indexed - Add == | 84 | == Indexed - Add == | |||
| idx = 4 | | idx = 4 | |||
| -> :path: / | | -> :path: / | |||
be | == Indexed - Add == | be | == Indexed - Add == | |||
| idx = 62 | | idx = 62 | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
58 | == Literal indexed == | 58 | == Literal indexed == | |||
| Indexed name (idx = 24) | | Indexed name (idx = 24) | |||
| cache-control | | cache-control | |||
08 | Literal value (len = 8) | 08 | Literal value (len = 8) | |||
6e6f 2d63 6163 6865 | no-cache | 6e6f 2d63 6163 6865 | no-cache | |||
| -> cache-control: no-cache | | -> cache-control: no-cache | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 53) cache-control: no-cache | [ 1] (s = 53) cache-control: no-cache | |||
[ 2] (s = 57) :authority: www.example.com | [ 2] (s = 57) :authority: www.example.com | |||
Table size: 110 | Table size: 110 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
cache-control: no-cache | cache-control: no-cache | |||
D.3.3. Third Request | C.3.3. Third Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: https | :scheme: https | |||
:path: /index.html | :path: /index.html | |||
:authority: www.example.com | :authority: www.example.com | |||
custom-key: custom-value | custom-key: custom-value | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
8287 85bf 400a 6375 7374 6f6d 2d6b 6579 | ....@.custom-key | 8287 85bf 400a 6375 7374 6f6d 2d6b 6579 | ....@.custom-key | |||
0c63 7573 746f 6d2d 7661 6c75 65 | .custom-value | 0c63 7573 746f 6d2d 7661 6c75 65 | .custom-value | |||
Decoding process: | Decoding process: | |||
82 | == Indexed - Add == | 82 | == Indexed - Add == | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
87 | == Indexed - Add == | 87 | == Indexed - Add == | |||
| idx = 7 | | idx = 7 | |||
| -> :scheme: https | | -> :scheme: https | |||
85 | == Indexed - Add == | 85 | == Indexed - Add == | |||
| idx = 5 | | idx = 5 | |||
| -> :path: /index.html | | -> :path: /index.html | |||
bf | == Indexed - Add == | bf | == Indexed - Add == | |||
| idx = 63 | | idx = 63 | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
40 | == Literal indexed == | 40 | == Literal indexed == | |||
0a | Literal name (len = 10) | 0a | Literal name (len = 10) | |||
6375 7374 6f6d 2d6b 6579 | custom-key | 6375 7374 6f6d 2d6b 6579 | custom-key | |||
0c | Literal value (len = 12) | 0c | Literal value (len = 12) | |||
6375 7374 6f6d 2d76 616c 7565 | custom-value | 6375 7374 6f6d 2d76 616c 7565 | custom-value | |||
| -> custom-key: custom-valu\ | | -> custom-key: | |||
| e | | custom-value | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 54) custom-key: custom-value | [ 1] (s = 54) custom-key: custom-value | |||
[ 2] (s = 53) cache-control: no-cache | [ 2] (s = 53) cache-control: no-cache | |||
[ 3] (s = 57) :authority: www.example.com | [ 3] (s = 57) :authority: www.example.com | |||
Table size: 164 | Table size: 164 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: https | :scheme: https | |||
:path: /index.html | :path: /index.html | |||
:authority: www.example.com | :authority: www.example.com | |||
custom-key: custom-value | custom-key: custom-value | |||
D.4. Request Examples with Huffman Coding | C.4. Request Examples with Huffman Coding | |||
This section shows the same examples as the previous section, but | This section shows the same examples as the previous section but uses | |||
using Huffman encoding for the literal values. | Huffman encoding for the literal values. | |||
D.4.1. First Request | C.4.1. First Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 42, line 38 ¶ | skipping to change at page 40, line 24 ¶ | |||
| idx = 4 | | idx = 4 | |||
| -> :path: / | | -> :path: / | |||
41 | == Literal indexed == | 41 | == Literal indexed == | |||
| Indexed name (idx = 1) | | Indexed name (idx = 1) | |||
| :authority | | :authority | |||
8c | Literal value (len = 12) | 8c | Literal value (len = 12) | |||
| Huffman encoded: | | Huffman encoded: | |||
f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | f1e3 c2e5 f23a 6ba0 ab90 f4ff | .....:k..... | |||
| Decoded: | | Decoded: | |||
| www.example.com | | www.example.com | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 57) :authority: www.example.com | [ 1] (s = 57) :authority: www.example.com | |||
Table size: 57 | Table size: 57 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
D.4.2. Second Request | C.4.2. Second Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
cache-control: no-cache | cache-control: no-cache | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 43, line 32 ¶ | skipping to change at page 41, line 18 ¶ | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
86 | == Indexed - Add == | 86 | == Indexed - Add == | |||
| idx = 6 | | idx = 6 | |||
| -> :scheme: http | | -> :scheme: http | |||
84 | == Indexed - Add == | 84 | == Indexed - Add == | |||
| idx = 4 | | idx = 4 | |||
| -> :path: / | | -> :path: / | |||
be | == Indexed - Add == | be | == Indexed - Add == | |||
| idx = 62 | | idx = 62 | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
58 | == Literal indexed == | 58 | == Literal indexed == | |||
| Indexed name (idx = 24) | | Indexed name (idx = 24) | |||
| cache-control | | cache-control | |||
86 | Literal value (len = 6) | 86 | Literal value (len = 6) | |||
| Huffman encoded: | | Huffman encoded: | |||
a8eb 1064 9cbf | ...d.. | a8eb 1064 9cbf | ...d.. | |||
| Decoded: | | Decoded: | |||
| no-cache | | no-cache | |||
| -> cache-control: no-cache | | -> cache-control: no-cache | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 53) cache-control: no-cache | [ 1] (s = 53) cache-control: no-cache | |||
[ 2] (s = 57) :authority: www.example.com | [ 2] (s = 57) :authority: www.example.com | |||
Table size: 110 | Table size: 110 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: http | :scheme: http | |||
:path: / | :path: / | |||
:authority: www.example.com | :authority: www.example.com | |||
cache-control: no-cache | cache-control: no-cache | |||
D.4.3. Third Request | C.4.3. Third Request | |||
Header list to encode: | Header list to encode: | |||
:method: GET | :method: GET | |||
:scheme: https | :scheme: https | |||
:path: /index.html | :path: /index.html | |||
:authority: www.example.com | :authority: www.example.com | |||
custom-key: custom-value | custom-key: custom-value | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 | ....@.%.I.[.}..% | 8287 85bf 4088 25a8 49e9 5ba9 7d7f 8925 | ....@.%.I.[.}..% | |||
a849 e95b b8e8 b4bf | .I.[.... | a849 e95b b8e8 b4bf | .I.[.... | |||
Decoding process: | Decoding process: | |||
82 | == Indexed - Add == | 82 | == Indexed - Add == | |||
| idx = 2 | | idx = 2 | |||
| -> :method: GET | | -> :method: GET | |||
87 | == Indexed - Add == | 87 | == Indexed - Add == | |||
| idx = 7 | | idx = 7 | |||
| -> :scheme: https | | -> :scheme: https | |||
85 | == Indexed - Add == | 85 | == Indexed - Add == | |||
| idx = 5 | | idx = 5 | |||
| -> :path: /index.html | | -> :path: /index.html | |||
bf | == Indexed - Add == | bf | == Indexed - Add == | |||
| idx = 63 | | idx = 63 | |||
| -> :authority: www.example\ | | -> :authority: | |||
| .com | | www.example.com | |||
40 | == Literal indexed == | 40 | == Literal indexed == | |||
88 | Literal name (len = 8) | 88 | Literal name (len = 8) | |||
| Huffman encoded: | | Huffman encoded: | |||
25a8 49e9 5ba9 7d7f | %.I.[.}. | 25a8 49e9 5ba9 7d7f | %.I.[.}. | |||
| Decoded: | | Decoded: | |||
| custom-key | | custom-key | |||
89 | Literal value (len = 9) | 89 | Literal value (len = 9) | |||
| Huffman encoded: | | Huffman encoded: | |||
25a8 49e9 5bb8 e8b4 bf | %.I.[.... | 25a8 49e9 5bb8 e8b4 bf | %.I.[.... | |||
| Decoded: | | Decoded: | |||
| custom-value | | custom-value | |||
| -> custom-key: custom-valu\ | | -> custom-key: | |||
| e | | custom-value | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 54) custom-key: custom-value | [ 1] (s = 54) custom-key: custom-value | |||
[ 2] (s = 53) cache-control: no-cache | [ 2] (s = 53) cache-control: no-cache | |||
[ 3] (s = 57) :authority: www.example.com | [ 3] (s = 57) :authority: www.example.com | |||
Table size: 164 | Table size: 164 | |||
Decoded header list: | Decoded header list: | |||
:method: GET | :method: GET | |||
:scheme: https | :scheme: https | |||
:path: /index.html | :path: /index.html | |||
:authority: www.example.com | :authority: www.example.com | |||
custom-key: custom-value | custom-key: custom-value | |||
D.5. Response Examples without Huffman Coding | C.5. Response Examples without Huffman Coding | |||
This section shows several consecutive header lists, corresponding to | This section shows several consecutive header lists, corresponding to | |||
HTTP responses, on the same connection. The HTTP/2 setting parameter | HTTP responses, on the same connection. The HTTP/2 setting parameter | |||
SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing | SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 octets, causing | |||
some evictions to occur. | some evictions to occur. | |||
D.5.1. First Response | C.5.1. First Response | |||
Header list to encode: | Header list to encode: | |||
:status: 302 | :status: 302 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 47, line 24 ¶ | skipping to change at page 44, line 24 ¶ | |||
| cache-control | | cache-control | |||
07 | Literal value (len = 7) | 07 | Literal value (len = 7) | |||
7072 6976 6174 65 | private | 7072 6976 6174 65 | private | |||
| -> cache-control: private | | -> cache-control: private | |||
61 | == Literal indexed == | 61 | == Literal indexed == | |||
| Indexed name (idx = 33) | | Indexed name (idx = 33) | |||
| date | | date | |||
1d | Literal value (len = 29) | 1d | Literal value (len = 29) | |||
4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013 | 4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013 | |||
2032 303a 3133 3a32 3120 474d 54 | 20:13:21 GMT | 2032 303a 3133 3a32 3120 474d 54 | 20:13:21 GMT | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:21 GMT | | 20:13:21 GMT | |||
6e | == Literal indexed == | 6e | == Literal indexed == | |||
| Indexed name (idx = 46) | | Indexed name (idx = 46) | |||
| location | | location | |||
17 | Literal value (len = 23) | 17 | Literal value (len = 23) | |||
6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam | 6874 7470 733a 2f2f 7777 772e 6578 616d | https://www.exam | |||
706c 652e 636f 6d | ple.com | 706c 652e 636f 6d | ple.com | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 63) location: https://www.example.com | [ 1] (s = 63) location: https://www.example.com | |||
[ 2] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | [ 2] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | |||
[ 3] (s = 52) cache-control: private | [ 3] (s = 52) cache-control: private | |||
[ 4] (s = 42) :status: 302 | [ 4] (s = 42) :status: 302 | |||
Table size: 222 | Table size: 222 | |||
Decoded header list: | Decoded header list: | |||
:status: 302 | :status: 302 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
D.5.2. Second Response | C.5.2. Second Response | |||
The (":status", "302") header field is evicted from the header table | The (":status", "302") header field is evicted from the dynamic table | |||
to free space to allow adding the (":status", "307") header field. | to free space to allow adding the (":status", "307") header field. | |||
Header list to encode: | Header list to encode: | |||
:status: 307 | :status: 307 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 48, line 35 ¶ | skipping to change at page 45, line 35 ¶ | |||
| :status | | :status | |||
03 | Literal value (len = 3) | 03 | Literal value (len = 3) | |||
3330 37 | 307 | 3330 37 | 307 | |||
| - evict: :status: 302 | | - evict: :status: 302 | |||
| -> :status: 307 | | -> :status: 307 | |||
c1 | == Indexed - Add == | c1 | == Indexed - Add == | |||
| idx = 65 | | idx = 65 | |||
| -> cache-control: private | | -> cache-control: private | |||
c0 | == Indexed - Add == | c0 | == Indexed - Add == | |||
| idx = 64 | | idx = 64 | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:21 GMT | | 20:13:21 GMT | |||
bf | == Indexed - Add == | bf | == Indexed - Add == | |||
| idx = 63 | | idx = 63 | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 42) :status: 307 | [ 1] (s = 42) :status: 307 | |||
[ 2] (s = 63) location: https://www.example.com | [ 2] (s = 63) location: https://www.example.com | |||
[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | [ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | |||
[ 4] (s = 52) cache-control: private | [ 4] (s = 52) cache-control: private | |||
Table size: 222 | Table size: 222 | |||
Decoded header list: | Decoded header list: | |||
:status: 307 | :status: 307 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
D.5.3. Third Response | C.5.3. Third Response | |||
Several header fields are evicted from the header table during the | Several header fields are evicted from the dynamic table during the | |||
processing of this header list. | processing of this header list. | |||
Header list to encode: | Header list to encode: | |||
:status: 200 | :status: 200 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:22 GMT | date: Mon, 21 Oct 2013 20:13:22 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
content-encoding: gzip | content-encoding: gzip | |||
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | |||
skipping to change at page 50, line 18 ¶ | skipping to change at page 47, line 18 ¶ | |||
| -> :status: 200 | | -> :status: 200 | |||
c1 | == Indexed - Add == | c1 | == Indexed - Add == | |||
| idx = 65 | | idx = 65 | |||
| -> cache-control: private | | -> cache-control: private | |||
61 | == Literal indexed == | 61 | == Literal indexed == | |||
| Indexed name (idx = 33) | | Indexed name (idx = 33) | |||
| date | | date | |||
1d | Literal value (len = 29) | 1d | Literal value (len = 29) | |||
4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013 | 4d6f 6e2c 2032 3120 4f63 7420 3230 3133 | Mon, 21 Oct 2013 | |||
2032 303a 3133 3a32 3220 474d 54 | 20:13:22 GMT | 2032 303a 3133 3a32 3220 474d 54 | 20:13:22 GMT | |||
| - evict: cache-control: pr\ | | - evict: cache-control: | |||
| ivate | | private | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:22 GMT | | 20:13:22 GMT | |||
c0 | == Indexed - Add == | c0 | == Indexed - Add == | |||
| idx = 64 | | idx = 64 | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
5a | == Literal indexed == | 5a | == Literal indexed == | |||
| Indexed name (idx = 26) | | Indexed name (idx = 26) | |||
| content-encoding | | content-encoding | |||
04 | Literal value (len = 4) | 04 | Literal value (len = 4) | |||
677a 6970 | gzip | 677a 6970 | gzip | |||
| - evict: date: Mon, 21 Oct\ | | - evict: date: Mon, 21 Oct | |||
| 2013 20:13:21 GMT | | 2013 20:13:21 GMT | |||
| -> content-encoding: gzip | | -> content-encoding: gzip | |||
77 | == Literal indexed == | 77 | == Literal indexed == | |||
| Indexed name (idx = 55) | | Indexed name (idx = 55) | |||
| set-cookie | | set-cookie | |||
38 | Literal value (len = 56) | 38 | Literal value (len = 56) | |||
666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO | 666f 6f3d 4153 444a 4b48 514b 425a 584f | foo=ASDJKHQKBZXO | |||
5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU; | 5157 454f 5049 5541 5851 5745 4f49 553b | QWEOPIUAXQWEOIU; | |||
206d 6178 2d61 6765 3d33 3630 303b 2076 | max-age=3600; v | 206d 6178 2d61 6765 3d33 3630 303b 2076 | max-age=3600; v | |||
6572 7369 6f6e 3d31 | ersion=1 | 6572 7369 6f6e 3d31 | ersion=1 | |||
| - evict: location: https:/\ | | - evict: location: | |||
| /www.example.com | | https://www.example.com | |||
| - evict: :status: 307 | | - evict: :status: 307 | |||
| -> set-cookie: foo=ASDJKHQ\ | | -> set-cookie: foo=ASDJKHQ | |||
| KBZXOQWEOPIUAXQWEOIU; ma\ | | KBZXOQWEOPIUAXQWEOIU; ma | |||
| x-age=3600; version=1 | | x-age=3600; version=1 | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age\ | [ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; | |||
=3600; version=1 | max-age=3600; version=1 | |||
[ 2] (s = 52) content-encoding: gzip | [ 2] (s = 52) content-encoding: gzip | |||
[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT | [ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT | |||
Table size: 215 | Table size: 215 | |||
Decoded header list: | Decoded header list: | |||
:status: 200 | :status: 200 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:22 GMT | date: Mon, 21 Oct 2013 20:13:22 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
content-encoding: gzip | content-encoding: gzip | |||
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | |||
D.6. Response Examples with Huffman Coding | C.6. Response Examples with Huffman Coding | |||
This section shows the same examples as the previous section, but | This section shows the same examples as the previous section but uses | |||
using Huffman encoding for the literal values. The HTTP/2 setting | Huffman encoding for the literal values. The HTTP/2 setting | |||
parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 | parameter SETTINGS_HEADER_TABLE_SIZE is set to the value of 256 | |||
octets, causing some evictions to occur. The eviction mechanism uses | octets, causing some evictions to occur. The eviction mechanism uses | |||
the length of the decoded literal values, so the same evictions | the length of the decoded literal values, so the same evictions occur | |||
occurs as in the previous section. | as in the previous section. | |||
D.6.1. First Response | C.6.1. First Response | |||
Header list to encode: | Header list to encode: | |||
:status: 302 | :status: 302 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 52, line 33 ¶ | skipping to change at page 49, line 33 ¶ | |||
| private | | private | |||
| -> cache-control: private | | -> cache-control: private | |||
61 | == Literal indexed == | 61 | == Literal indexed == | |||
| Indexed name (idx = 33) | | Indexed name (idx = 33) | |||
| date | | date | |||
96 | Literal value (len = 22) | 96 | Literal value (len = 22) | |||
| Huffman encoded: | | Huffman encoded: | |||
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | |||
e082 a62d 1bff | ...-.. | e082 a62d 1bff | ...-.. | |||
| Decoded: | | Decoded: | |||
| Mon, 21 Oct 2013 20:13:21 \ | | Mon, 21 Oct 2013 20:13:21 | |||
| GMT | | GMT | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:21 GMT | | 20:13:21 GMT | |||
6e | == Literal indexed == | 6e | == Literal indexed == | |||
| Indexed name (idx = 46) | | Indexed name (idx = 46) | |||
| location | | location | |||
91 | Literal value (len = 17) | 91 | Literal value (len = 17) | |||
| Huffman encoded: | | Huffman encoded: | |||
9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C | 9d29 ad17 1863 c78f 0b97 c8e9 ae82 ae43 | .)...c.........C | |||
d3 | . | d3 | . | |||
| Decoded: | | Decoded: | |||
| https://www.example.com | | https://www.example.com | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 63) location: https://www.example.com | [ 1] (s = 63) location: https://www.example.com | |||
[ 2] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | [ 2] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | |||
[ 3] (s = 52) cache-control: private | [ 3] (s = 52) cache-control: private | |||
[ 4] (s = 42) :status: 302 | [ 4] (s = 42) :status: 302 | |||
Table size: 222 | Table size: 222 | |||
Decoded header list: | Decoded header list: | |||
:status: 302 | :status: 302 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
D.6.2. Second Response | C.6.2. Second Response | |||
The (":status", "302") header field is evicted from the header table | The (":status", "302") header field is evicted from the dynamic table | |||
to free space to allow adding the (":status", "307") header field. | to free space to allow adding the (":status", "307") header field. | |||
Header list to encode: | Header list to encode: | |||
:status: 307 | :status: 307 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
Hex dump of encoded data: | Hex dump of encoded data: | |||
skipping to change at page 54, line 22 ¶ | skipping to change at page 51, line 22 ¶ | |||
640e ff | d.. | 640e ff | d.. | |||
| Decoded: | | Decoded: | |||
| 307 | | 307 | |||
| - evict: :status: 302 | | - evict: :status: 302 | |||
| -> :status: 307 | | -> :status: 307 | |||
c1 | == Indexed - Add == | c1 | == Indexed - Add == | |||
| idx = 65 | | idx = 65 | |||
| -> cache-control: private | | -> cache-control: private | |||
c0 | == Indexed - Add == | c0 | == Indexed - Add == | |||
| idx = 64 | | idx = 64 | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:21 GMT | | 20:13:21 GMT | |||
bf | == Indexed - Add == | bf | == Indexed - Add == | |||
| idx = 63 | | idx = 63 | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 42) :status: 307 | [ 1] (s = 42) :status: 307 | |||
[ 2] (s = 63) location: https://www.example.com | [ 2] (s = 63) location: https://www.example.com | |||
[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | [ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:21 GMT | |||
[ 4] (s = 52) cache-control: private | [ 4] (s = 52) cache-control: private | |||
Table size: 222 | Table size: 222 | |||
Decoded header list: | Decoded header list: | |||
:status: 307 | :status: 307 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:21 GMT | date: Mon, 21 Oct 2013 20:13:21 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
D.6.3. Third Response | C.6.3. Third Response | |||
Several header fields are evicted from the header table during the | Several header fields are evicted from the dynamic table during the | |||
processing of this header list. | processing of this header list. | |||
Header list to encode: | Header list to encode: | |||
:status: 200 | :status: 200 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:22 GMT | date: Mon, 21 Oct 2013 20:13:22 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
content-encoding: gzip | content-encoding: gzip | |||
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | |||
skipping to change at page 55, line 38 ¶ | skipping to change at page 52, line 38 ¶ | |||
| idx = 65 | | idx = 65 | |||
| -> cache-control: private | | -> cache-control: private | |||
61 | == Literal indexed == | 61 | == Literal indexed == | |||
| Indexed name (idx = 33) | | Indexed name (idx = 33) | |||
| date | | date | |||
96 | Literal value (len = 22) | 96 | Literal value (len = 22) | |||
| Huffman encoded: | | Huffman encoded: | |||
d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | d07a be94 1054 d444 a820 0595 040b 8166 | .z...T.D. .....f | |||
e084 a62d 1bff | ...-.. | e084 a62d 1bff | ...-.. | |||
| Decoded: | | Decoded: | |||
| Mon, 21 Oct 2013 20:13:22 \ | | Mon, 21 Oct 2013 20:13:22 | |||
| GMT | | GMT | |||
| - evict: cache-control: pr\ | | - evict: cache-control: | |||
| ivate | | private | |||
| -> date: Mon, 21 Oct 2013 \ | | -> date: Mon, 21 Oct 2013 | |||
| 20:13:22 GMT | | 20:13:22 GMT | |||
c0 | == Indexed - Add == | c0 | == Indexed - Add == | |||
| idx = 64 | | idx = 64 | |||
| -> location: https://www.e\ | | -> location: | |||
| xample.com | | https://www.example.com | |||
5a | == Literal indexed == | 5a | == Literal indexed == | |||
| Indexed name (idx = 26) | | Indexed name (idx = 26) | |||
| content-encoding | | content-encoding | |||
83 | Literal value (len = 3) | 83 | Literal value (len = 3) | |||
| Huffman encoded: | | Huffman encoded: | |||
9bd9 ab | ... | 9bd9 ab | ... | |||
| Decoded: | | Decoded: | |||
| gzip | | gzip | |||
| - evict: date: Mon, 21 Oct\ | | - evict: date: Mon, 21 Oct | |||
| 2013 20:13:21 GMT | | 2013 20:13:21 GMT | |||
| -> content-encoding: gzip | | -> content-encoding: gzip | |||
77 | == Literal indexed == | 77 | == Literal indexed == | |||
| Indexed name (idx = 55) | | Indexed name (idx = 55) | |||
| set-cookie | | set-cookie | |||
ad | Literal value (len = 45) | ad | Literal value (len = 45) | |||
| Huffman encoded: | | Huffman encoded: | |||
94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` | 94e7 821d d7f2 e6c7 b335 dfdf cd5b 3960 | .........5...[9` | |||
d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... | d5af 2708 7f36 72c1 ab27 0fb5 291f 9587 | ..'..6r..'..)... | |||
3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. | 3160 65c0 03ed 4ee5 b106 3d50 07 | 1`e...N...=P. | |||
| Decoded: | | Decoded: | |||
| foo=ASDJKHQKBZXOQWEOPIUAXQ\ | | foo=ASDJKHQKBZXOQWEOPIUAXQ | |||
| WEOIU; max-age=3600; versi\ | | WEOIU; max-age=3600; versi | |||
| on=1 | | on=1 | |||
| - evict: location: https:/\ | | - evict: location: | |||
| /www.example.com | | https://www.example.com | |||
| - evict: :status: 307 | | - evict: :status: 307 | |||
| -> set-cookie: foo=ASDJKHQ\ | | -> set-cookie: foo=ASDJKHQ | |||
| KBZXOQWEOPIUAXQWEOIU; ma\ | | KBZXOQWEOPIUAXQWEOIU; ma | |||
| x-age=3600; version=1 | | x-age=3600; version=1 | |||
Header Table (after decoding): | Dynamic Table (after decoding): | |||
[ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age\ | [ 1] (s = 98) set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; | |||
=3600; version=1 | max-age=3600; version=1 | |||
[ 2] (s = 52) content-encoding: gzip | [ 2] (s = 52) content-encoding: gzip | |||
[ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT | [ 3] (s = 65) date: Mon, 21 Oct 2013 20:13:22 GMT | |||
Table size: 215 | Table size: 215 | |||
Decoded header list: | Decoded header list: | |||
:status: 200 | :status: 200 | |||
cache-control: private | cache-control: private | |||
date: Mon, 21 Oct 2013 20:13:22 GMT | date: Mon, 21 Oct 2013 20:13:22 GMT | |||
location: https://www.example.com | location: https://www.example.com | |||
content-encoding: gzip | content-encoding: gzip | |||
set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | set-cookie: foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1 | |||
Acknowledgments | ||||
This specification includes substantial input from the following | ||||
individuals: | ||||
o Mike Bishop, Jeff Pinner, Julian Reschke, and Martin Thomson | ||||
(substantial editorial contributions). | ||||
o Johnny Graettinger (Huffman code statistics). | ||||
Authors' Addresses | Authors' Addresses | |||
Roberto Peon | Roberto Peon | |||
Google, Inc | Google, Inc | |||
EMail: fenix@google.com | EMail: fenix@google.com | |||
Herve Ruellan | Herve Ruellan | |||
Canon CRF | Canon CRF | |||
End of changes. 289 change blocks. | ||||
804 lines changed or deleted | 732 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |