forked from http2/compression-spec
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcompression-spec.xml
More file actions
891 lines (854 loc) · 42.4 KB
/
compression-spec.xml
File metadata and controls
891 lines (854 loc) · 42.4 KB
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
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type='text/xsl' href='lib/rfc2629.xslt' ?>
<!--<?rfc header="Documentation"?>-->
<!--?rfc private="RFC2629 through 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"?>
<?ref rfcedstyle="yes"?>
<?rfc-ext allow-markup-in-artwork="yes" ?>
<?rfc-ext include-index="no" ?>
<!-- <?rfc topblock="no"?> -->
<!--<?rfc strict="no"?>-->
<rfc category="info"
ipr="trust200902"
docName="header"
xmlns:x='http://purl.org/net/xml2rfc/ext'>
<front>
<title abbrev="HTTP Header Compression">HTTP Header Compression</title>
<author initials="R." surname="Peon" fullname="Roberto Peon">
<organization>Google, Inc</organization>
<address>
<email>fenix@google.com</email>
</address>
</author>
<author initials="H." surname="Ruellan" fullname="Hervé Ruellan">
<organization>Canon CRF</organization>
<address>
<email>herve.ruellan@crf.canon.fr</email>
</address>
</author>
<date month="May" year="2013"/>
<area>Applications</area>
<workgroup>HTTPbis Working Group</workgroup>
<keyword>HTTP</keyword>
<keyword>Header</keyword>
<abstract>
<t>
This document describes a format adapted to efficiently
represent HTTP headers in the context of HTTP/2.0.
</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t>
This document describes a format adapted to efficiently
represent HTTP headers in the context of HTTP/2.0.
</t>
</section>
<section title="Overview" anchor="overview">
<t>
In HTTP/1.X, HTTP headers, which are necessary for the
functioning of the protocol, are transmitted with no
transformations. Unfortunately, the amount of redundancy in
both the keys and the values of these headers is astonishingly
high, and is the cause of increased latency on
lower bandwidth links. This indicates that an alternate
encoding for headers would be beneficial to latency, and that
is what is proposed here.
As shown by <xref target="SPDY">SPDY</xref>, Deflate
compresses HTTP very effectively. However, the use of a
compression scheme which allows for arbitrary matches against
the previously encoded data (such as Deflate) exposes users to
security issues.
In particular, the compression of sensitive data, together
with other data controlled by an attacker, may lead to leakage
of that sensitive data, even when the resultant bytes are
transmitted over an encrypted channel.
Another consideration is that processing and memory costs of a
compressor such as Deflate may also be too high for some
classes of devices, for example when doing forward or reverse
proxying.
</t>
<section title="Outline">
<t>
The HTTP header representation described in this document
is based on indexing tables that store (name, value) pairs,
called header tables in the remainder of this document.
This scheme is believed to be safe for all known attacks
against the compression context today. Header tables are
incrementally updated during the whole HTTP/2.0 session.
Two independent header tables are used during a HTTP/2.0
session, one for HTTP request headers and one for HTTP
response headers.
</t>
<t>
The encoder is responsible for deciding which headers to
insert as (name, value) pairs in the header table. The
decoder then does exactly what the encoder prescribes,
ending in a state that exactly matches the encoder's
state. This enables decoders to remain simple and
understand a wide variety of encoders.
</t>
<t>
A header may be represented as a literal or as an index.
If represented as a literal, the representation specifies
whether this header is used to update the indexing table.
The different representations are described in <xref
target="header.representation" />.
</t>
<t>
A set of headers is coded as a difference from the
previous set of headers.
</t>
<t>
An example illustrating the use these different mechanisms
to represent headers is available in <xref
target="example"/>.
</t>
</section>
</section>
<section title="Indexing Strategies" anchor="indexing.strategies">
<section title="Header Table" anchor="header.table">
<t>
A header table consists of an ordered list of (name,
value) pairs. A pair is either inserted at the end of the
table or replaces an existing pair depending on the chosen
representation. A pair can be represented as an index
which is its position in the table, starting with 0 for
the first entry.
</t>
<t>
Header names are always represented as lower-case strings.
An input header name matches the header name of a (name,
value) pair stored in the Header Table if they are
equal using a character-based, <spanx>case
insensitive</spanx> comparison.
An input header value matches the header value of a
(name, value) pair stored in the Header Table if they are
equal using a character-based, <spanx>case
sensitive</spanx> comparison.
An input header (name, value) pair matches a pair in the
Header Table if both the name and value are matching as
per above.
</t>
<t>
The header table is progressively updated based on headers
represented as literal (as defined in <xref
target="literal" />). Two update mechanisms are
defined:
<list style="symbols">
<t>
Incremental indexing: the represented header is
inserted at the end of the header table as a
(name, value) pair. The inserted pair index is
set to the next free index in the table: it is
equal to the number of headers in the table before
its insertion.
</t>
<t>
Substitution indexing: the represented header
contains an index to an existing (name, value)
pair. The existing pair value is replaced by the
pair representing the new header.
</t>
</list>
Incremental and substitution indexing are optional. If
none of them is selected in a header representation, the
header table is not updated. In particular, no update
happens on the header table when processing an indexed
representation.
</t>
<t>
The header table size can be bounded so as to limit the
memory requirements (see the SETTINGS_MAX_BUFFER_SIZE in
<xref target="parameter.negotiation"/>). The header table
size is defined as the sum of the size of each entry of
the table. The size of an entry is the sum of the length
in bytes (as defined in <xref
target="string.literal.representation" />) of its
name, of value's length in bytes and of 32 bytes (for
accounting for the entry structure overhead).
</t>
<t>
When an entry is added to the header table, if the header
table size is greater than the limit, the table size is
reduced by dropping the entries at the beginning of the
table until the header table size becomes lower than or
equal to the limit. Dropping entries from the beginning of
the table causes a renumbering of the remaining entries.
</t>
<t>
To optimize the representation of the headers exchanged at
the beginning of an HTTP/2.0 session, the header table is
initialized with common headers. The list of these initial
headers is provided in <xref target="initial.headers"/>.
</t>
</section>
<section title="Header Representation" anchor="header.representation">
<section title="Literal Representation" anchor="literal">
<t>
The literal representation defines a new header. A
literal header is represented as:
<list style="symbols">
<t>
A header name, with two possible
representations:
<list style="symbols">
<t>
A literal string, as described in
<xref
target="string.literal.representation"/>.
</t>
<t>
A index in the header table
referencing the name of the
corresponding header. The index is
represented as an integer, as
described in <xref
target="integer.representation"/>.
</t>
</list>
</t>
<t>
The header value, represented as a literal
string, as described in <xref
target="string.literal.representation" />.
</t>
</list>
</t>
</section>
<section title="Indexed Representation" anchor="indexed">
<t>
The indexed representation defines a header as a match
to a (name, value) pair in the header table. An
indexed header is represented as:
<list style="symbols">
<t>
An integer representing the index of the
matching (name, value) pair, as described in
<xref target="integer.representation" />.
</t>
</list>
</t>
</section>
</section>
<section title="Differential Coding" anchor="differential.coding">
<t>
A set of headers is encoded as a difference from the
previous reference set of headers. The initial reference
set of headers is the empty set.
</t>
<t>
An indexed representation toggles the presence of the
header in the current set of headers. If the header
corresponding to the indexed representation was not in the
set, it is added to the set. If the header index was in
the set, it is removed from it.
</t>
<t>
A literal representation adds a header to the current set
of headers if the header is added to the header table
(either by incremental indexing or by substitution
indexing).
</t>
<t>
To ensure a correct decoding of a set of headers, the
following steps or equivalent ones MUST be executed by the
decoder.
</t>
<t>
First, upon starting the decoding of a new set of headers,
the reference set of headers is interpreted into the
working set of headers: for each header in the reference
set, an entry is added to the working set, containing the
header name, its value, and its current index in the
header table.
</t>
<t>
Then, the header representations are processed in their
order of occurrence in the frame.
</t>
<t>
For an indexed representation, the decoder checks whether
the index is present in the working set. If true, the
corresponding entry is removed from the working set. If
several entries correspond to this encoded index, all
these entries are removed from the working set. If
the index is not present in the working set, it is used to
retrieve the corresponding header from the header table,
and a new entry is added to the working set representing
this header.
</t>
<t>
For a literal representation, a new entry is added to the
working set representing this header. If the literal
representation specifies that the header is to be indexed,
the header is added accordingly to the header table, and
its index is included in the entry in the working set.
Otherwise, the entry in the working set contains an
undefined index.
</t>
<t>
When all the header representations have been processed,
the working set contains all the headers of the set of
headers.
</t>
<t>
The new reference set of headers is computed by removing
from the working set all the headers that are not present
in the header table.
</t>
<t>
It should be noted that during the decoding of the header
representations, the same index may be associated to
different headers in the working set and in the header
table.
</t>
</section>
</section>
<section title="Detailed Format" anchor="detailed.format">
<section title="Header Blocks" anchor="header.blocks">
<t>
A header block consists of a set of header fields, which
are name-value pairs. Each header field is encoded using
one of the header representation.
</t>
</section>
<section title="Low-level representations" anchor="string.encoding">
<section title="Integer representation" anchor="integer.representation">
<t>
Integers are used to represent name indexes, pair
indexes or string lengths.
The integer representation keeps byte-alignment as
much as possible as this allows various processing
optimizations as well as efficient use of DEFLATE.
For that purpose, an integer representation always
finishes at the end of a byte.
</t>
<t>
An integer is represented in two parts: a prefix that
fills the current byte and an optional list of bytes
that are used if the integer value does not fit in the
prefix. The number of bits of the prefix (called N)
is a parameter of the integer representation.
</t>
<t>
The N-bit prefix allows filling the current byte. If
the value is small enough (strictly less than 2^N-1),
it is encoded within the N-bit prefix. Otherwise all
the bits of the prefix are set to 1 and the value is
encoded using an <eref
target="http://en.wikipedia.org/wiki/Variable-length_quantity">
unsigned variable length integer</eref>
representation.
</t>
<t>
The algorithm to represent an integer I is as follows:
<list style="numbers">
<t>If I < 2^N - 1, encode I on N bits</t>
<t>Else, encode 2^N - 1 on N bits and do the
following steps:</t>
<t><list style="numbers">
<t>Set I to (I - (2^N - 1)) and Q to 1</t>
<t>While Q > 0</t>
<t><list style="numbers">
<t>Compute Q and R, quotient and remainder
of I divided by 2^7</t>
<t>If Q is strictly greater than 0, write
one 1 bit; otherwise, write one 0
bit</t>
<t>Encode R on the next 7 bits</t>
<t>I = Q</t>
</list></t>
</list></t>
</list>
</t>
<section title="Example 1: Encoding 10 using a 5-bit prefix"
anchor="integer.representation.example1">
<t>
The value 10 is to be encoded with a 5-bit prefix.
<list style="symbols">
<t>
10 is less than 31 (= 2^5 - 1) and is
represented using the 5-bit prefix.
</t>
</list>
</t>
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| X | X | X | 0 | 1 | 0 | 1 | 0 | 10 stored on 5 bits
+---+---+---+---+---+---+---+---+
</artwork>
</figure>
</section>
<section title="Example 2: Encoding 1337 using a 5-bit prefix"
anchor="integer.representation.example2">
<t>
The value I=1337 is to be encoded with a 5-bit
prefix.
<list style="symbols">
<t>1337 is greater than 31 (= 2^5 - 1).</t>
<t><list style="symbols">
<t>The 5-bit prefix is filled with its max
value (31).</t>
</list></t>
<t>The value to represent on next bytes is I =
1337 - (2^5 - 1) = 1306.</t>
<t><list style="symbols">
<t>1306 = 128*10 + 26, i.e. Q=10 and
R=26.</t>
<t>Q is greater than 1, bit 8 is set to
1.</t>
<t>The remainder R=26 is encoded on next 7
bits.</t>
<t>I is replaced by the quotient Q=10.</t>
</list></t>
<t>The value to represent on next bytes is I =
10.</t>
<t><list style="symbols">
<t>10 = 128*0 + 10, i.e. Q=0 and R=10.</t>
<t>Q is equal to 0, bit 16 is set to
0.</t>
<t>The remainder R=10 is encoded on next 7
bits.</t>
<t>I is replaced by the quotient Q=0.</t>
</list></t>
<t>The process ends.</t>
</list>
</t>
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| X | X | X | 1 | 1 | 1 | 1 | 1 | Prefix = 31
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | Q>=1, R=26
| 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | Q=0 , R=10
+---+---+---+---+---+---+---+---+
</artwork>
</figure>
</section>
</section>
<section title="String literal representation" anchor="string.literal.representation">
<t>
Literal strings can represent header names or header
values. They are encoded in two parts:
<list style="numbers">
<t>The string length, defined as the number of
bytes needed to store its UTF-8
representation, is represented as an integer
with a zero bits prefix. If the string length
is strictly less than 128, it is represented
as one byte.
</t>
<t>
The string value represented as a list of
UTF-8 characters.
</t>
</list>
</t>
</section>
</section>
<section title="Indexed Header Representation">
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 1 | Index (7+) |
+---+---------------------------+
</artwork>
</figure>
<t>
This representation starts with the '1' 1-bit prefix,
followed by the index of the matching pair, represented as
an integer with a 7-bit prefix.
</t>
</section>
<section title="Literal Header Representation">
<section title="Literal Header without Indexing">
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 1 | 1 | Index (5+) |
+---+---+---+-------------------+
</artwork>
</figure>
<t>
This representation, which does not involve updating
the header table, starts with the '011' 3-bit pattern.
</t>
<t>
If the header name matches the header name of a (name,
value) pair stored in the Header Table, the index of
the pair increased by one (index + 1) is represented
as an integer with a 5-bit prefix. Note that if the
index is strictly below 30, one byte is used.
</t>
<t>
If the header name does not match a header name entry,
the value 0 is represented on 5 bits followed by the
header name, represented as a literal string.
</t>
<t>
Header name representation is followed by the header
value represented as a literal string as described in
<xref target="string.literal.representation" />.
</t>
</section>
<section title="Literal Header with Incremental Indexing">
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 1 | 0 | Index (5+) |
+---+---+---+-------------------+
</artwork>
</figure>
<t>
This representation starts with the '010' 3-bit
pattern.
</t>
<t>
If the header name matches the header name of a (name,
value) pair stored in the Header Table, the index of
the pair increased by one (index + 1) is represented
as an integer with a 5-bit prefix. Note that if the
index is strictly below 30, one byte is used.
</t>
<t>
If the header name does not match a header name entry,
the value 0 is represented on 5 bits followed by the
header name, represented as a literal string.
</t>
<t>
Header name representation is followed by the header
value represented as a literal string as described in
<xref target="string.literal.representation" />.
</t>
</section>
<section title="Literal Header with Substitution Indexing">
<figure>
<artwork type="inline">
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| 0 | 0 | Index (6+) |
+---+---+-----------------------+
</artwork>
</figure>
<t>
This representation starts with the '00' 2-bit
pattern.
</t>
<t>
If the header name matches the header name of a (name,
value) pair stored in the Header Table, the index of
the pair increased by one (index + 1) is represented
as an integer with a 6-bit prefix. Note that if the
index is strictly below 62, one byte is used.
</t>
<t>
If the header name does not match a header name entry,
the value 0 is represented on 6 bits followed by the
header name, represented as a literal string.
</t>
<t>
The index of the substituted (name, value) pair is
inserted after the header name representation as a
0-bit prefix integer.
</t>
<t>
This index is followed by the header
value represented as a literal string as described in
<xref target="string.literal.representation" />.
</t>
</section>
</section>
</section>
<section anchor="parameter.negotiation" title="Parameter Negotiation">
<t>
A few parameters can be used to accomodate client and server
processing and memory requirements.
<list style="hanging">
<t hangText="SETTINGS_MAX_BUFFER_SIZE:">
<t>
Allows the sender to inform the remote endpoint of
the maximum size it accepts for the header table.
</t>
<t>
The default value is 4096 bytes.
</t>
<cref>Is this default value OK?</cref>
<t>
When the remote endpoint receives a SETTINGS frame
containing a SETTINGS_MAX_BUFFER_SIZE setting with
a value smaller than the one currently in use, it
MUST send as soon as possible a HEADER frame with
a stream identifier of 0x0 containing a value
smaller than or equal to the received setting
value.
</t>
<cref>This changes lightly the behaviour of the
HEADERS frame, which should be updated.
</cref>
<t>
A HEADER frame with a stream identifier of 0x0
indicates that the sender has reduced the maximum
size of the header table. The new maximum size of
the header table is encoded on 32-bit. The decoder
MUST reduce its own header table by dropping the
entries with the largest index until the size of
the header table is lower than or equal to the
transmitted maximum size.
</t>
</t>
</list>
</t>
</section>
<section anchor="Security" title="Security Considerations">
<t>TODO?</t>
</section>
<section anchor="IANA" title="IANA Considerations">
<t>This memo includes no request to IANA.</t>
</section>
</middle>
<back>
<references title="Informative References">
<reference anchor="SPDY" target="http://tools.ietf.org/html/draft-mbelshe-httpbis-spdy">
<front>
<title>SPDY Protocol</title>
<author initials="M" surname="Belshe" fullname="Mike Belshe">
<organization>Twist</organization>
</author>
<author initials="R" surname="Peon" fullname="Roberto Peon">
<organization>Google</organization>
</author>
</front>
</reference>
</references>
<section title="Initial header names" anchor="initial.headers">
<cref>
The tables in this section should be updated based on
statistical analysis of header names frequency and specific
HTTP 2.0 header rules (like removal of some headers).
</cref>
<cref>
These tables are not adapted for headers contained in
PUSH_PROMISE frames. Either the tables can be merged, or the
table for responses can be updated.
</cref>
<section title="Requests">
<t>
The following table contains the pre-defined headers used
to initialize the header table used to represent
requests.
</t>
<texttable anchor="initial.headers.request">
<ttcol>Index</ttcol>
<ttcol>Header Name</ttcol>
<ttcol>Header Value</ttcol>
<c>0</c><c>:scheme</c><c>http</c>
<c>1</c><c>:scheme</c><c>https</c>
<c>2</c><c>:host</c><c></c>
<c>3</c><c>:path</c><c>/</c>
<c>4</c><c>:method</c><c>get</c>
<c>5</c><c>accept</c><c></c>
<c>6</c><c>accept-charset</c><c></c>
<c>7</c><c>accept-encoding</c><c></c>
<c>8</c><c>accept-language</c><c></c>
<c>9</c><c>cookie</c><c></c>
<c>10</c><c>if-modified-since</c><c></c>
<c>11</c><c>keep-alive</c><c></c>
<c>12</c><c>user-agent</c><c></c>
<c>13</c><c>proxy-connection</c><c></c>
<c>14</c><c>referer</c><c></c>
<c>15</c><c>accept-datetime</c><c></c>
<c>16</c><c>authorization</c><c></c>
<c>17</c><c>allow</c><c></c>
<c>18</c><c>cache-control</c><c></c>
<c>19</c><c>connection</c><c></c>
<c>20</c><c>content-length</c><c></c>
<c>21</c><c>content-md5</c><c></c>
<c>22</c><c>content-type</c><c></c>
<c>23</c><c>date</c><c></c>
<c>24</c><c>expect</c><c></c>
<c>25</c><c>from</c><c></c>
<c>26</c><c>if-match</c><c></c>
<c>27</c><c>if-none-match</c><c></c>
<c>28</c><c>if-range</c><c></c>
<c>29</c><c>if-unmodified-since</c><c></c>
<c>30</c><c>max-forwards</c><c></c>
<c>31</c><c>pragma</c><c></c>
<c>32</c><c>proxy-authorization</c><c></c>
<c>33</c><c>range</c><c></c>
<c>34</c><c>te</c><c></c>
<c>35</c><c>upgrade</c><c></c>
<c>36</c><c>via</c><c></c>
<c>37</c><c>warning</c><c></c>
</texttable>
</section>
<section title="Responses">
<t>
The following table contains the pre-defined headers used
to initialize the header table used to represent
responses.
</t>
<texttable anchor="initial.headers.response">
<ttcol>Index</ttcol>
<ttcol>Header Name</ttcol>
<ttcol>Header Value</ttcol>
<c>0</c><c>:status</c><c>200</c>
<c>1</c><c>age</c><c></c>
<c>2</c><c>cache-control</c><c></c>
<c>3</c><c>content-length</c><c></c>
<c>4</c><c>content-type</c><c></c>
<c>5</c><c>date</c><c></c>
<c>6</c><c>etag</c><c></c>
<c>7</c><c>expires</c><c></c>
<c>8</c><c>last-modified</c><c></c>
<c>9</c><c>server</c><c></c>
<c>10</c><c>set-cookie</c><c></c>
<c>11</c><c>vary</c><c></c>
<c>12</c><c>via</c><c></c>
<c>13</c><c>access-control-allow-origin</c><c></c>
<c>14</c><c>accept-ranges</c><c></c>
<c>15</c><c>allow</c><c></c>
<c>16</c><c>connection</c><c></c>
<c>17</c><c>content-disposition</c><c></c>
<c>18</c><c>content-encoding</c><c></c>
<c>19</c><c>content-language</c><c></c>
<c>20</c><c>content-location</c><c></c>
<c>21</c><c>content-md5</c><c></c>
<c>22</c><c>content-range</c><c></c>
<c>23</c><c>link</c><c></c>
<c>24</c><c>location</c><c></c>
<c>25</c><c>p3p</c><c></c>
<c>26</c><c>pragma</c><c></c>
<c>27</c><c>proxy-authenticate</c><c></c>
<c>28</c><c>refresh</c><c></c>
<c>29</c><c>retry-after</c><c></c>
<c>30</c><c>strict-transport-security</c><c></c>
<c>31</c><c>trailer</c><c></c>
<c>32</c><c>transfer-encoding</c><c></c>
<c>33</c><c>warning</c><c></c>
<c>34</c><c>www-authenticate</c><c></c>
</texttable>
</section>
</section>
<section title="Example" anchor="example">
<t>
Here is an example that illustrates different representations
and how tables are updated.
</t>
<section title="First header set">
<t>
The first header set to represent is the following:
<figure><artwork type="message/http" x:indent-with=" ">
path: /my-example/index.html
user-agent: my-user-agent
x-my-header: first
</artwork></figure>
The header table is empty, all headers are represented as
literal headers with indexing. The 'x-my-header' header
name is not in the header name table and is encoded
literally. This gives the following representation:
<figure><artwork type="message/http" x:indent-with=" ">
0x44 (literal header with incremental indexing, name index = 3)
0x16 (header value string length = 22)
/my-example/index.html
0x4D (literal header with incremental indexing, name index = 12)
0x0D (header value string length = 13)
my-user-agent
0x40 (literal header with incremental indexing, new name)
0x0B (header name string length = 11)
x-my-header
0x05 (header value string length = 5)
first
</artwork></figure>
The header table is as follows after the processing of
these headers:
<figure><artwork type="inline">
Header table
+---------+-----------------+---------------------------+
| Index | Header Name | Header Value |
+---------+-----------------+---------------------------+
| 0 | :scheme | http |
+---------+-----------------+---------------------------+
| 1 | :scheme | https |
+---------+-----------------+---------------------------+
| ... | ... | ... |
+---------+-----------------+---------------------------+
| 37 | warning | |
+---------+-----------------+---------------------------+
| 38 | path | /my-example/index.html | added header
+---------+-----------------+---------------------------+
| 39 | user-agent | my-user-agent | added header
+---------+-----------------+---------------------------+
| 40 | x-my-header | first | added header
+---------+-----------------+---------------------------+
</artwork></figure>
</t>
</section>
<section title="Second header set">
<t>
The second header set to represent is the following:
<figure><artwork type="message/http" x:indent-with=" ">
path: /my-example/resources/script.js
user-agent: my-user-agent
x-my-header: second
</artwork></figure>
The url header is represented as a literal header with
substitution indexing. The user-agent header will be
represented as an indexed header. The x-my-header will be
represented as a literal header with incremental indexing.
<figure><artwork type="message/http" x:indent-with=" ">
0x04 (delta header with substitution indexing, name index = 3)
0x26 (replaced entry index = 38)
0x1f (header value string length = 31)
/my-example/resources/script.js
0x7f 0x08 (indexed header, index = 39)
0x5f 0x09 (literal header with indexing, name index = 40)
0x06 (header value string length = 6)
second
</artwork></figure>
The header table is updated as follow:
<figure><artwork type="inline">
Header table
+---------+-----------------+---------------------------+
| Index | Header Name | Header Value |
+---------+-----------------+---------------------------+
| 0 | :scheme | http |
+---------+-----------------+---------------------------+
| 1 | :scheme | https |
+---------+-----------------+---------------------------+
| ... | ... | ... |
+---------+-----------------+---------------------------+
| 37 | warning | |
+---------+-----------------+---------------------------+
| 38 | path | /my-example/resources/ |
| | | script.js | replaced header
+---------+-----------------+---------------------------+
| 39 | user-agent | my-user-agent |
+---------+-----------------+---------------------------+
| 40 | x-my-header | first |
+---------+-----------------+---------------------------+
| 41 | x-my-header | second | added header
+---------+-----------------+---------------------------+
</artwork></figure>
</t>
</section>
</section>
</back>
</rfc>
<!--
vim:et:tw=78:sw=4:
-->