idnits 2.17.1 draft-ietf-httpbis-header-structure-09.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 : ---------------------------------------------------------------------------- ** There is 1 instance of too long lines in the document, the longest one being 5 characters in excess of 72. ** The abstract seems to contain references ([2], [3], [4], [5], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (December 1, 2018) is 1972 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 1361 -- Looks like a reference, but probably isn't: '2' on line 1363 -- Looks like a reference, but probably isn't: '3' on line 1365 -- Looks like a reference, but probably isn't: '4' on line 1367 -- Looks like a reference, but probably isn't: '5' on line 1369 == Missing Reference: 'RFCxxxx' is mentioned on line 252, but not defined == Missing Reference: 'RFC3986' is mentioned on line 270, but not defined -- Looks like a reference, but probably isn't: '6' on line 1371 -- Looks like a reference, but probably isn't: '7' on line 1451 ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) -- Obsolete informational reference (is this intentional?): RFC 7231 (Obsoleted by RFC 9110) -- Obsolete informational reference (is this intentional?): RFC 7540 (Obsoleted by RFC 9113) Summary: 3 errors (**), 0 flaws (~~), 3 warnings (==), 11 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 HTTP M. Nottingham 3 Internet-Draft Fastly 4 Intended status: Standards Track P-H. Kamp 5 Expires: June 4, 2019 The Varnish Cache Project 6 December 1, 2018 8 Structured Headers for HTTP 9 draft-ietf-httpbis-header-structure-09 11 Abstract 13 This document describes a set of data types and algorithms associated 14 with them that are intended to make it easier and safer to define and 15 handle HTTP header fields. It is intended for use by new 16 specifications of HTTP header fields as well as revisions of existing 17 header field specifications when doing so does not cause 18 interoperability issues. 20 Note to Readers 22 _RFC EDITOR: please remove this section before publication_ 24 Discussion of this draft takes place on the HTTP working group 25 mailing list (ietf-http-wg@w3.org), which is archived at 26 https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. 28 Working Group information can be found at https://httpwg.github.io/ 29 [2]; source code and issues list for this draft can be found at 30 https://github.com/httpwg/http-extensions/labels/header-structure 31 [3]. 33 Tests for implementations are collected at https://github.com/httpwg/ 34 structured-header-tests [4]. 36 Implementations are tracked at https://github.com/httpwg/wiki/wiki/ 37 Structured-Headers [5]. 39 Status of This Memo 41 This Internet-Draft is submitted in full conformance with the 42 provisions of BCP 78 and BCP 79. 44 Internet-Drafts are working documents of the Internet Engineering 45 Task Force (IETF). Note that other groups may also distribute 46 working documents as Internet-Drafts. The list of current Internet- 47 Drafts is at https://datatracker.ietf.org/drafts/current/. 49 Internet-Drafts are draft documents valid for a maximum of six months 50 and may be updated, replaced, or obsoleted by other documents at any 51 time. It is inappropriate to use Internet-Drafts as reference 52 material or to cite them other than as "work in progress." 54 This Internet-Draft will expire on June 4, 2019. 56 Copyright Notice 58 Copyright (c) 2018 IETF Trust and the persons identified as the 59 document authors. All rights reserved. 61 This document is subject to BCP 78 and the IETF Trust's Legal 62 Provisions Relating to IETF Documents 63 (https://trustee.ietf.org/license-info) in effect on the date of 64 publication of this document. Please review these documents 65 carefully, as they describe your rights and restrictions with respect 66 to this document. Code Components extracted from this document must 67 include Simplified BSD License text as described in Section 4.e of 68 the Trust Legal Provisions and are provided without warranty as 69 described in the Simplified BSD License. 71 Table of Contents 73 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 74 1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 75 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 76 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 77 3. Structured Header Data Types . . . . . . . . . . . . . . . . 7 78 3.1. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 7 79 3.2. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 7 80 3.3. Lists of Lists . . . . . . . . . . . . . . . . . . . . . 8 81 3.4. Parameterised Lists . . . . . . . . . . . . . . . . . . . 8 82 3.5. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 9 83 3.6. Integers . . . . . . . . . . . . . . . . . . . . . . . . 9 84 3.7. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 9 85 3.8. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 10 86 3.9. Tokens . . . . . . . . . . . . . . . . . . . . . . . . . 11 87 3.10. Byte Sequences . . . . . . . . . . . . . . . . . . . . . 11 88 3.11. Booleans . . . . . . . . . . . . . . . . . . . . . . . . 11 89 4. Structured Headers in HTTP/1 . . . . . . . . . . . . . . . . 12 90 4.1. Serialising Structured Headers into HTTP/1 . . . . . . . 12 91 4.2. Parsing HTTP/1 Header Fields into Structured Headers . . 18 92 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 93 6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 94 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 28 95 7.1. Normative References . . . . . . . . . . . . . . . . . . 28 96 7.2. Informative References . . . . . . . . . . . . . . . . . 28 97 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 29 98 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 29 99 Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 29 100 B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 30 101 B.2. Structured Headers don't "fit" my data. . . . . . . . . . 30 102 B.3. What should generic Structured Headers implementations 103 expose? . . . . . . . . . . . . . . . . . . . . . . . . . 31 104 Appendix C. Changes . . . . . . . . . . . . . . . . . . . . . . 31 105 C.1. Since draft-ietf-httpbis-header-structure-08 . . . . . . 31 106 C.2. Since draft-ietf-httpbis-header-structure-07 . . . . . . 32 107 C.3. Since draft-ietf-httpbis-header-structure-06 . . . . . . 32 108 C.4. Since draft-ietf-httpbis-header-structure-05 . . . . . . 32 109 C.5. Since draft-ietf-httpbis-header-structure-04 . . . . . . 33 110 C.6. Since draft-ietf-httpbis-header-structure-03 . . . . . . 33 111 C.7. Since draft-ietf-httpbis-header-structure-02 . . . . . . 33 112 C.8. Since draft-ietf-httpbis-header-structure-01 . . . . . . 33 113 C.9. Since draft-ietf-httpbis-header-structure-00 . . . . . . 33 114 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 34 116 1. Introduction 118 Specifying the syntax of new HTTP header fields is an onerous task; 119 even with the guidance in [RFC7231], Section 8.3.1, there are many 120 decisions - and pitfalls - for a prospective HTTP header field 121 author. 123 Once a header field is defined, bespoke parsers and serialisers often 124 need to be written, because each header has slightly different 125 handling of what looks like common syntax. 127 This document introduces a set of common data structures for use in 128 HTTP header field values to address these problems. In particular, 129 it defines a generic, abstract model for header field values, along 130 with a concrete serialisation for expressing that model in HTTP/1 131 [RFC7230] header fields. 133 HTTP headers that are defined as "Structured Headers" use the types 134 defined in this specification to define their syntax and basic 135 handling rules, thereby simplifying both their definition by 136 specification writers and handling by implementations. 138 Additionally, future versions of HTTP can define alternative 139 serialisations of the abstract model of these structures, allowing 140 headers that use it to be transmitted more efficiently without being 141 redefined. 143 Note that it is not a goal of this document to redefine the syntax of 144 existing HTTP headers; the mechanisms described herein are only 145 intended to be used with headers that explicitly opt into them. 147 To specify a header field that is a Structured Header, see Section 2. 149 Section 3 defines a number of abstract data types that can be used in 150 Structured Headers. 152 Those abstract types can be serialised into and parsed from textual 153 headers - such as those used in HTTP/1 - using the algorithms 154 described in Section 4. 156 1.1. Intentionally Strict Processing 158 This specification intentionally defines strict parsing and 159 serialisation behaviours using step-by-step algorithms; the only 160 error handling defined is to fail the operation altogether. 162 This is designed to encourage faithful implementation and therefore 163 good interoperability. Therefore, implementations that try to be 164 "helpful" by being more tolerant of input are doing a disservice to 165 the overall community, since it will encourage other implementations 166 to implement similar (but likely subtly different) workarounds. 168 In other words, strict processing is an intentional feature of this 169 specification; it allows non-conformant input to be discovered and 170 corrected early, and avoids both interoperability and security issues 171 that might otherwise result. 173 Note that as a result of this strictness, if a header field is 174 appended to by multiple parties (e.g., intermediaries, or different 175 components in the sender), it could be that an error in one party's 176 value causes the entire header field to fail parsing. 178 1.2. Notational Conventions 180 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 181 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 182 "OPTIONAL" in this document are to be interpreted as described in BCP 183 14 [RFC2119] [RFC8174] when, and only when, they appear in all 184 capitals, as shown here. 186 This document uses the Augmented Backus-Naur Form (ABNF) notation of 187 [RFC5234], including the VCHAR, SP, DIGIT, ALPHA and DQUOTE rules 188 from that document. It also includes the OWS rule from [RFC7230]. 190 This document uses algorithms to specify parsing and serialisation 191 behaviours, and ABNF to illustrate expected syntax in HTTP/1-style 192 header fields. 194 For parsing from HTTP/1 header fields, implementations MUST follow 195 the algorithms, but MAY vary in implementation so as the behaviours 196 are indistinguishable from specified behaviour. If there is 197 disagreement between the parsing algorithms and ABNF, the specified 198 algorithms take precedence. In some places, the algorithms are 199 "greedy" with whitespace, but this should not affect conformance. 201 For serialisation to HTTP/1 header fields, the ABNF illustrates the 202 range of acceptable wire representations with as much fidelity as 203 possible, and the algorithms define the recommended way to produce 204 them. Implementations MAY vary from the specified behaviour so long 205 as the output still matches the ABNF. 207 2. Defining New Structured Headers 209 To define a HTTP header as a structured header, its specification 210 needs to: 212 o Reference this specification. Recipients and generators of the 213 header need to know that the requirements of this document are in 214 effect. 216 o Specify the header field's allowed syntax for values, in terms of 217 the types described in Section 3, along with their associated 218 semantics. Syntax definitions are encouraged to use the ABNF 219 rules beginning with "sh-" defined in this specification. 221 o Specify any additional constraints upon the syntax of the 222 structured used, as well as the consequences when those 223 constraints are violated. When Structured Headers parsing fails, 224 the header is discarded (see Section 4.2); in most situations, 225 header-specific constraints should do likewise. 227 Note that a header field definition cannot relax the requirements of 228 a structure or its processing because doing so would preclude 229 handling by generic software; they can only add additional 230 constraints. Likewise, header field definitions should use 231 Structured Headers for the entire header field value, not a portion 232 thereof. 234 For example: 236 # Foo-Example Header 238 The Foo-Example HTTP header field conveys information about how 239 much Foo the message has. 241 Foo-Example is a Structured Header [RFCxxxx]. Its value MUST be a 242 dictionary ([RFCxxxx], Section Y.Y). Its ABNF is: 244 Foo-Example = sh-dictionary 246 The dictionary MUST contain: 248 * Exactly one member whose key is "foo", and whose value is an 249 integer ([RFCxxxx], Section Y.Y), indicating the number of foos 250 in the message. 251 * Exactly one member whose key is "barUrls", and whose value is a 252 string ([RFCxxxx], Section Y.Y), conveying the Bar URLs for the 253 message. See below for processing requirements. 255 If the parsed header field does not contain both, it MUST be 256 ignored. 258 "foo" MUST be between 0 and 10, inclusive; other values MUST cause 259 the header to be ignored. 261 "barUrls" contains a space-separated list of URI-references 262 ([RFC3986], Section 4.1): 264 barURLs = URI-reference *( 1*SP URI-reference ) 266 If a member of barURLs is not a valid URI-reference, it MUST cause 267 that value to be ignored. 269 If a member of barURLs is a relative reference ([RFC3986], 270 Section 4.2), it MUST be resolved ([RFC3986], Section 5) before 271 being used. 273 This specification defines minimums for the length or number of 274 various structures supported by Structured Headers implementations. 275 It does not specify maximum sizes in most cases, but header authors 276 should be aware that HTTP implementations do impose various limits on 277 the size of individual header fields, the total number of fields, 278 and/or the size of the entire header block. 280 3. Structured Header Data Types 282 This section defines the abstract value types that can be composed 283 into Structured Headers. The ABNF provided represents the on-wire 284 format in HTTP/1. 286 3.1. Dictionaries 288 Dictionaries are ordered maps of key-value pairs, where the keys are 289 short, textual strings and the values are items (Section 3.5). There 290 can be one or more members, and keys are required to be unique. 292 Implementations MUST provide access to dictionaries both by index and 293 by key. Specifications MAY use either means of accessing the 294 members. 296 The ABNF for dictionaries in HTTP/1 headers is: 298 sh-dictionary = dict-member *( OWS "," OWS dict-member ) 299 dict-member = member-name "=" member-value 300 member-name = key 301 member-value = sh-item 302 key = lcalpha *( lcalpha / DIGIT / "_" / "-" ) 303 lcalpha = %x61-7A ; a-z 305 In HTTP/1, keys and values are separated by "=" (without whitespace), 306 and key/value pairs are separated by a comma with optional 307 whitespace. For example: 309 Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=* 311 Typically, a header field specification will define the semantics of 312 individual keys, as well as whether their presence is required or 313 optional. Recipients MUST ignore keys that are undefined or unknown, 314 unless the header field's specification specifically disallows them. 316 Parsers MUST support dictionaries containing at least 1024 key/value 317 pairs, and dictionary keys with at least 64 characters. 319 3.2. Lists 321 Lists are arrays of items (Section 3.5) with one or more members. 323 The ABNF for lists in HTTP/1 headers is: 325 sh-list = list-member *( OWS "," OWS list-member ) 326 list-member = sh-item 327 In HTTP/1, each member is separated by a comma and optional 328 whitespace. For example, a header field whose value is defined as a 329 list of strings could look like: 331 Example-StrListHeader: "foo", "bar", "It was the best of times." 333 Header specifications can constrain the types of individual values if 334 necessary. 336 Parsers MUST support lists containing at least 1024 members. 338 3.3. Lists of Lists 340 Lists of Lists are arrays of arrays containing items (Section 3.5). 342 The ABNF for lists of lists in HTTP/1 headers is: 344 sh-listlist = inner-list *( OWS "," OWS inner-list ) 345 inner-list = list-member *( OWS ";" OWS list-member ) 347 In HTTP/1, each inner-list is separated by a comma and optional 348 whitespace, and members of the inner-list are separated by semicolons 349 and optional whitespace. For example, a header field whose value is 350 defined as a list of lists of strings could look like: 352 Example-StrListListHeader: "foo";"bar", "baz", "bat"; "one" 354 Header specifications can constrain the types of individual inner- 355 list values if necessary. 357 Parsers MUST support lists of lists containing at least 1024 members, 358 and inner-lists containing at least 256 members. 360 3.4. Parameterised Lists 362 Parameterised Lists are arrays of parameterised identifier with one 363 or more members. 365 A parameterised identifier is a token (Section 3.9}) with an optional 366 set of parameters, each parameter having a textual name and an 367 optional value that is an item (Section 3.5). Ordering between 368 parameters is not significant, and duplicate parameters MUST cause 369 parsing to fail. 371 The ABNF for parameterised lists in HTTP/1 headers is: 373 sh-param-list = param-item *( OWS "," OWS param-item ) 374 param-item = primary-id *parameter 375 primary-id = sh-token 376 parameter = OWS ";" OWS param-name [ "=" param-value ] 377 param-name = key 378 param-value = sh-item 380 In HTTP/1, each param-id is separated by a comma and optional 381 whitespace (as in Lists), and the parameters are separated by 382 semicolons. For example: 384 Example-ParamListHeader: abc_123;a=1;b=2; cdef_456, ghi;q="9";r="w" 386 Parsers MUST support parameterised lists containing at least 1024 387 members, support members with at least 256 parameters, and support 388 parameter keys with at least 64 characters. 390 3.5. Items 392 An item is can be a integer (Section 3.6), float (Section 3.7), 393 string (Section 3.8), token (Section 3.9}), byte sequence 394 (Section 3.10), or Boolean (Section 3.11). 396 The ABNF for items in HTTP/1 headers is: 398 sh-item = sh-integer / sh-float / sh-string / sh-token / sh-binary 399 / sh-boolean 401 3.6. Integers 403 Integers have a range of -9,223,372,036,854,775,808 to 404 9,223,372,036,854,775,807 inclusive (i.e., a 64-bit signed integer). 406 The ABNF for integers in HTTP/1 headers is: 408 sh-integer = ["-"] 1*19DIGIT 410 For example: 412 Example-IntegerHeader: 42 414 3.7. Floats 416 Floats are integers with a fractional part, that can be stored as 417 IEEE 754 double precision numbers (binary64) ([IEEE754]). 419 The ABNF for floats in HTTP/1 headers is: 421 sh-float = ["-"] ( 422 DIGIT "." 1*14DIGIT / 423 2DIGIT "." 1*13DIGIT / 424 3DIGIT "." 1*12DIGIT / 425 4DIGIT "." 1*11DIGIT / 426 5DIGIT "." 1*10DIGIT / 427 6DIGIT "." 1*9DIGIT / 428 7DIGIT "." 1*8DIGIT / 429 8DIGIT "." 1*7DIGIT / 430 9DIGIT "." 1*6DIGIT / 431 10DIGIT "." 1*5DIGIT / 432 11DIGIT "." 1*4DIGIT / 433 12DIGIT "." 1*3DIGIT / 434 13DIGIT "." 1*2DIGIT / 435 14DIGIT "." 1DIGIT ) 437 For example, a header whose value is defined as a float could look 438 like: 440 Example-FloatHeader: 4.5 442 3.8. Strings 444 Strings are zero or more printable ASCII [RFC0020] characters (i.e., 445 the range 0x20 to 0x7E). Note that this excludes tabs, newlines, 446 carriage returns, etc. 448 The ABNF for strings in HTTP/1 headers is: 450 sh-string = DQUOTE *(chr) DQUOTE 451 chr = unescaped / escaped 452 unescaped = %x20-21 / %x23-5B / %x5D-7E 453 escaped = "\" ( DQUOTE / "\" ) 455 In HTTP/1 headers, strings are delimited with double quotes, using a 456 backslash ("\") to escape double quotes and backslashes. For 457 example: 459 Example-StringHeader: "hello world" 461 Note that strings only use DQUOTE as a delimiter; single quotes do 462 not delimit strings. Furthermore, only DQUOTE and "\" can be 463 escaped; other sequences MUST cause parsing to fail. 465 Unicode is not directly supported in this document, because it causes 466 a number of interoperability issues, and - with few exceptions - 467 header values do not require it. 469 When it is necessary for a field value to convey non-ASCII string 470 content, a byte sequence (Section 3.10) SHOULD be specified, along 471 with a character encoding (preferably UTF-8). 473 Parsers MUST support strings with at least 1024 characters. 475 3.9. Tokens 477 Tokens are short textual words; their abstract model is identical to 478 their expression in the textual HTTP serialisation. 480 The ABNF for tokens in HTTP/1 headers is: 482 sh-token = ALPHA *( ALPHA / DIGIT / "_" / "-" / "." / ":" / "%" / "*" / "/" ) 484 Parsers MUST support tokens with at least 512 characters. 486 3.10. Byte Sequences 488 Byte sequences can be conveyed in Structured Headers. 490 The ABNF for a byte sequence in HTTP/1 headers is: 492 sh-binary = "*" *(base64) "*" 493 base64 = ALPHA / DIGIT / "+" / "/" / "=" 495 In HTTP/1 headers, a byte sequence is delimited with asterisks and 496 encoded using base64 ([RFC4648], Section 4). For example: 498 Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==* 500 Parsers MUST support byte sequences with at least 16384 octets after 501 decoding. 503 3.11. Booleans 505 Boolean values can be conveyed in Structured Headers. 507 The ABNF for a Boolean in HTTP/1 headers is: 509 sh-boolean = "?" boolean 510 boolean = %54 / %46 ; capital "T" or "F" 512 In HTTP/1 headers, a byte sequence is indicated with a leading "?" 513 character. For example: 515 Example-BoolHdr: ?T 517 4. Structured Headers in HTTP/1 519 This section defines how to serialise and parse Structured Headers in 520 HTTP/1 textual header fields, and protocols compatible with them 521 (e.g., in HTTP/2 [RFC7540] before HPACK [RFC7541] is applied). 523 4.1. Serialising Structured Headers into HTTP/1 525 Given a structured defined in this specification: 527 1. If the structure is a dictionary, return the result of 528 Serialising a Dictionary (Section 4.1.1). 530 2. If the structure is a parameterised list, return the result of 531 Serialising a Parameterised List (Section 4.1.4). 533 3. If the structure is a list of lists, return the result of 534 Serialising a List of Lists ({ser-listlist}). 536 4. If the structure is a list, return the result of Serialising a 537 List Section 4.1.2. 539 5. If the structure is an item, return the result of Serialising an 540 Item (Section 4.1.5). 542 6. Otherwise, fail serialisation. 544 4.1.1. Serialising a Dictionary 546 Given a dictionary as input_dictionary: 548 1. Let output be an empty string. 550 2. For each member mem of input_dictionary: 552 1. Let name be the result of applying Serialising an Key 553 (Section 4.1.1.1) to mem's member-name. 555 2. Append name to output. 557 3. Append "=" to output. 559 4. Let value be the result of applying Serialising an Item 560 (Section 4.1.5) to mem's member-value. 562 5. Append value to output. 564 6. If more members remain in input_dictionary: 566 1. Append a COMMA to output. 568 2. Append a single WS to output. 570 3. Return output. 572 4.1.1.1. Serialising a Key 574 Given a key as input_key: 576 1. If input_key is not a sequence of characters, or contains 577 characters not allowed in the ABNF for key, fail serialisation. 579 2. Let output be an empty string. 581 3. Append input_key to output, using ASCII encoding [RFC0020]. 583 4. Return output. 585 4.1.2. Serialising a List 587 Given a list as input_list: 589 1. Let output be an empty string. 591 2. For each member mem of input_list: 593 1. Let value be the result of applying Serialising an Item 594 (Section 4.1.5) to mem. 596 2. Append value to output. 598 3. If more members remain in input_list: 600 1. Append a COMMA to output. 602 2. Append a single WS to output. 604 3. Return output. 606 4.1.3. Serialising a List of Lists 608 Given a list of lists of items as input_list: 610 1. Let output be an empty string. 612 2. For each member inner_list of input_list: 614 1. If inner_list is not a list, fail serialisation. 616 2. If inner_list is empty, fail serialisation. 618 3. For each inner_mem of inner_list: 620 1. Let value be the result of applying Serialising an Item 621 (Section 4.1.5) to inner_mem. 623 2. Append value to output. 625 3. If more members remain in inner_list: 627 1. Append a ";" to output. 629 2. Append a single WS to output. 631 4. If more members remain in input_list: 633 1. Append a COMMA to output. 635 2. Append a single WS to output. 637 3. Return output. 639 4.1.4. Serialising a Parameterised List 641 Given a parameterised list as input_plist: 643 1. Let output be an empty string. 645 2. For each member mem of input_plist: 647 1. Let id be the result of applying Serialising a Token 648 (Section 4.1.9) to mem's token. 650 2. Append id to output. 652 3. For each parameter in mem's parameters: 654 1. Append ";" to output. 656 2. Let name be the result of applying Serialising a Key 657 (Section 4.1.1.1) to parameter's param-name. 659 3. Append name to output. 661 4. If parameter has a param-value: 663 1. Let value be the result of applying Serialising an 664 Item (Section 4.1.5) to parameter's param-value. 666 2. Append "=" to output. 668 3. Append value to output. 670 4. If more members remain in input_plist: 672 1. Append a COMMA to output. 674 2. Append a single WS to output. 676 3. Return output. 678 4.1.5. Serialising an Item 680 Given an item as input_item: 682 1. If input_item is an integer, return the result of applying 683 Serialising an Integer (Section 4.1.6) to input_item. 685 2. If input_item is a float, return the result of applying 686 Serialising a Float (Section 4.1.7) to input_item. 688 3. If input_item is a string, return the result of applying 689 Serialising a String (Section 4.1.8) to input_item. 691 4. If input_item is a token, return the result of Serialising a 692 Token (Section 4.1.9) to input_item. 694 5. If input_item is a Boolean, return the result of applying 695 Serialising a Boolean (Section 4.1.11) to input_item. 697 6. If input_item is a byte sequence, return the result of applying 698 Serialising a Byte Sequence (Section 4.1.10) to input_item. 700 7. Otherwise, fail serialisation. 702 4.1.6. Serialising an Integer 704 Given an integer as input_integer: 706 1. If input_integer is not an integer in the range of 707 -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 708 inclusive, fail serialisation. 710 2. Let output be an empty string. 712 3. If input_integer is less than (but not equal to) 0, append "-" to 713 output. 715 4. Append input_integer's numeric value represented in base 10 using 716 only decimal digits to output. 718 5. Return output. 720 4.1.7. Serialising a Float 722 Given a float as input_float: 724 1. If input_float is not a IEEE 754 double precision number, fail 725 serialisation. 727 2. Let output be an empty string. 729 3. If input_float is less than (but not equal to) 0, append "-" to 730 output. 732 4. Append input_float's integer component represented in base 10 733 using only decimal digits to output; if it is zero, append "0". 735 5. Append "." to output. 737 6. Append input_float's decimal component represented in base 10 738 using only decimal digits to output; if it is zero, append "0". 740 7. Return output. 742 4.1.8. Serialising a String 744 Given a string as input_string: 746 1. If input_string is not a sequence of characters, or contains 747 characters outside the range allowed by VCHAR or SP, fail 748 serialisation. 750 2. Let output be an empty string. 752 3. Append DQUOTE to output. 754 4. For each character char in input_string: 756 1. If char is "\" or DQUOTE: 758 1. Append "\" to output. 760 2. Append char to output, using ASCII encoding [RFC0020]. 762 5. Append DQUOTE to output. 764 6. Return output. 766 4.1.9. Serialising a Token 768 Given a token as input_token: 770 1. If input_token is not a sequence of characters, or contains 771 characters not allowed in Section 3.9}, fail serialisation. 773 2. Let output be an empty string. 775 3. Append input_token to output, using ASCII encoding [RFC0020]. 777 4. Return output. 779 4.1.10. Serialising a Byte Sequence 781 Given a byte sequence as input_bytes: 783 1. If input_bytes is not a sequence of bytes, fail serialisation. 785 2. Let output be an empty string. 787 3. Append "*" to output. 789 4. Append the result of base64-encoding input_bytes as per 790 [RFC4648], Section 4, taking account of the requirements below. 792 5. Append "*" to output. 794 6. Return output. 796 The encoded data is required to be padded with "=", as per [RFC4648], 797 Section 3.2. 799 Likewise, encoded data SHOULD have pad bits set to zero, as per 800 [RFC4648], Section 3.5, unless it is not possible to do so due to 801 implementation constraints. 803 4.1.11. Serialising a Boolean 805 Given a Boolean as input_boolean: 807 1. If input_boolean is not a boolean, fail serialisation. 809 2. Let output be an empty string. 811 3. Append "?" to output. 813 4. If input_boolean is true, append "T" to output. 815 5. If input_boolean is false, append "F" to output. 817 6. Return output. 819 4.2. Parsing HTTP/1 Header Fields into Structured Headers 821 When a receiving implementation parses textual HTTP header fields 822 (e.g., in HTTP/1 or HTTP/2) that are known to be Structured Headers, 823 it is important that care be taken, as there are a number of edge 824 cases that can cause interoperability or even security problems. 825 This section specifies the algorithm for doing so. 827 Given an ASCII string input_string that represents the chosen 828 header's field-value, and header_type, one of "dictionary", "list", 829 "list-list", "param-list", or "item", return the parsed header value. 831 1. Discard any leading OWS from input_string. 833 2. If header_type is "dictionary", let output be the result of 834 Parsing a Dictionary from Text (Section 4.2.1). 836 3. If header_type is "list", let output be the result of Parsing a 837 List from Text (Section 4.2.3). 839 4. If header_type is "list-list", let output be the result of 840 Parsing a List of Lists from Text (Section 4.2.4). 842 5. If header_type is "param-list", let output be the result of 843 Parsing a Parameterised List from Text (Section 4.2.5). 845 6. If header_type is "item", let output be the result of Parsing an 846 Item from Text (Section 4.2.7). 848 7. Discard any leading OWS from input_string. 850 8. If input_string is not empty, fail parsing. 852 9. Otherwise, return output. 854 When generating input_string, parsers MUST combine all instances of 855 the target header field into one comma-separated field-value, as per 857 [RFC7230], Section 3.2.2; this assures that the header is processed 858 correctly. 860 For Lists, Lists of Lists, Parameterised Lists and Dictionaries, this 861 has the effect of correctly concatenating all instances of the header 862 field, as long as individual individual members of the top-level data 863 structure are not split across multiple header instances. 865 Strings split across multiple header instances will have 866 unpredictable results, because comma(s) and whitespace inserted upon 867 combination will become part of the string output by the parser. 868 Since concatenation might be done by an upstream intermediary, the 869 results are not under the control of the serialiser or the parser. 871 Integers, Floats and Byte Sequences cannot be split across multiple 872 headers because the inserted commas will cause parsing to fail. 874 If parsing fails - including when calling another algorithm - the 875 entire header field's value MUST be discarded. This is intentionally 876 strict, to improve interoperability and safety, and specifications 877 referencing this document cannot loosen this requirement. 879 Note that this has the effect of discarding any header field with 880 non-ASCII characters in input_string. 882 4.2.1. Parsing a Dictionary from Text 884 Given an ASCII string input_string, return an ordered map of (key, 885 item). input_string is modified to remove the parsed value. 887 1. Let dictionary be an empty, ordered map. 889 2. While input_string is not empty: 891 1. Let this_key be the result of running Parse a Key from Text 892 (Section 4.2.2) with input_string. 894 2. If dictionary already contains this_key, fail parsing. 896 3. Consume the first character of input_string; if it is not 897 "=", fail parsing. 899 4. Let this_value be the result of running Parse Item from Text 900 (Section 4.2.7) with input_string. 902 5. Add key this_key with value this_value to dictionary. 904 6. Discard any leading OWS from input_string. 906 7. If input_string is empty, return dictionary. 908 8. Consume the first character of input_string; if it is not 909 COMMA, fail parsing. 911 9. Discard any leading OWS from input_string. 913 10. If input_string is empty, fail parsing. 915 3. No structured data has been found; fail parsing. 917 4.2.2. Parsing a Key from Text 919 Given an ASCII string input_string, return a key. input_string is 920 modified to remove the parsed value. 922 1. If the first character of input_string is not lcalpha, fail 923 parsing. 925 2. Let output_string be an empty string. 927 3. While input_string is not empty: 929 1. Let char be the result of removing the first character of 930 input_string. 932 2. If char is not one of lcalpha, DIGIT, "_", or "-": 934 1. Prepend char to input_string. 936 2. Return output_string. 938 3. Append char to output_string. 940 4. Return output_string. 942 4.2.3. Parsing a List from Text 944 Given an ASCII string input_string, return a list of items. 945 input_string is modified to remove the parsed value. 947 1. Let items be an empty array. 949 2. While input_string is not empty: 951 1. Let item be the result of running Parse Item from Text 952 (Section 4.2.7) with input_string. 954 2. Append item to items. 956 3. Discard any leading OWS from input_string. 958 4. If input_string is empty, return items. 960 5. Consume the first character of input_string; if it is not 961 COMMA, fail parsing. 963 6. Discard any leading OWS from input_string. 965 7. If input_string is empty, fail parsing. 967 3. No structured data has been found; fail parsing. 969 4.2.4. Parsing a List of Lists from Text 971 Given an ASCII string input_string, return a list of lists of items. 972 input_string is modified to remove the parsed value. 974 1. let top_list be an empty array. 976 2. Let inner_list be an empty array. 978 3. While input_string is not empty: 980 1. Let item be the result of running Parse Item from Text 981 (Section 4.2.7) with input_string. 983 2. Append item to inner_list. 985 3. Discard any leading OWS from input_string. 987 4. If input_string is empty, append inner_list to top_list and 988 return top_list. 990 5. Let char be the result of consuming the first character of 991 input_string. 993 6. If char is COMMA: 995 1. Append inner_list to top_list. 997 2. Let inner_list be an empty array. 999 7. Else if char is not ";", fail parsing. 1001 8. Discard any leading OWS from input_string. 1003 9. If input_string is empty, fail parsing. 1005 4. No structured data has been found; fail parsing. 1007 4.2.5. Parsing a Parameterised List from Text 1009 Given an ASCII string input_string, return a list of parameterised 1010 identifiers. input_string is modified to remove the parsed value. 1012 1. Let items be an empty array. 1014 2. While input_string is not empty: 1016 1. Let item be the result of running Parse Parameterised 1017 Identifier from Text (Section 4.2.6) with input_string. 1019 2. Append item to items. 1021 3. Discard any leading OWS from input_string. 1023 4. If input_string is empty, return items. 1025 5. Consume the first character of input_string; if it is not 1026 COMMA, fail parsing. 1028 6. Discard any leading OWS from input_string. 1030 7. If input_string is empty, fail parsing. 1032 3. No structured data has been found; fail parsing. 1034 4.2.6. Parsing a Parameterised Identifier from Text 1036 Given an ASCII string input_string, return an token with an unordered 1037 map of parameters. input_string is modified to remove the parsed 1038 value. 1040 1. Let primary_identifier be the result of Parsing a Token from Text 1041 (Section 4.2.10) from input_string. 1043 2. Let parameters be an empty, unordered map. 1045 3. In a loop: 1047 1. Discard any leading OWS from input_string. 1049 2. If the first character of input_string is not ";", exit the 1050 loop. 1052 3. Consume a ";" character from the beginning of input_string. 1054 4. Discard any leading OWS from input_string. 1056 5. let param_name be the result of Parsing a key from Text 1057 (Section 4.2.2) from input_string. 1059 6. If param_name is already present in parameters, fail parsing. 1061 7. Let param_value be a null value. 1063 8. If the first character of input_string is "=": 1065 1. Consume the "=" character at the beginning of 1066 input_string. 1068 2. Let param_value be the result of Parsing an Item from 1069 Text (Section 4.2.7) from input_string. 1071 9. Add key param_name with value param_value to parameters. 1073 4. Return the tuple (primary_identifier, parameters). 1075 4.2.7. Parsing an Item from Text 1077 Given an ASCII string input_string, return an item. input_string is 1078 modified to remove the parsed value. 1080 1. If the first character of input_string is a "-" or a DIGIT, 1081 process input_string as a number (Section 4.2.8) and return the 1082 result. 1084 2. If the first character of input_string is a DQUOTE, process 1085 input_string as a string (Section 4.2.9) and return the result. 1087 3. If the first character of input_string is "*", process 1088 input_string as a byte sequence (Section 4.2.11) and return the 1089 result. 1091 4. If the first character of input_string is "?", process 1092 input_string as a Boolean (Section 4.2.12) and return the result. 1094 5. If the first character of input_string is an ALPHA, process 1095 input_string as a token (Section 4.2.10) and return the result. 1097 6. Otherwise, fail parsing. 1099 4.2.8. Parsing a Number from Text 1101 Given an ASCII string input_string, return a number. input_string is 1102 modified to remove the parsed value. 1104 NOTE: This algorithm parses both Integers Section 3.6 and Floats 1105 Section 3.7, and returns the corresponding structure. 1107 1. Let type be "integer". 1109 2. Let sign be 1. 1111 3. Let input_number be an empty string. 1113 4. If the first character of input_string is "-", remove it from 1114 input_string and set sign to -1. 1116 5. If input_string is empty, fail parsing. 1118 6. If the first character of input_string is not a DIGIT, fail 1119 parsing. 1121 7. While input_string is not empty: 1123 1. Let char be the result of removing the first character of 1124 input_string. 1126 2. If char is a DIGIT, append it to input_number. 1128 3. Else, if type is "integer" and char is ".", append char to 1129 input_number and set type to "float". 1131 4. Otherwise, prepend char to input_string, and exit the loop. 1133 5. If type is "integer" and input_number contains more than 19 1134 characters, fail parsing. 1136 6. If type is "float" and input_number contains more than 16 1137 characters, fail parsing. 1139 8. If type is "integer": 1141 1. Parse input_number as an integer and let output_number be 1142 the product of the result and sign. 1144 2. If output_number is outside the range defined in 1145 Section 3.6, fail parsing. 1147 9. Otherwise: 1149 1. If the final character of input_number is ".", fail parsing. 1151 2. Parse input_number as a float and let output_number be the 1152 product of the result and sign. 1154 10. Return output_number. 1156 4.2.9. Parsing a String from Text 1158 Given an ASCII string input_string, return an unquoted string. 1159 input_string is modified to remove the parsed value. 1161 1. Let output_string be an empty string. 1163 2. If the first character of input_string is not DQUOTE, fail 1164 parsing. 1166 3. Discard the first character of input_string. 1168 4. While input_string is not empty: 1170 1. Let char be the result of removing the first character of 1171 input_string. 1173 2. If char is a backslash ("\"): 1175 1. If input_string is now empty, fail parsing. 1177 2. Else: 1179 1. Let next_char be the result of removing the first 1180 character of input_string. 1182 2. If next_char is not DQUOTE or "\", fail parsing. 1184 3. Append next_char to output_string. 1186 3. Else, if char is DQUOTE, return output_string. 1188 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not 1189 in VCHAR or SP), fail parsing. 1191 5. Else, append char to output_string. 1193 5. Reached the end of input_string without finding a closing DQUOTE; 1194 fail parsing. 1196 4.2.10. Parsing a Token from Text 1198 Given an ASCII string input_string, return a token. input_string is 1199 modified to remove the parsed value. 1201 1. If the first character of input_string is not ALPHA, fail 1202 parsing. 1204 2. Let output_string be an empty string. 1206 3. While input_string is not empty: 1208 1. Let char be the result of removing the first character of 1209 input_string. 1211 2. If char is not one of ALPHA, DIGIT, "_", "-", ".", ":", "%", 1212 "*" or "/": 1214 1. Prepend char to input_string. 1216 2. Return output_string. 1218 3. Append char to output_string. 1220 4. Return output_string. 1222 4.2.11. Parsing a Byte Sequence from Text 1224 Given an ASCII string input_string, return a byte sequence. 1225 input_string is modified to remove the parsed value. 1227 1. If the first character of input_string is not "*", fail parsing. 1229 2. Discard the first character of input_string. 1231 3. If there is not a "*" character before the end of input_string, 1232 fail parsing. 1234 4. Let b64_content be the result of removing content of input_string 1235 up to but not including the first instance of the character "*". 1237 5. Consume the "*" character at the beginning of input_string. 1239 6. If b64_content contains a character not included in ALPHA, DIGIT, 1240 "+", "/" and "=", fail parsing. 1242 7. Let binary_content be the result of Base 64 Decoding [RFC4648] 1243 b64_content, synthesising padding if necessary (note the 1244 requirements about recipient behaviour below). 1246 8. Return binary_content. 1248 Because some implementations of base64 do not allow reject of encoded 1249 data that is not properly "=" padded (see [RFC4648], Section 3.2), 1250 parsers SHOULD NOT fail when it is not present, unless they cannot be 1251 configured to do so. 1253 Because some implementations of base64 do not allow rejection of 1254 encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), 1255 parsers SHOULD NOT fail when it is present, unless they cannot be 1256 configured to do so. 1258 This specification does not relax the requirements in [RFC4648], 1259 Section 3.1 and 3.3; therefore, parsers MUST fail on characters 1260 outside the base64 alphabet, and on line feeds in encoded data. 1262 4.2.12. Parsing a Boolean from Text 1264 Given an ASCII string input_string, return a Boolean. input_string is 1265 modified to remove the parsed value. 1267 1. If the first character of input_string is not "?", fail parsing. 1269 2. Discard the first character of input_string. 1271 3. If the first character of input_string case-sensitively matches 1272 "T", discard the first character, and return true. 1274 4. If the first character of input_string case-sensitively matches 1275 "F", discard the first character, and return false. 1277 5. No value has matched; fail parsing. 1279 5. IANA Considerations 1281 This draft has no actions for IANA. 1283 6. Security Considerations 1285 The size of most types defined by Structured Headers is not limited; 1286 as a result, extremely large header fields could be an attack vector 1287 (e.g., for resource consumption). Most HTTP implementations limit 1288 the sizes of size of individual header fields as well as the overall 1289 header block size to mitigate such attacks. 1291 It is possible for parties with the ability to inject new HTTP header 1292 fields to change the meaning of a Structured Header. In some 1293 circumstances, this will cause parsing to fail, but it is not 1294 possible to reliably fail in all such circumstances. 1296 7. References 1298 7.1. Normative References 1300 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1301 RFC 20, DOI 10.17487/RFC0020, October 1969, 1302 . 1304 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1305 Requirement Levels", BCP 14, RFC 2119, 1306 DOI 10.17487/RFC2119, March 1997, 1307 . 1309 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 1310 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 1311 . 1313 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 1314 Specifications: ABNF", STD 68, RFC 5234, 1315 DOI 10.17487/RFC5234, January 2008, 1316 . 1318 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1319 Protocol (HTTP/1.1): Message Syntax and Routing", 1320 RFC 7230, DOI 10.17487/RFC7230, June 2014, 1321 . 1323 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1324 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1325 May 2017, . 1327 7.2. Informative References 1329 [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 1330 IEEE 754-2008, DOI 10.1109/IEEESTD.2008.4610935, 1331 ISBN 978-0-7381-5752-8, August 2008, 1332 . 1334 See also http://grouper.ieee.org/groups/754/ [6]. 1336 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1337 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 1338 DOI 10.17487/RFC7231, June 2014, 1339 . 1341 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 1342 DOI 10.17487/RFC7493, March 2015, 1343 . 1345 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 1346 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 1347 DOI 10.17487/RFC7540, May 2015, 1348 . 1350 [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for 1351 HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, 1352 . 1354 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 1355 Interchange Format", STD 90, RFC 8259, 1356 DOI 10.17487/RFC8259, December 2017, 1357 . 1359 7.3. URIs 1361 [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ 1363 [2] https://httpwg.github.io/ 1365 [3] https://github.com/httpwg/http-extensions/labels/header-structure 1367 [4] https://github.com/httpwg/structured-header-tests 1369 [5] https://github.com/httpwg/wiki/wiki/Structured-Headers 1371 [6] https://github.com/httpwg/structured-header-tests 1373 Appendix A. Acknowledgements 1375 Many thanks to Matthew Kerwin for his detailed feedback and careful 1376 consideration during the development of this specification. 1378 Appendix B. Frequently Asked Questions 1379 B.1. Why not JSON? 1381 Earlier proposals for structured headers were based upon JSON 1382 [RFC8259]. However, constraining its use to make it suitable for 1383 HTTP header fields required senders and recipients to implement 1384 specific additional handling. 1386 For example, JSON has specification issues around large numbers and 1387 objects with duplicate members. Although advice for avoiding these 1388 issues is available (e.g., [RFC7493]), it cannot be relied upon. 1390 Likewise, JSON strings are by default Unicode strings, which have a 1391 number of potential interoperability issues (e.g., in comparison). 1392 Although implementers can be advised to avoid non-ASCII content where 1393 unnecessary, this is difficult to enforce. 1395 Another example is JSON's ability to nest content to arbitrary 1396 depths. Since the resulting memory commitment might be unsuitable 1397 (e.g., in embedded and other limited server deployments), it's 1398 necessary to limit it in some fashion; however, existing JSON 1399 implementations have no such limits, and even if a limit is 1400 specified, it's likely that some header field definition will find a 1401 need to violate it. 1403 Because of JSON's broad adoption and implementation, it is difficult 1404 to impose such additional constraints across all implementations; 1405 some deployments would fail to enforce them, thereby harming 1406 interoperability. 1408 Since a major goal for Structured Headers is to improve 1409 interoperability and simplify implementation, these concerns led to a 1410 format that requires a dedicated parser and serialiser. 1412 Additionally, there were widely shared feelings that JSON doesn't 1413 "look right" in HTTP headers. 1415 B.2. Structured Headers don't "fit" my data. 1417 Structured headers intentionally limits the complexity of data 1418 structures, to assure that it can be processed in a performant manner 1419 with little overhead. This means that work is necessary to fit some 1420 data types into them. 1422 Sometimes, this can be achieved by creating limited substructures in 1423 values, and/or using more than one header. For example, consider: 1425 Example-Thing: name="Widget", cost=89.2, descriptions="foo bar" 1426 Example-Description: foo; url="https://example.net"; context=123, 1427 bar; url="https://example.org"; context=456 1429 Since the description contains a list of key/value pairs, we use a 1430 Parameterised List to represent them, with the token for each item in 1431 the list used to identify it in the "descriptions" member of the 1432 Example-Thing header. 1434 When specifying more than one header, it's important to remember to 1435 describe what a processor's behaviour should be when one of the 1436 headers is missing. 1438 If you need to fit arbitrarily complex data into a header, Structured 1439 Headers is probably a poor fit for your use case. 1441 B.3. What should generic Structured Headers implementations expose? 1443 A generic implementation should expose the top-level parse 1444 (Section 4.2) and serialise (Section 4.1) functions. They need not 1445 be functions; for example, it could be implemented as an object, with 1446 methods for each of the different top-level types. 1448 For interoperability, it's important that generic implementations be 1449 complete and follow the algorithms closely; see Section 1.1. To aid 1450 this, a common test suite is being maintained by the community; see 1451 https://github.com/httpwg/structured-header-tests [7]. 1453 Appendix C. Changes 1455 _RFC Editor: Please remove this section before publication._ 1457 C.1. Since draft-ietf-httpbis-header-structure-08 1459 o Disallow whitespace before items properly (#703). 1461 o Created "key" for use in dictionaries and parameters, rather than 1462 relying on identifier (#702). Identifiers have a separate minimum 1463 supported size. 1465 o Expanded the range of special characters allowed in identifier to 1466 include all of ALPHA, ".", ":", and "%" (#702). 1468 o Use "?" instead of "!" to indicate a Boolean (#719). 1470 o Added "Intentionally Strict Processing" (#684). 1472 o Gave better names for referring specs to use in Parameterised 1473 Lists (#720). 1475 o Added Lists of Lists (#721). 1477 o Rename Identifier to Token (#725). 1479 o Add implementation guidance (#727). 1481 C.2. Since draft-ietf-httpbis-header-structure-07 1483 o Make Dictionaries ordered mappings (#659). 1485 o Changed "binary content" to "byte sequence" to align with Infra 1486 specification (#671). 1488 o Changed "mapping" to "map" for #671. 1490 o Don't fail if byte sequences aren't "=" padded (#658). 1492 o Add Booleans (#683). 1494 o Allow identifiers in items again (#629). 1496 o Disallowed whitespace before items (#703). 1498 o Explain the consequences of splitting a string across multiple 1499 headers (#686). 1501 C.3. Since draft-ietf-httpbis-header-structure-06 1503 o Add a FAQ. 1505 o Allow non-zero pad bits. 1507 o Explicitly check for integers that violate constraints. 1509 C.4. Since draft-ietf-httpbis-header-structure-05 1511 o Reorganise specification to separate parsing out. 1513 o Allow referencing specs to use ABNF. 1515 o Define serialisation algorithms. 1517 o Refine relationship between ABNF, parsing and serialisation 1518 algorithms. 1520 C.5. Since draft-ietf-httpbis-header-structure-04 1522 o Remove identifiers from item. 1524 o Remove most limits on sizes. 1526 o Refine number parsing. 1528 C.6. Since draft-ietf-httpbis-header-structure-03 1530 o Strengthen language around failure handling. 1532 C.7. Since draft-ietf-httpbis-header-structure-02 1534 o Split Numbers into Integers and Floats. 1536 o Define number parsing. 1538 o Tighten up binary parsing and give it an explicit end delimiter. 1540 o Clarify that mappings are unordered. 1542 o Allow zero-length strings. 1544 o Improve string parsing algorithm. 1546 o Improve limits in algorithms. 1548 o Require parsers to combine header fields before processing. 1550 o Throw an error on trailing garbage. 1552 C.8. Since draft-ietf-httpbis-header-structure-01 1554 o Replaced with draft-nottingham-structured-headers. 1556 C.9. Since draft-ietf-httpbis-header-structure-00 1558 o Added signed 64bit integer type. 1560 o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- 1561 unicode-string. 1563 o Change h1_blob delimiter to ":" since "'" is valid t_char 1565 Authors' Addresses 1567 Mark Nottingham 1568 Fastly 1570 Email: mnot@mnot.net 1571 URI: https://www.mnot.net/ 1573 Poul-Henning Kamp 1574 The Varnish Cache Project 1576 Email: phk@varnish-cache.org