-
Notifications
You must be signed in to change notification settings - Fork 565
/
draft-ietf-httpbis-header-compression.xml
3066 lines (3065 loc) · 140 KB
/
draft-ietf-httpbis-header-compression.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version='1.0' encoding='utf-8'?>
<?xml-stylesheet type='text/xsl' href='lib/rfc2629.xslt' ?>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc linkmailto="no"?>
<?rfc editing="no"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc rfcedstyle="yes"?>
<?rfc-ext allow-markup-in-artwork="yes" ?>
<?rfc-ext include-index="no" ?>
<!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent">
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:x="http://purl.org/net/xml2rfc/ext" category="std" ipr="trust200902" docName="draft-ietf-httpbis-header-compression-latest" tocInclude="true" symRefs="true" sortRefs="true" version="3" submissionType="IETF">
<front>
<title abbrev="HPACK">HPACK: Header Compression for HTTP/2</title>
<seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-header-compression-latest"/>
<author initials="R." surname="Peon" fullname="Roberto Peon">
<organization>Google, Inc</organization>
<address>
<email>[email protected]</email>
</address>
</author>
<author initials="H." surname="Ruellan" fullname="Hervé Ruellan">
<organization>Canon CRF</organization>
<address>
<email>[email protected]</email>
</address>
</author>
<area>Applications</area>
<workgroup>HTTPbis</workgroup>
<keyword>HTTP</keyword>
<keyword>Header</keyword>
<abstract>
<t>
This specification defines HPACK, a compression format for
efficiently representing HTTP header fields, to be used in
HTTP/2.
</t>
</abstract>
<note>
<name>Editorial Note (To be removed by RFC Editor)</name>
<t>
Discussion of this draft takes place on the HTTPBIS working group
mailing list ([email protected]), which is archived at <eref target="https://lists.w3.org/Archives/Public/ietf-http-wg/"/>.
</t>
<t>
Working Group information can be found at <eref target="http://tools.ietf.org/wg/httpbis/"/>; that specific to HTTP/2
are at <eref target="http://http2.github.io/"/>.
</t>
<!--<t>
The changes in this draft are summarized in <xref
target="changes.since.draft-ietf-httpbis-header-compression-09"/>.
</t>-->
</note>
</front>
<middle>
<section>
<name>Introduction</name>
<t>
In HTTP/1.1 (see <xref target="RFC7230"/>), header fields are
not compressed. As web pages have grown to require dozens to
hundreds of requests, the redundant header fields in these
requests unnecessarily consume bandwidth, measurably increasing
latency.
</t>
<t>
<xref target="SPDY">SPDY</xref> initially addressed this
redundancy by compressing header fields using the <xref target="DEFLATE">DEFLATE</xref> format, which proved very
effective at efficiently representing the redundant header
fields. However, that approach exposed a security risk as
demonstrated by the CRIME (Compression Ratio Info-leak Made Easy)
attack (see <xref target="CRIME"/>).
</t>
<t>
This specification defines HPACK, a new compressor that
eliminates redundant header fields, limits
vulnerability to known security attacks, and has a bounded
memory requirement for use in constrained environments.
Potential security concerns for HPACK are described in <xref target="Security"/>.
</t>
<t>
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.
</t>
<section>
<name>Overview</name>
<t>
The format defined in this specification treats a list of
header fields as an ordered collection of name-value pairs
that can include duplicate pairs. Names and values are
considered to be opaque sequences of octets, and the order
of header fields is preserved after being compressed and
decompressed.
</t>
<t>
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.
</t>
<t>
In the encoded form, a header field is represented either
literally or as a reference to a header field in one of
the header field tables. Therefore, a list of header fields
can be encoded using a mixture of references and literal
values.
</t>
<t>
Literal values are either encoded directly or use a static
Huffman code.
</t>
<t>
The encoder is responsible for deciding which header fields
to insert as new entries in the header field tables. The
decoder executes the modifications to the header field
tables prescribed by the encoder, reconstructing the list of
header fields in the process. This enables decoders to
remain simple and interoperate with a wide variety of
encoders.
</t>
<t>
Examples illustrating the use of these different mechanisms
to represent header fields are available in <xref target="examples"/>.
</t>
</section>
<section anchor="conventions">
<name>Conventions</name>
<t>
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL",
"SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY",
and "OPTIONAL" in this document are to be interpreted as
described in <xref target="RFC2119">RFC 2119</xref>.
</t>
<t>
All numeric values are in network byte order. Values are
unsigned unless otherwise indicated. Literal values are
provided in decimal or hexadecimal as appropriate.
</t>
</section>
<section anchor="encoding.concepts">
<name>Terminology</name>
<t>
This specification uses the following terms:
</t>
<dl newline="false" spacing="normal">
<dt>Header Field:</dt>
<dd>
A name-value pair. Both the name and value are
treated as opaque sequences of octets.
</dd>
<dt>Dynamic Table:</dt>
<dd>
The dynamic table (see <xref target="dynamic.table"/>) is a table that
associates stored header fields with index values.
This table is dynamic and specific to an encoding or
decoding context.
</dd>
<dt>Static Table:</dt>
<dd>
The static table (see <xref target="static.table"/>)
is a table that statically associates header fields
that occur frequently
with index values. This table is ordered,
read-only, always accessible, and it may be shared
amongst all encoding or decoding contexts.
</dd>
<dt>Header List:</dt>
<dd>
A header list is an ordered collection of header
fields that are encoded jointly and can contain
duplicate header fields. A complete list of
header fields contained in an HTTP/2 header block
is a header list.
</dd>
<dt>Header Field Representation:</dt>
<dd>
A header field can be represented in encoded form
either as a literal or as an index (see <xref target="header.representation"/>).
</dd>
<dt>Header Block:</dt>
<dd>
An ordered list of header field representations,
which, when decoded, yields a complete header list.
</dd>
</dl>
</section>
</section>
<section anchor="header.encoding">
<name>Compression Process Overview</name>
<t>
This specification does not describe a specific algorithm for an
encoder. Instead, it defines precisely how a decoder is
expected to operate, allowing encoders to produce any encoding
that this definition permits.
</t>
<section anchor="header.list.ordering">
<name>Header List Ordering</name>
<t>
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.
</t>
</section>
<section anchor="encoding.context">
<name>Encoding and Decoding Contexts</name>
<t>
To decompress header blocks, a decoder only needs to
maintain a dynamic table (see <xref target="dynamic.table"/>) as a decoding context. No
other dynamic state is needed.
</t>
<t>
When used for bidirectional communication, such as in HTTP,
the encoding and decoding dynamic tables maintained by an
endpoint are completely independent, i.e., the request
and response dynamic tables are separate.
</t>
</section>
<section anchor="indexing.tables">
<name>Indexing Tables</name>
<t>
HPACK uses two tables for associating header fields to
indexes. The static table (see <xref target="static.table"/>) is predefined and contains
common header fields (most of them with an empty value). The
dynamic table (see <xref target="dynamic.table"/>) is
dynamic and can be used by the encoder to index header
fields repeated in the encoded header lists.
</t>
<t>
These two tables are combined into a single address space
for defining index values (see <xref target="index.address.space"/>).
</t>
<section anchor="static.table">
<name>Static Table</name>
<t>
The static table consists of a predefined static list of
header fields. Its entries are defined in <xref target="static.table.definition"/>.
</t>
</section>
<section anchor="dynamic.table">
<name>Dynamic Table</name>
<t>
The dynamic table consists of a list of header fields
maintained in 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.
</t>
<t>
The dynamic table is initially empty. Entries are added
as each header block is decompressed.
</t>
<t>
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.
</t>
<t>
The encoder decides how to update the dynamic table and
as such can control how much memory is used by the
dynamic table. To limit the memory requirements of the
decoder, the dynamic table size is strictly bounded (see
<xref target="maximum.table.size"/>).
</t>
<t>
The decoder updates the dynamic table during the
processing of a list of header field representations
(see <xref target="header.representation.processing"/>).
</t>
</section>
<section anchor="index.address.space">
<name>Index Address Space</name>
<t>
The static table and the dynamic table are combined into
a single index address space.
</t>
<t>
Indices between 1 and the length of the static table
(inclusive) refer to elements in the static table (see
<xref target="static.table"/>).
</t>
<t>
Indices strictly greater than the length of the static
table refer to elements in the dynamic table (see <xref target="dynamic.table"/>). The length
of the static table is subtracted to find the index into
the dynamic table.
</t>
<t>
Indices strictly greater than the sum of the lengths of
both tables MUST be treated as a decoding error.
</t>
<t keepWithNext="true">
For a static table size of s and a dynamic table
size of k, the following diagram shows the entire
valid index address space.
</t>
<figure anchor="Index.Address.Space">
<name>Index Address Space</name>
<artwork type="drawing"><![CDATA[
<---------- Index Address Space ---------->
<-- Static Table --> <-- Dynamic Table -->
+---+-----------+---+ +---+-----------+---+
| 1 | ... | s | |s+1| ... |s+k|
+---+-----------+---+ +---+-----------+---+
^ |
| V
Insertion Point Dropping Point
]]></artwork>
</figure>
</section>
</section>
<section anchor="header.representation">
<name>Header Field Representation</name>
<t>
An encoded header field can be represented either as an
index or as a literal.
</t>
<t>
An indexed representation defines a header field as a
reference to an entry in either the static table or the
dynamic table (see <xref target="indexed.header.representation"/>).
</t>
<t>
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.
</t>
<t>
Three different literal representations are defined:
</t>
<ul spacing="normal">
<li>
A literal representation that adds the header field
as a new entry at the beginning of the dynamic table
(see <xref target="literal.header.with.incremental.indexing"/>).
</li>
<li>
A literal representation that does not add the
header field to the dynamic table (see <xref target="literal.header.without.indexing"/>).
</li>
<li>
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 <xref target="literal.header.never.indexed"/>). This
representation is intended for protecting header
field values that are not to be put at risk by
compressing them (see <xref target="never.indexed.literals"/> for more
details).
</li>
</ul>
<t>
The selection of one of these literal representations can be
guided by security considerations, in order to protect
sensitive header field values (see <xref target="compression.based.attacks"/>).
</t>
<t>
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 <xref target="string.literal.representation"/>).
</t>
</section>
</section>
<section anchor="header.block.decoding">
<name>Header Block Decoding</name>
<section anchor="header.block.processing">
<name>Header Block Processing</name>
<t>
A decoder processes a header block sequentially to
reconstruct the original header list.
</t>
<t>
A header block is the concatenation of header field
representations. The different possible header field
representations are described in <xref target="detailed.format"/>.
</t>
<t>
Once a header field is decoded and added to the
reconstructed header list, the header field cannot be
removed. A header field added to the header list can be
safely passed to the application.
</t>
<t>
By passing the resulting header fields to the application,
a decoder can be implemented with minimal transitory memory
commitment in addition to the memory required for the dynamic table.
</t>
</section>
<section anchor="header.representation.processing">
<name>Header Field Representation Processing</name>
<t>
The processing of a header block to obtain a header list is
defined in this section. To ensure that the decoding will
successfully produce a header list, a decoder MUST obey the
following rules.
</t>
<t>
All the header field representations contained in a header
block are processed in the order in which they appear, as
specified below. Details on the formatting of the various
header field representations and some additional processing
instructions are found in <xref target="detailed.format"/>.
</t>
<t>
An <em>indexed representation</em> entails the
following actions:
</t>
<ul spacing="normal">
<li>
The header field corresponding to the referenced
entry in either the static table or dynamic table is
appended to the decoded header list.
</li>
</ul>
<t>
A <em>literal representation</em> that is <em>not
added</em> to the dynamic table entails the following
action:
</t>
<ul spacing="normal">
<li>
The header field is appended to the decoded header
list.
</li>
</ul>
<t>
A <em>literal representation</em> that is
<em>added</em> to the dynamic table entails the
following actions:
</t>
<ul spacing="normal">
<li>
The header field is appended to the decoded header
list.
</li>
<li>
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 <xref target="entry.addition"/>).
</li>
</ul>
</section>
</section>
<section anchor="dynamic.table.management">
<name>Dynamic Table Management</name>
<t>
To limit the memory requirements on the decoder side, the
dynamic table is constrained in size.
</t>
<section anchor="calculating.table.size">
<name>Calculating Table Size</name>
<t>
The size of the dynamic table is the sum of the size of its
entries.
</t>
<t>
The size of an entry is the sum of its name's length in
octets (as defined in <xref target="string.literal.representation"/>), its value's
length in octets, and 32.
</t>
<t>
The size of an entry is calculated using the length of its
name and value without any Huffman encoding applied.
</t>
<aside>
<t>
<strong>Note:</strong>
The additional 32 octets account for an estimated
overhead associated with an entry. For example, an
entry structure using 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.
</t>
</aside>
</section>
<section anchor="maximum.table.size">
<name>Maximum Table Size</name>
<t>
Protocols that use HPACK determine the maximum size that the
encoder is permitted to use for the dynamic table. In
HTTP/2, this value is determined by the
SETTINGS_HEADER_TABLE_SIZE setting (see <xref target="HTTP2"/>).
</t>
<t>
An encoder can choose to use less capacity than this maximum
size (see <xref target="encoding.context.update"/>), but the
chosen size MUST stay lower than or equal to the maximum set
by the protocol.
</t>
<t>
A change in the maximum size of the dynamic table is
signaled via a dynamic table size update (see <xref target="encoding.context.update"/>). This dynamic table size
update MUST occur at the beginning of the first header block
following the change to the dynamic table size. In HTTP/2,
this follows a settings acknowledgment (see <xref target="HTTP2"/>).
</t>
<t>
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 <xref target="entry.eviction"/>).
</t>
<t>
This mechanism can be used to completely clear entries from
the dynamic table by setting a maximum size of 0, which can
subsequently be restored.
</t>
</section>
<section anchor="entry.eviction">
<name>Entry Eviction When Dynamic Table Size Changes</name>
<t>
Whenever the maximum size for the dynamic table is reduced,
entries are evicted from the end of the dynamic table until
the size of the dynamic table is less than or equal to the
maximum size.
</t>
</section>
<section anchor="entry.addition">
<name>Entry Eviction When Adding New Entries</name>
<t>
Before a new entry is added to the dynamic table, entries
are evicted from the end of the dynamic table until the size
of the dynamic table is less than or equal to (maximum size
- new entry size) or until the table is empty.
</t>
<t>
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 attempt to add an entry that is larger than the
maximum size; an attempt to add an entry larger than the
maximum size causes the table to be emptied of all existing
entries and results in an empty table.
</t>
<t>
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.
</t>
</section>
</section>
<section anchor="low-level.representation">
<name>Primitive Type Representations</name>
<t>
HPACK encoding uses two primitive types: unsigned variable-length
integers and strings of octets.
</t>
<section anchor="integer.representation">
<name>Integer Representation</name>
<t>
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.
</t>
<t>
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 integer value does not fit within the prefix.
The number of bits of the prefix (called N) is a parameter
of the integer representation.
</t>
<t>
If the integer value is small enough, i.e., strictly less
than 2<sup>N</sup>-1, it is encoded within the N-bit
prefix.
</t>
<figure anchor="Integer.Value.Encoded.within.the.Prefix.shown.for.N.5">
<name>Integer Value Encoded within the Prefix (Shown for N = 5)</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| ? | ? | ? | Value |
+---+---+---+-------------------+
]]></artwork>
</figure>
<t>
Otherwise, all the bits of the prefix are set to 1, and the
value, decreased by 2<sup>N</sup>-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.
</t>
<figure anchor="Integer.Value.Encoded.after.the.Prefix.shown.for.N.5">
<name>Integer Value Encoded after the Prefix (Shown for N = 5)</name>
<artwork type="inline"><![CDATA[
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 |
+---+---------------------------+
]]></artwork>
</figure>
<t>
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<sup>N</sup>-1 to
obtain the integer value.
</t>
<t>
The prefix size, N, is always between 1 and 8 bits. An
integer starting at an octet boundary will have an 8-bit
prefix.
</t>
<t keepWithNext="true">
Pseudocode to represent an integer I is as follows:
</t>
<artwork type="inline"><![CDATA[
if I < 2^N - 1, encode I on N bits
else
encode (2^N - 1) on N bits
I = I - (2^N - 1)
while I >= 128
encode (I % 128 + 128) on 8 bits
I = I / 128
encode I on 8 bits
]]></artwork>
<t keepWithNext="true">
Pseudocode to decode an integer I is as follows:
</t>
<artwork type="inline"><![CDATA[
decode I from the next N bits
if I < 2^N - 1, return I
else
M = 0
repeat
B = next octet
I = I + (B & 127) * 2^M
M = M + 7
while B & 128 == 128
return I
]]></artwork>
<t>
Examples illustrating the encoding of integers are available
in <xref target="integer.representation.examples"/>.
</t>
<t>
This integer representation allows for values of indefinite
size. It 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. Integer encodings that
exceed implementation limits -- in value or octet length --
MUST be treated as decoding errors. Different limits can
be set for each of the different uses of integers, based on
implementation constraints.
</t>
</section>
<section anchor="string.literal.representation">
<name>String Literal Representation</name>
<t>
Header field names and header field values can be
represented as string literals. A string literal is encoded
as a sequence of octets, either by directly encoding the
string literal's octets or by using a Huffman code
(see <xref target="HUFFMAN"/>).
</t>
<figure anchor="String.Literal.Representation">
<name>String Literal Representation</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| H | String Length (7+) |
+---+---------------------------+
| String Data (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<t>
A string literal representation contains the following
fields:
</t>
<dl newline="false" spacing="normal">
<dt>H:</dt>
<dd>
A one-bit flag, H, indicating whether or not the
octets of the string are Huffman encoded.
</dd>
<dt>String Length:</dt>
<dd>
The number of octets used to encode the string
literal, encoded as an integer with a 7-bit prefix
(see <xref target="integer.representation"/>).
</dd>
<dt>String Data:</dt>
<dd>
The encoded data of the string literal. If H is
'0', 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
string literal.
</dd>
</dl>
<t>
String literals that use Huffman encoding are encoded with
the Huffman code defined in <xref target="huffman.code"/>
(see examples for requests in <xref target="request.examples.with.huffman.coding"/> and for
responses in <xref target="response.examples.with.huffman.coding"/>). The
encoded data is the bitwise concatenation of the codes
corresponding to each octet of the string literal.
</t>
<t>
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 prevent this padding from being misinterpreted
as part of the string literal, the most significant bits of
the code corresponding to the EOS (end-of-string) symbol are
used.
</t>
<t>
Upon decoding, an incomplete code at the end of the
encoded data is to be considered as padding and discarded. A
padding strictly longer 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 symbol MUST be
treated as a decoding error. A Huffman-encoded string
literal containing the EOS symbol MUST be treated as a
decoding error.
</t>
</section>
</section>
<section anchor="detailed.format">
<name>Binary Format</name>
<t>
This section describes the detailed format of each of the
different header field representations and the dynamic table
size update instruction.
</t>
<section anchor="indexed.header.representation">
<name>Indexed Header Field Representation</name>
<t>
An indexed header field representation identifies an entry
in either the static table or the dynamic table (see <xref target="indexing.tables"/>).
</t>
<t>
An indexed header field representation causes a
header field to be added to the decoded header list, as
described in <xref target="header.representation.processing"/>.
</t>
<figure anchor="Indexed.Header.Field">
<name>Indexed Header Field</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 1 | Index (7+) |
+---+---------------------------+
]]></artwork>
</figure>
<t>
An indexed header field starts with the '1' 1-bit pattern,
followed by the index of the matching header field,
represented as an integer with a 7-bit prefix (see <xref target="integer.representation"/>).
</t>
<t>
The index value of 0 is not used. It MUST be treated as a
decoding error if found in an indexed header field
representation.
</t>
</section>
<section anchor="literal.header.representation">
<name>Literal Header Field Representation</name>
<t>
A literal header field representation contains a literal
header field value. Header field names are provided either
as a literal or by reference to an existing table entry,
either from the static table or the dynamic table (see <xref target="indexing.tables"/>).
</t>
<t>
This specification defines three forms of literal header
field representations: with indexing, without indexing,
and never indexed.
</t>
<section anchor="literal.header.with.incremental.indexing">
<name>Literal Header Field with Incremental Indexing</name>
<t>
A literal header field with incremental indexing
representation results in appending a header field to
the decoded header list and inserting it as a new entry
into the dynamic table.
</t>
<figure anchor="Literal.Header.Field.with.Incremental.Indexing.Indexed.Name">
<name>Literal Header Field with Incremental Indexing -- Indexed Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 1 | Index (6+) |
+---+---+-----------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<figure anchor="Literal.Header.Field.with.Incremental.Indexing.New.Name">
<name>Literal Header Field with Incremental Indexing -- New Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 1 | 0 |
+---+---+-----------------------+
| H | Name Length (7+) |
+---+---------------------------+
| Name String (Length octets) |
+---+---------------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<t>
A literal header field with incremental indexing
representation starts with the '01' 2-bit pattern.
</t>
<t>
If the header field name matches the header field name
of an entry stored in the static table or the dynamic
table, the header field name can be represented using
the index of that entry. In this case, the index of the
entry is represented as an integer with a 6-bit prefix
(see <xref target="integer.representation"/>). This
value is always non-zero.
</t>
<t>
Otherwise, the header field name is represented as a
string literal (see <xref target="string.literal.representation"/>). A value
0 is used in place of the 6-bit index, followed by the
header field name.
</t>
<t>
Either form of header field name representation is
followed by the header field value represented as a
string literal (see <xref target="string.literal.representation"/>).
</t>
</section>
<section anchor="literal.header.without.indexing">
<name>Literal Header Field without Indexing</name>
<t>
A literal header field without indexing representation
results in appending a header field to the decoded
header list without altering the dynamic table.
</t>
<figure anchor="Literal.Header.Field.without.Indexing.Indexed.Name">
<name>Literal Header Field without Indexing -- Indexed Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | Index (4+) |
+---+---+-----------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<figure anchor="Literal.Header.Field.without.Indexing.New.Name">
<name>Literal Header Field without Indexing -- New Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 0 | 0 |
+---+---+-----------------------+
| H | Name Length (7+) |
+---+---------------------------+
| Name String (Length octets) |
+---+---------------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<t>
A literal header field without indexing representation
starts with the '0000' 4-bit pattern.
</t>
<t>
If the header field name matches the header field name
of an entry stored in the static table or the dynamic
table, the header field name can be represented using
the index of that entry. In this case, the index of the
entry is represented as an integer with a 4-bit prefix
(see <xref target="integer.representation"/>). This
value is always non-zero.
</t>
<t>
Otherwise, the header field name is represented as a
string literal (see <xref target="string.literal.representation"/>). A value
0 is used in place of the 4-bit index, followed by the
header field name.
</t>
<t>
Either form of header field name representation is
followed by the header field value represented as a
string literal (see <xref target="string.literal.representation"/>).
</t>
</section>
<section anchor="literal.header.never.indexed">
<name>Literal Header Field Never Indexed</name>
<t>
A literal header field never-indexed representation
results in appending a header field to the decoded
header list without altering the dynamic table.
Intermediaries MUST use the same representation for
encoding this header field.
</t>
<figure anchor="Literal.Header.Field.never.Indexed.Indexed.Name">
<name>Literal Header Field Never Indexed -- Indexed Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | Index (4+) |
+---+---+-----------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<figure anchor="Literal.Header.Field.never.Indexed.New.Name">
<name>Literal Header Field Never Indexed -- New Name</name>
<artwork type="inline"><![CDATA[
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 0 | 0 | 1 | 0 |
+---+---+-----------------------+
| H | Name Length (7+) |
+---+---------------------------+
| Name String (Length octets) |
+---+---------------------------+
| H | Value Length (7+) |
+---+---------------------------+
| Value String (Length octets) |
+-------------------------------+
]]></artwork>
</figure>
<t>
A literal header field never-indexed representation
starts with the '0001' 4-bit pattern.
</t>
<t>
When a header field is represented as a literal header
field never indexed, it MUST always be encoded with
this specific literal representation. In particular,
when a peer sends a header field that it received
represented as a literal header field never indexed, it
MUST use the same representation to forward this header
field.
</t>
<t>
This representation is intended for protecting header
field values that are not to be put at risk by
compressing them (see <xref target="compression.based.attacks"/> for more details).
</t>
<t>
The encoding of the representation is identical to the
literal header field without indexing
(see <xref target="literal.header.without.indexing"/>).
</t>
</section>
</section>
<section anchor="encoding.context.update">
<name>Dynamic Table Size Update</name>
<t>
A dynamic table size update signals a change to the size of
the dynamic table.
</t>
<figure anchor="Maximum.Dynamic.Table.Size.Change">
<name>Maximum Dynamic Table Size Change</name>
<artwork type="inline"><![CDATA[