idnits 2.17.1 draft-snell-httpbis-bohe-13.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an Introduction section. ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year == The document seems to lack the recommended RFC 2119 boilerplate, even if it appears to use RFC 2119 keywords. (The document does seem to have the reference to RFC 2119 which the ID-Checklist requires). -- The document date (August 14, 2013) is 3907 days in the past. Is this intentional? Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '1' on line 343 -- Looks like a reference, but probably isn't: '64' on line 343 == Unused Reference: 'RFC2119' is defined on line 390, but no explicit reference was found in the text == Unused Reference: 'RFC3629' is defined on line 393, but no explicit reference was found in the text == Unused Reference: 'RFC6265' is defined on line 403, but no explicit reference was found in the text == Outdated reference: A later version (-12) exists of draft-ietf-httpbis-header-compression-01 == Outdated reference: A later version (-26) exists of draft-ietf-httpbis-p1-messaging-23 Summary: 2 errors (**), 0 flaws (~~), 7 warnings (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group J. Snell 3 Internet-Draft 4 Intended status: Informational August 14, 2013 5 Expires: February 15, 2014 7 HTTP/2.0 Discussion: Stored Header Encoding 8 draft-snell-httpbis-bohe-13 10 Abstract 12 This memo describes a proposed alternative optimized encoding for 13 ordered sets of header field (name,value) pairs in HTTP/2 HEADERS and 14 PUSH_PROMISE frames. 16 Status of This Memo 18 This Internet-Draft is submitted in full conformance with the 19 provisions of BCP 78 and BCP 79. 21 Internet-Drafts are working documents of the Internet Engineering 22 Task Force (IETF). Note that other groups may also distribute 23 working documents as Internet-Drafts. The list of current Internet- 24 Drafts is at http://datatracker.ietf.org/drafts/current/. 26 Internet-Drafts are draft documents valid for a maximum of six months 27 and may be updated, replaced, or obsoleted by other documents at any 28 time. It is inappropriate to use Internet-Drafts as reference 29 material or to cite them other than as "work in progress." 31 This Internet-Draft will expire on February 15, 2014. 33 Copyright Notice 35 Copyright (c) 2013 IETF Trust and the persons identified as the 36 document authors. All rights reserved. 38 This document is subject to BCP 78 and the IETF Trust's Legal 39 Provisions Relating to IETF Documents 40 (http://trustee.ietf.org/license-info) in effect on the date of 41 publication of this document. Please review these documents 42 carefully, as they describe your rights and restrictions with respect 43 to this document. Code Components extracted from this document must 44 include Simplified BSD License text as described in Section 4.e of 45 the Trust Legal Provisions and are provided without warranty as 46 described in the Simplified BSD License. 48 Table of Contents 50 1. Stored Header Encoding . . . . . . . . . . . . . . . . . . . 2 51 2. Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 52 3. Header Encoding and Decoding . . . . . . . . . . . . . . . . 3 53 3.1. Literal (name,value) Representation . . . . . . . . . . . 5 54 3.1.1. Dealing with invalid name or value encodings . . . . 7 55 3.2. Indexed Representation . . . . . . . . . . . . . . . . . 7 56 3.3. Non-Indexed Literal Representation . . . . . . . . . . . 8 57 3.4. Indexed Literal Representation . . . . . . . . . . . . . 8 58 4. Unsigned Variable Length Integer Syntax . . . . . . . . . . . 8 59 5. Security Considerations . . . . . . . . . . . . . . . . . . . 9 60 6. References . . . . . . . . . . . . . . . . . . . . . . . . . 9 61 6.1. Normative References . . . . . . . . . . . . . . . . . . 9 62 6.2. Informational References . . . . . . . . . . . . . . . . 9 63 Appendix A. Initial Cache Entries . . . . . . . . . . . . . . . 9 64 Appendix B. Updated Standard Header Definitions . . . . . . . . 11 65 Appendix C. Example . . . . . . . . . . . . . . . . . . . . . . 13 66 C.1. First Header Set: . . . . . . . . . . . . . . . . . . . . 13 67 C.2. Second Header Set: . . . . . . . . . . . . . . . . . . . 14 68 C.3. Third Header Set: . . . . . . . . . . . . . . . . . . . . 15 69 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 15 71 1. Stored Header Encoding 73 The Stored Header Encoding is a proposed alternative "compressed 74 header encoding" for HTTP/2.0 that offers reasonably good compression 75 ratios, support for a range of compressor strategies, efficient value 76 type codecs, constrained state requirements, routing-friendly header 77 value ordering, and easier implementation relative to the current 78 header compression proposal. 80 2. Model 82 A "header" is a (name,value) pair. The name is a sequence of lower- 83 case ASCII characters. The value is either an HTTP 1.1 defined 84 field-value (see [I-D.ietf-httpbis-p1-messaging]), a sequence of 85 UTF-8 encoded octets, an integer, a timestamp, or an opaque sequence 86 of binary octets. 88 The compressor and decompressor each maintain a synchronized cache of 89 up to 256 headers. Every header stored in the cache is referenced by 90 an 8-bit identifier ranging from 0x00-FF (inclusive). 92 The cache is managed in a "least recently written" manner, that is, 93 as the cache fills to capacity in both number of entries and maximum 94 stored byte size, the least recently written items are cleared and 95 their index positions can be reused. 97 The specific index position to which a header is assigned is 98 determined by the encoder using any algorithm the encoder determines 99 to be appropriate. If a specific index position already has an 100 assigned header, the existing header is replaced. 102 The maximum total size of the cache can be limited by the 103 decompressor using the SETTINGS_MAX_BUFFER_SIZE setting. Each stored 104 header contributes a certain number of octets to the total 105 accumulated size of the cache. If adding a new header to the cache 106 will cause the total size to grow beyond the set limit, the least- 107 recently written items are removed in the order written until enough 108 space is available to add the new item. Clearing existing items does 109 not change the index positions of the remaining items in the cache. 111 The SETTINGS_MAX_BUFFER_SIZE setting has an initial default value of 112 4096 bytes. The decompressor can establish a new maximum buffer size 113 at any time, possibly causing header (name,value) pairs to be evicted 114 from the cache if the newly established limit is less than the 115 current total size. 117 The decompressor can disable use of the storage cache completely by 118 setting the SETTINGS_MAX_BUFFER_SIZE setting to 0, forcing the cache 119 to empty completely and making it impossible to add new headers. 121 The size of a header is calculated as: The number of octets required 122 for the name plus the number of octets required for the value plus 123 32-octets to account for any internal storage overhead. The number 124 of octets required for the value depends on the value type: 126 o String values are measured by the number of UTF-8 encoded octets 127 required to represent the character sequence. 129 o Number and Date-Time values are measured by the number of unsigned 130 variable length integer (uvarint) encoded octets required to 131 represent the value using a 5-bit prefix. 133 o Legacy (HTTP/1.1) values are measured by the number of octets 134 required to represent the value. 136 o Binary values are measured by the number of octets contained by 137 the sequence. 139 3. Header Encoding and Decoding 141 The set of headers is encoded for transmission using the following 142 process: 144 1. For each header, determine if the (name,value) pair already 145 exists in the cache. 147 * If an exact match is found in the cache, encode the indexed 148 position of the header as an Indexed Reference and advance to 149 the next header (name,value) pair. 151 * Otherwise, move to step #2. 153 2. Determine if a header (name,value) pair with the same name 154 already exists in the cache. If a matching name is found, make 155 note of the indexed position of the matching name and continue to 156 step #3. 158 3. Determine whether the new header (name,value) pair ought to be 159 assigned to the cache. 161 * If the header is not to be cached, encode the header as a Non- 162 Indexed Literal Representation and continue to the next header 163 (name,value) pair. 165 * Otherwise, assign an index position for the header 166 (name,value) pair and encode the header as an Indexed Literal 167 Representation. 169 Following these steps, headers are serialized into one of four 170 representation types, each represented by a two-bit prefix code. The 171 types and their codes are: 173 o 10 - Indexed 175 o 00 - Non-Indexed Literal 177 o 01 - Indexed Literal 179 Headers can be encoded into groups of up to 64 instances. Each group 180 is prefixed by a single octet. The two most significant bits of this 181 prefix identify the representation type, the six remaining bits 182 specify the number of instances, with 000000 indicating a single 183 instance and 111111 indicating 64. 185 Decoding simply reverses the encoding steps: 187 1. First initialize an empty working set of headers. 189 2. Begin iterating through each representation group: 191 * If it is an Indexed group, iterate through each index included 192 in the group, look up the corresponding (name,value) pair in 193 the cache and add that to the working set. If no matching 194 (name,value) is found, terminate and report an error. 196 * If it's a Non-Indexed Literal group, iterate through each 197 (name,value) pair included in the group and add that to the 198 working set. 200 * If it's an Indexed Literal group, iterate through each 201 (name,value) pair, assign it to the specified position in the 202 cache and add it to the working set. 204 3. Continue with each representation group until the full block has 205 been decoded. 207 When a single header name is used multiple times with different 208 values, the order in which those values are serialized and processed 209 is significant. The working set created by the decoding process 210 above MUST preserve the ordering of those values as received. 212 3.1. Literal (name,value) Representation 214 The structure of an encoded (name,value) pair consists of: 216 o A 3-bit value type identifier, 218 o The name, encoded either as a literal sequence of ASCII octets or 219 as the cache index position of another existing header sharing the 220 same name, and 222 o The encoded value. 224 The three most-sigificant bits of the first octet identify the value 225 type. 227 This design allows for a maximum of 7 value types, five of which are 228 defined by this specification. The two remaining types are reserved 229 for future use. The currently defined value types are: 231 UTF-8 (000) 233 Integer (001) 235 Timestamp (010) 237 Legacy (100) 238 Opaque Binary (111) 240 Of the five types, the Legacy type is reserved for encoding header 241 values conforming to the field-value construct defined by 242 [I-D.ietf-httpbis-p1-messaging], and is used specifically for 243 backwards compatibility with header fields that have not yet been 244 updated to use a more specific type value (see Appendix B). 246 If the name is encoded using an index reference to another existing 247 (name,value) pair in the cache, the remaining five least significant 248 bits of the first octet are set to zero and the next octet identifies 249 the referenced cache index position. This octet MUST NOT reference a 250 cache index position that is not currently assigned. 252 If the name is encoded as a sequence of ASCII octets, the number of 253 octets required to represent the name is encoded as a unsigned 254 variable length integer with a five-bit prefix, filling the 255 5-remaining least significant bits of the first octet, followed by 256 the sequence of ASCII octets conforming to the following header-name 257 construct: 259 Header name ABNF: 261 header-name = [":"] 1*header-char 263 header-char = "!" / "#" / "$" / "%" / "&" / "'" / 264 "*" / "+" / "-" / "." / "^" / "_" / 265 "`" / "|" / "~" / DIGIT / LOWERALPHA 267 LOWERALPHA = %x61-7A 269 The encoding of the value depends on the value type. 271 UTF-8: 272 First, the number of UTF-8 encoded bytes required to represent the 273 value is encoded as an unsigned variable length integer with a 274 0-bit prefix, followed by the full sequence of UTF-8 octets. 276 Integer 277 Integer values ranging from 0 to 2^64-1 are encoded as unsigned 278 variable length integers with a 0-bit prefix. Negative or 279 fractional numbers cannot be represented. 281 Timestamp 282 Timestamps is represented as the number of milliseconds ellapsed 283 since the standard Epoch (1970-01-01T00:00:00 GMT), encoded as an 284 unsigned variable length integer with a 0-bit prefix. Timestamps 285 that predate the Epoch cannot be represented. 287 Legacy 288 First, the number of octets required to represent the value is 289 encoded as an unsigned variable length integer with a 0-bit 290 prefix, followed by the full sequence of octets. 292 Opaque 293 The number of octets in the sequence is encoded as an unsigned 294 variable length integer with a 0-bit prefix, followed by the full 295 sequence of octets. 297 3.1.1. Dealing with invalid name or value encodings 299 Implementations encountering invalid name or value encodings MUST 300 signal an error and terminate processing of the header block. 301 Examples of such errors include: 303 o Header names that include any octets not explicitly permitted by 304 the above header-name ABNF construction; 306 o UTF-8 values that include a byte order mark, over-long or invalid 307 octet sequences, or octets representing invalid Unicode 308 codepoints; 310 o Integer or Date-Time values that encode numbers strictly larger 311 than 2^64-1; 313 3.2. Indexed Representation 315 The serialization of an Indexed Representation consists of a single 316 octet prefix followed by up to 64 single-octet cache index position 317 references. 319 +--------+--------+ +---------+ 320 |10xxxxxx| IDX[1] | ... | IDX[64] | 321 +--------+--------- +---------+ 323 For instance: 325 0x80 0x00 326 References item #0 from the cache. 328 0x81 0x00 0x01 329 References items #0 and #1 from the cache. 331 Indexed Representations do not cause the cache state to be modified 332 in any way. If an Indexed References specifies an index position 333 that has not yet been assigned or whose value has been cleared, 334 decoding MUST terminate with an error. 336 3.3. Non-Indexed Literal Representation 338 The serialization of a group of Non-Indexed Literal representations 339 consists of a single-octet prefix followed by up to 64 Literal 340 (name,value) Representations. 342 +--------+-----------------+ +------------------+ 343 |00xxxxxx| (name,value)[1] | ... | (name,value)[64] | 344 +--------+-----------------+ +------------------+ 346 For instance: 348 0x00 0x01 0x61 0x01 0x62 349 Specifies a single header with name "a" and a UTF-8 value of "b" 350 is to be handled as a Non-Indexed header (it is not added to the 351 cache). 353 3.4. Indexed Literal Representation 355 The serialization of a group of Indexed Literal representations 356 consists of a single-octet prefix followed by up to 64 (index 357 position, Literal (name,value) representation) pairs. 359 +--------+------+---------------+ +-------+----------------+ 360 |01xxxxxx|IDX[1]|(name,value)[1]| ... |IDX[64]|(name,value)[64]| 361 +--------+------+---------------+ +-------+----------------+ 363 For instance: 365 0x40 0x03 0x01 0x61 0x01 0x62 366 Specifies that a single header with name "a" and a UTF-8 String 367 value of "b" is to be assigned to the cache at index position #3. 369 0x40 0x03 0x21 0x61 0x04 370 Specifies that a single header with name "a" and Integer value of 371 3 is to be assigned to the cache at index position #4. 373 4. Unsigned Variable Length Integer Syntax 374 Unsigned integers are encoded as defined in 375 [I-D.ietf-httpbis-header-compression]. 377 5. Security Considerations 379 TBD 381 6. References 383 6.1. Normative References 385 [I-D.ietf-httpbis-header-compression] 386 Peon, R. and H. Ruellan, "HTTP/2.0 Header Compression", 387 draft-ietf-httpbis-header-compression-01 (work in 388 progress), July 2013. 390 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 391 Requirement Levels", BCP 14, RFC 2119, March 1997. 393 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 394 10646", STD 63, RFC 3629, November 2003. 396 6.2. Informational References 398 [I-D.ietf-httpbis-p1-messaging] 399 Fielding, R. and J. Reschke, "Hypertext Transfer Protocol 400 (HTTP/1.1): Message Syntax and Routing", draft-ietf- 401 httpbis-p1-messaging-23 (work in progress), July 2013. 403 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, 404 April 2011. 406 Appendix A. Initial Cache Entries 408 +-------+-----------------------------+-------+---------+ 409 | Index | Name | Value | Type | 410 +-------+-----------------------------+-------+---------+ 411 | 0 | :scheme | http | Text | 412 | 1 | :scheme | https | Text | 413 | 2 | :host | | | 414 | 3 | :path | / | | 415 | 4 | :method | GET | Text | 416 | 5 | accept | | | 417 | 6 | accept-charset | | | 418 | 7 | accept-encoding | | | 419 | 8 | accept-language | | | 420 | 9 | cookie | | | 421 | 10 | if-modified-since | | | 422 | 11 | keep-alive | | | 423 | 12 | user-agent | | | 424 | 13 | proxy-connection | | | 425 | 14 | referer | | | 426 | 15 | accept-datetime | | | 427 | 16 | authorization | | | 428 | 17 | allow | | | 429 | 18 | cache-control | | | 430 | 19 | connection | | | 431 | 20 | content-length | | | 432 | 21 | content-md5 | | | 433 | 22 | content-type | | | 434 | 23 | date | | | 435 | 24 | expect | | | 436 | 25 | from | | | 437 | 26 | if-match | | | 438 | 27 | if-none-match | | | 439 | 28 | if-range | | | 440 | 29 | if-unmodified-since | | | 441 | 30 | max-forwards | | | 442 | 31 | pragma | | | 443 | 32 | proxy-authorization | | | 444 | 33 | range | | | 445 | 34 | te | | | 446 | 35 | upgrade | | | 447 | 36 | via | | | 448 | 37 | warning | | | 449 | 38 | :status | 200 | Integer | 450 | 39 | age | | | 451 | 40 | cache-control | | | 452 | 41 | content-length | | | 453 | 42 | content-type | | | 454 | 43 | date | | | 455 | 44 | etag | | | 456 | 45 | expires | | | 457 | 46 | last-modified | | | 458 | 47 | server | | | 459 | 48 | set-cookie | | | 460 | 49 | vary | | | 461 | 50 | via | | | 462 | 51 | access-control-allow-origin | | | 463 | 52 | accept-ranges | | | 464 | 53 | allow | | | 465 | 54 | connection | | | 466 | 55 | content-disposition | | | 467 | 56 | content-encoding | | | 468 | 57 | content-language | | | 469 | 58 | content-location | | | 470 | 59 | content-md5 | | | 471 | 60 | content-range | | | 472 | 61 | link | | | 473 | 62 | location | | | 474 | 63 | p3p | | | 475 | 64 | pragma | | | 476 | 65 | proxy-authenticate | | | 477 | 66 | refresh | | | 478 | 67 | retry-after | | | 479 | 68 | strict-transport-security | | | 480 | 69 | trailer | | | 481 | 70 | transfer-encoding | | | 482 | 71 | warning | | | 483 | 72 | www-authenticate | | | 484 | 73 | user-agent | | | 485 +-------+-----------------------------+-------+---------+ 487 Appendix B. Updated Standard Header Definitions 489 To properly deal with the backwards compatibility concerns for HTTP/ 490 1, there are several important rules for use of Typed Codecs in HTTP 491 headers: 493 o All header fields MUST be explicitly defined to use the new header 494 types. All existing HTTP/1 header fields will continue to be 495 represented in conformance to the field-value construct defined by 496 [I-D.ietf-httpbis-p1-messaging] unless their specific definitions 497 are updated. Such fields MUST specify the Legacy value type when 498 serialized. The HTTP/2 specification would update the definitions 499 of specific known header fields (e.g. content-length, date, if- 500 modified-since, etc). 502 o For translation to HTTP/1.1, header fields that use the typed 503 codecs will have specific normative transformations defined. 505 * UTF-8 will be converted to ISO-8859-1 with extended characters 506 pct-encoded 508 * Numbers will be converted to their ASCII equivalent values. 510 * Date Times will be converted to their HTTP-Date equivalent 511 values. 513 * Opaque fields will be Base64-encoded. 515 * Legacy fields are passed through untranslated. 517 o There will be no normative transformation from legacy values into 518 the typed codecs. Implementations are free to apply 519 transformation where they determine it to be appropriate, but it 520 will be perfectly acceptable for an implementation to pass a text 521 value through as a Legacy type even if it is known that a given 522 header has a typed codec equivalent. 524 A Note of warning: Individual header fields MAY be defined such that 525 they can be represented using multiple types. Numeric fields, for 526 instance, can be represented using either the uvarint encoding or 527 using the equivalent sequence of ASCII numbers. Implementers will 528 need to be capable of supporting each of the possible variations. 529 Designers of header field definitions need to be aware of the 530 additional complexity and possible issues that allowing for such 531 alternatives can introduce for implementers. 533 Based on an initial survey of header fields currently defined by the 534 HTTPbis specification documents, the following header field 535 definitions can be updated to make use of the new types 537 +---------------------+---------------+-----------------------------+ 538 | Field | Type | Description | 539 +---------------------+---------------+-----------------------------+ 540 | content-length | Numeric or | Can be represented as | 541 | | Text | either an unsigned, | 542 | | | variable-length integer or | 543 | | | a sequence of ASCII | 544 | | | numbers. | 545 | date | Timestamp or | Can be represented as | 546 | | Text | either a uvarint encoded | 547 | | | timestamp or as text (HTTP- | 548 | | | date). | 549 | max-forwards | Numeric or | Can be represented as | 550 | | Text | either an unsigned, | 551 | | | variable-length integer or | 552 | | | a sequence of ASCII | 553 | | | numbers. | 554 | retry-after | Timestamp, | Can be represented as | 555 | | Numeric or | either a uvarint encoded | 556 | | Text | timestamp, an unsigned, | 557 | | | variable-length integer, or | 558 | | | the text equivalents of | 559 | | | either (HTTP-date or | 560 | | | sequence of ASCII numbers) | 561 | if-modified-since | Timestamp or | Can be represented as | 562 | | Text | either a uvarint encoded | 563 | | | timestamp or as text (HTTP- | 564 | | | date). | 565 | if-unmodified-since | Timestamp or | Can be represented as | 566 | | Text | either a uvarint encoded | 567 | | | timestamp or as text (HTTP- | 568 | | | date). | 569 | last-modified | Timestamp or | Can be represented as | 570 | | Text | either a uvarint encoded | 571 | | | timestamp or as text (HTTP- | 572 | | | date). | 573 | age | Numeric or | Can be represented as | 574 | | Text | either an unsigned, | 575 | | | variable-length integer or | 576 | | | a sequence of ASCII | 577 | | | numbers. | 578 | expires | Timestamp or | Can be represented as | 579 | | Text | either a uvarint encoded | 580 | | | timestamp or as text (HTTP- | 581 | | | date). | 582 | etag | Binary or | Can be represented as | 583 | | Text | either an opaque sequence | 584 | | | of binary octets or using | 585 | | | the currently defined text | 586 | | | format. When represented as | 587 | | | binary octets, the Entity | 588 | | | Tag MUST be considered to | 589 | | | be a Strong Entity tag. | 590 | | | Weak Entity Tags cannot be | 591 | | | represented using the | 592 | | | binary octet option. | 593 +---------------------+---------------+-----------------------------+ 595 Appendix C. Example 597 C.1. First Header Set: 599 The first header set to represent is the following: 601 :path: /my-example/index.html 602 user-agent: my-user-agent 603 x-my-header: first 605 The cache is prefilled as defined in Appendix A, however, none of the 606 values represented in the initial set can be found in the cache. All 607 headers, then, are encoding using the Indexed Literal Representation: 609 43 4a 00 03 16 2f 6d 79 2d 65 610 78 61 6d 70 6c 65 2f 69 6e 64 611 65 78 2e 68 74 6d 6c 4B 00 49 612 6d 79 2d 75 73 65 72 2d 61 67 613 65 6e 74 4c 0b 78 2d 6d 79 2d 614 68 65 61 64 65 72 05 66 69 72 615 73 74 617 Three new entries are added to the cache: 619 +-------+-------------+------------------------+ 620 | Index | Name | Value | 621 +-------+-------------+------------------------+ 622 | 74 | :path | /my-example/index.html | 623 | 75 | user-agent | my-user-agent | 624 | 76 | x-my-header | first | 625 +-------+-------------+------------------------+ 627 C.2. Second Header Set: 629 The second header set to represent is the following: 631 :path: /my-example/resources/script.js 632 user-agent: my-user-agent 633 x-my-header: second 635 Comparing this second header set to the first, we see that the :path 636 and x-my-header headers have new values, while the user-agent value 637 remains unchanged. 639 80 4b 41 4a 00 4a 1f 2f 6d 79 640 2d 65 78 61 6d 70 6c 65 2f 72 641 65 73 6f 75 72 63 65 73 2f 73 642 63 72 69 70 74 2e 6a 73 4c 00 643 4c 06 73 65 63 6f 6e 64 645 Items #74 and #76 added by the previous header set are replaced: 647 +-------+-------------+---------------------------------+ 648 | Index | Name | Value | 649 +-------+-------------+---------------------------------+ 650 | 74 | :path | /my-example/resources/script.js | 651 | 75 | user-agent | my-user-agent | 652 | 76 | x-my-header | second | 653 +-------+-------------+---------------------------------+ 655 C.3. Third Header Set: 657 Let's suppose a third header set that is identical to the second is 658 sent: 660 82 4b 4c 4d 662 Author's Address 664 James M Snell 666 Email: jasnell@gmail.com