idnits 2.17.00 (12 Aug 2021) /tmp/idnits15075/draft-ietf-httpbis-header-structure-14.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 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 (October 30, 2019) is 933 days in the past. Is this intentional? 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 1436 -- Looks like a reference, but probably isn't: '2' on line 1438 -- Looks like a reference, but probably isn't: '3' on line 1440 -- Looks like a reference, but probably isn't: '4' on line 1442 -- Looks like a reference, but probably isn't: '5' on line 1444 == Missing Reference: 'RFCxxxx' is mentioned on line 278, but not defined == Missing Reference: 'RFC3986' is mentioned on line 285, but not defined -- Looks like a reference, but probably isn't: '6' on line 1528 Summary: 1 error (**), 0 flaws (~~), 3 warnings (==), 7 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: May 2, 2020 The Varnish Cache Project 6 October 30, 2019 8 Structured Headers for HTTP 9 draft-ietf-httpbis-header-structure-14 11 Abstract 13 This document describes a set of data types and associated algorithms 14 that are intended to make it easier and safer to define and handle 15 HTTP header fields. It is intended for use by specifications of new 16 HTTP header fields that wish to use a common syntax that is more 17 restrictive than traditional HTTP field values. 19 Note to Readers 21 _RFC EDITOR: please remove this section before publication_ 23 Discussion of this draft takes place on the HTTP working group 24 mailing list (ietf-http-wg@w3.org), which is archived at 25 https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. 27 Working Group information can be found at https://httpwg.github.io/ 28 [2]; source code and issues list for this draft can be found at 29 https://github.com/httpwg/http-extensions/labels/header-structure 30 [3]. 32 Tests for implementations are collected at https://github.com/httpwg/ 33 structured-header-tests [4]. 35 Implementations are tracked at https://github.com/httpwg/wiki/wiki/ 36 Structured-Headers [5]. 38 Status of This Memo 40 This Internet-Draft is submitted in full conformance with the 41 provisions of BCP 78 and BCP 79. 43 Internet-Drafts are working documents of the Internet Engineering 44 Task Force (IETF). Note that other groups may also distribute 45 working documents as Internet-Drafts. The list of current Internet- 46 Drafts is at https://datatracker.ietf.org/drafts/current/. 48 Internet-Drafts are draft documents valid for a maximum of six months 49 and may be updated, replaced, or obsoleted by other documents at any 50 time. It is inappropriate to use Internet-Drafts as reference 51 material or to cite them other than as "work in progress." 53 This Internet-Draft will expire on May 2, 2020. 55 Copyright Notice 57 Copyright (c) 2019 IETF Trust and the persons identified as the 58 document authors. All rights reserved. 60 This document is subject to BCP 78 and the IETF Trust's Legal 61 Provisions Relating to IETF Documents 62 (https://trustee.ietf.org/license-info) in effect on the date of 63 publication of this document. Please review these documents 64 carefully, as they describe your rights and restrictions with respect 65 to this document. Code Components extracted from this document must 66 include Simplified BSD License text as described in Section 4.e of 67 the Trust Legal Provisions and are provided without warranty as 68 described in the Simplified BSD License. 70 Table of Contents 72 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 73 1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 74 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 75 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 76 3. Structured Data Types . . . . . . . . . . . . . . . . . . . . 7 77 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 8 78 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 9 79 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 10 80 4. Working With Structured Headers in HTTP Headers . . . . . . . 13 81 4.1. Serializing Structured Headers . . . . . . . . . . . . . 13 82 4.2. Parsing Header Fields into Structured Headers . . . . . . 20 83 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 84 6. Security Considerations . . . . . . . . . . . . . . . . . . . 30 85 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 30 86 7.1. Normative References . . . . . . . . . . . . . . . . . . 30 87 7.2. Informative References . . . . . . . . . . . . . . . . . 31 88 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 31 89 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 32 90 Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 32 91 B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 32 92 B.2. Structured Headers don't "fit" my data. . . . . . . . . . 33 93 Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 33 94 Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 34 95 D.1. Since draft-ietf-httpbis-header-structure-13 . . . . . . 34 96 D.2. Since draft-ietf-httpbis-header-structure-12 . . . . . . 34 97 D.3. Since draft-ietf-httpbis-header-structure-11 . . . . . . 34 98 D.4. Since draft-ietf-httpbis-header-structure-10 . . . . . . 34 99 D.5. Since draft-ietf-httpbis-header-structure-09 . . . . . . 35 100 D.6. Since draft-ietf-httpbis-header-structure-08 . . . . . . 35 101 D.7. Since draft-ietf-httpbis-header-structure-07 . . . . . . 35 102 D.8. Since draft-ietf-httpbis-header-structure-06 . . . . . . 36 103 D.9. Since draft-ietf-httpbis-header-structure-05 . . . . . . 36 104 D.10. Since draft-ietf-httpbis-header-structure-04 . . . . . . 36 105 D.11. Since draft-ietf-httpbis-header-structure-03 . . . . . . 36 106 D.12. Since draft-ietf-httpbis-header-structure-02 . . . . . . 36 107 D.13. Since draft-ietf-httpbis-header-structure-01 . . . . . . 37 108 D.14. Since draft-ietf-httpbis-header-structure-00 . . . . . . 37 109 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37 111 1. Introduction 113 Specifying the syntax of new HTTP header fields is an onerous task; 114 even with the guidance in Section 8.3.1 of [RFC7231], there are many 115 decisions - and pitfalls - for a prospective HTTP header field 116 author. 118 Once a header field is defined, bespoke parsers and serializers often 119 need to be written, because each header has slightly different 120 handling of what looks like common syntax. 122 This document introduces a set of common data structures for use in 123 definitions of new HTTP header field values to address these 124 problems. In particular, it defines a generic, abstract model for 125 header field values, along with a concrete serialisation for 126 expressing that model in HTTP [RFC7230] header fields. 128 HTTP headers that are defined as "Structured Headers" use the types 129 defined in this specification to define their syntax and basic 130 handling rules, thereby simplifying both their definition by 131 specification writers and handling by implementations. 133 Additionally, future versions of HTTP can define alternative 134 serialisations of the abstract model of these structures, allowing 135 headers that use it to be transmitted more efficiently without being 136 redefined. 138 Note that it is not a goal of this document to redefine the syntax of 139 existing HTTP headers; the mechanisms described herein are only 140 intended to be used with headers that explicitly opt into them. 142 Section 2 describes how to specify a Structured Header. 144 Section 3 defines a number of abstract data types that can be used in 145 Structured Headers. Those abstract types can be serialized into and 146 parsed from HTTP headers using the algorithms described in Section 4. 148 1.1. Intentionally Strict Processing 150 This specification intentionally defines strict parsing and 151 serialisation behaviours using step-by-step algorithms; the only 152 error handling defined is to fail the operation altogether. 154 It is designed to encourage faithful implementation and therefore 155 good interoperability. Therefore, an implementation that tried to be 156 "helpful" by being more tolerant of input would make interoperability 157 worse, since that would create pressure on other implementations to 158 implement similar (but likely subtly different) workarounds. 160 In other words, strict processing is an intentional feature of this 161 specification; it allows non-conformant input to be discovered and 162 corrected by the producer early, and avoids both interoperability and 163 security issues that might otherwise result. 165 Note that as a result of this strictness, if a header field is 166 appended to by multiple parties (e.g., intermediaries, or different 167 components in the sender), an error in one party's value is likely to 168 cause the entire header field to fail parsing. 170 1.2. Notational Conventions 172 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 173 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 174 "OPTIONAL" in this document are to be interpreted as described in BCP 175 14 [RFC2119] [RFC8174] when, and only when, they appear in all 176 capitals, as shown here. 178 This document uses algorithms to specify parsing and serialisation 179 behaviours, and the Augmented Backus-Naur Form (ABNF) notation of 180 [RFC5234] to illustrate expected syntax in HTTP header fields. In 181 doing so, uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE rules from 182 [RFC5234]. It also includes the OWS and tchar rules from [RFC7230]. 184 When parsing from HTTP header fields, implementations MUST follow the 185 algorithms, but MAY vary in implementation so as the behaviours are 186 indistinguishable from specified behaviour. If there is disagreement 187 between the parsing algorithms and ABNF, the specified algorithms 188 take precedence. In some places, the algorithms are "greedy" with 189 whitespace, but this should not affect conformance. 191 For serialisation to header fields, the ABNF illustrates the range of 192 acceptable wire representations with as much fidelity as possible, 193 and the algorithms define the recommended way to produce them. 194 Implementations MAY vary from the specified behaviour so long as the 195 output still matches the ABNF. 197 2. Defining New Structured Headers 199 To specify a HTTP header as a structured header, its authors needs 200 to: 202 o Reference this specification. Recipients and generators of the 203 header need to know that the requirements of this document are in 204 effect. 206 o Specify the type of the header field itself; either Dictionary 207 (Section 3.2), List (Section 3.1), or Item (Section 3.3). 209 o Define the semantics of those structures. 211 o Specify any additional constraints upon the structures used, as 212 well as the consequences when those constraints are violated. 214 Typically, this means that a header definition will specify the top- 215 level type - Dictionary, List or Item - and then define its allowable 216 types, and constraints upon them. For example, a header defined as a 217 List might have all Integer members, or a mix of types; a header 218 defined as an Item might allow only Strings, and additionally only 219 strings beginning with the letter "Q". 221 When Structured Headers parsing fails, the header is ignored (see 222 Section 4.2); in most situations, violating header-specific 223 constraints should have the same effect. Thus, if a header is 224 defined as an Item and required to be an Integer, but a String is 225 received, it will by default be ignored. If the header requires 226 different error handling, this should be explicitly specified. 228 However, both Items and Inner Lists allow parameters as an 229 extensibility mechanism; this means that values can later be extended 230 to accommodate more information, if need be. As a result, header 231 specifications are discouraged from defining the presence of an 232 unrecognised parameter as an error condition. 234 Conversely, inner lists are only valid when a header definition 235 explicitly allows them. 237 Note that a header field definition cannot relax the requirements of 238 this specification because doing so would preclude handling by 239 generic software; they can only add additional constraints (for 240 example, on the numeric range of integers and floats, the format of 241 strings and tokens, the types allowed in a dictionary's values, or 242 the number of items in a list). Likewise, header field definitions 243 can only use Structured Headers for the entire header field value, 244 not a portion thereof. 246 This specification defines minimums for the length or number of 247 various structures supported by Structured Headers implementations. 248 It does not specify maximum sizes in most cases, but header authors 249 should be aware that HTTP implementations do impose various limits on 250 the size of individual header fields, the total number of fields, 251 and/or the size of the entire header block. 253 Specifications can refer to a Structured Header's field-name as a 254 "structured header name" and its field-value as a "structured header 255 value" as necessary. Header definitions are encouraged to use the 256 ABNF rules beginning with "sh-" defined in this specification; other 257 rules in this specification are not intended for their use. 259 For example, a fictitious Foo-Example header field might be specified 260 as: 262 42. Foo-Example Header 264 The Foo-Example HTTP header field conveys information about how 265 much Foo the message has. 267 Foo-Example is a Item Structured Header [RFCxxxx]. Its value MUST be 268 an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is: 270 Foo-Example = sh-integer 272 Its value indicates the amount of Foo in the message, and MUST 273 be between 0 and 10, inclusive; other values MUST cause 274 the entire header to be ignored. 276 The following parameters are defined: 277 * A parameter whose name is "fooUrl", and whose value is a string 278 (Section Y.Y of [RFCxxxx]), conveying the Foo URLs 279 for the message. See below for processing requirements. 281 "fooUrl" contains a URI-reference (Section 4.1 of 282 [RFC3986], Section 4.1). If its value is not a valid URI-reference, 283 that URL MUST be ignored. If its value is a relative reference 284 (Section 4.2 of [RFC3986]), it MUST be resolved (Section 5 of 285 [RFC3986]) before being used. 287 For example: 289 Foo-Example: 2; fooUrl="https://foo.example.com/" 291 3. Structured Data Types 293 This section defines the abstract value types that can be composed 294 into Structured Headers. The ABNF provided represents the on-wire 295 format in HTTP headers. 297 In summary: 299 o There are three top-level types that a HTTP header can be defined 300 as; Lists, Dictionaries, and Items. 302 o Lists and Dictionaries are containers; their members can be Items 303 or Inner Lists (which are themselves lists of items). 305 o Both Items and Inner Lists can be parameterised with key/value 306 pairs. 308 3.1. Lists 310 Lists are arrays of zero or more members, each of which can be an 311 item (Section 3.3) or an inner list (Section 3.1.1), both of which 312 can be parameterised (Section 3.1.2). 314 The ABNF for lists in HTTP headers is: 316 sh-list = list-member *( OWS "," OWS list-member ) 317 list-member = sh-item / inner-list 319 In HTTP headers, each member is separated by a comma and optional 320 whitespace. For example, a header field whose value is defined as a 321 list of strings could look like: 323 Example-StrListHeader: "foo", "bar", "It was the best of times." 325 In HTTP headers, an empty list is denoted by not serialising the 326 header at all. 328 Parsers MUST support lists containing at least 1024 members. Header 329 specifications can constrain the types and cardinality of individual 330 list values as they require. 332 3.1.1. Inner Lists 334 An inner list is an array of zero or more items (Section 3.3). Both 335 the individual items and the inner-list itself can be parameterised 336 (Section 3.1.2). 338 The ABNF for inner-lists in HTTP headers is: 340 inner-list = "(" OWS [ sh-item *( SP OWS sh-item ) OWS ] ")" 341 *parameter 343 In HTTP headers, inner lists are denoted by surrounding parenthesis, 344 and have their values delimited by a single space. A header field 345 whose value is defined as a list of inner-lists of strings could look 346 like: 348 Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () 350 Note that the last member in this example is an empty inner list. 352 A header field whose value is defined as a list of inner-lists with 353 parameters at both levels could look like: 355 Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar", "baz");lvl=1 356 Parsers MUST support inner-lists containing at least 256 members. 357 Header specifications can constrain the types and cardinality of 358 individual inner-list members as they require. 360 3.1.2. Parameters 362 Parameters are an ordered map of key-values pairs that are associated 363 with an item (Section 3.3) or inner-list (Section 3.1.1). The keys 364 are required to be unique within the scope of a map of parameters, 365 and the values are bare items (i.e., they themselves cannot be 366 parameterised; see Section 3.3). 368 The ABNF for parameters in HTTP headers is: 370 parameter = ";" OWS param-name [ "=" param-value ] 371 param-name = key 372 key = lcalpha *( lcalpha / DIGIT / "_" / "-" / "*" ) 373 lcalpha = %x61-7A ; a-z 374 param-value = bare-item 376 In HTTP headers, parameters are separated from their item or inner- 377 list and each other by semicolons. For example: 379 Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w 381 Parsers MUST support at least 256 parameters on an item or inner- 382 list, and support parameter keys with at least 64 characters. Header 383 specifications can constrain the types and cardinality of individual 384 parameter names and values as they require. 386 3.2. Dictionaries 388 Dictionaries are ordered maps of name-value pairs, where the names 389 are short, textual strings and the values are items (Section 3.3) or 390 arrays of items, both of which can be parameterised (Section 3.1.2). 391 There can be zero or more members, and their names are required to be 392 unique within the scope of the dictionary they occur within. 394 Implementations MUST provide access to dictionaries both by index and 395 by name. Specifications MAY use either means of accessing the 396 members. 398 The ABNF for dictionaries in HTTP headers is: 400 sh-dictionary = dict-member *( OWS "," OWS dict-member ) 401 dict-member = member-name "=" member-value 402 member-name = key 403 member-value = sh-item / inner-list 404 In HTTP headers, members are separated by a comma with optional 405 whitespace, while names and values are separated by "=" (without 406 whitespace). For example: 408 Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=* 410 A dictionary with a member whose value is an inner-list of tokens: 412 Example-DictListHeader: rating=1.5, feelings=(joy sadness) 414 A dictionary with a mix of singular and list values, some with 415 parameters: 417 Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?1 419 As with lists, an empty dictionary is represented in HTTP headers by 420 omitting the entire header field. 422 Typically, a header field specification will define the semantics of 423 dictionaries by specifying the allowed type(s) for individual member 424 names, as well as whether their presence is required or optional. 425 Recipients MUST ignore names that are undefined or unknown, unless 426 the header field's specification specifically disallows them. 428 Parsers MUST support dictionaries containing at least 1024 name/value 429 pairs, and names with at least 64 characters. 431 3.3. Items 433 An item is can be a integer (Section 3.3.1), float (Section 3.3.2), 434 string (Section 3.3.3), token (Section 3.3.4), byte sequence 435 (Section 3.3.5), or Boolean (Section 3.3.6). It can have associated 436 parameters (Section 3.1.2). 438 The ABNF for items in HTTP headers is: 440 sh-item = bare-item *parameter 441 bare-item = sh-integer / sh-float / sh-string / sh-token / sh-binary 442 / sh-boolean 444 For example, a header field that is defined to be an Item that is an 445 integer might look like: 447 Example-IntItemHeader: 5 449 or with parameters: 451 Example-IntItemHeader: 5; foo=bar 453 3.3.1. Integers 455 Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 456 inclusive (i.e., up to fifteen digits, signed), for IEEE 754 457 compatibility ([IEEE754]). 459 The ABNF for integers in HTTP headers is: 461 sh-integer = ["-"] 1*15DIGIT 463 For example: 465 Example-IntegerHeader: 42 467 Note that commas in integers are used in this section's prose only 468 for readability; they are not valid in the wire format. 470 3.3.2. Floats 472 Floats are decimal numbers with an integer and a fractional 473 component. The fractional component has at most six digits of 474 precision. Additionally, like integers, it can have no more than 475 fifteen digits in total, which in some cases further constrains its 476 precision. 478 The ABNF for floats in HTTP headers is: 480 sh-float = ["-"] (1*9DIGIT "." 1*6DIGIT / 481 10DIGIT "." 1*5DIGIT / 482 11DIGIT "." 1*4DIGIT / 483 12DIGIT "." 1*3DIGIT / 484 13DIGIT "." 1*2DIGIT / 485 14DIGIT "." 1DIGIT ) 487 For example, a header whose value is defined as a float could look 488 like: 490 Example-FloatHeader: 4.5 492 3.3.3. Strings 494 Strings are zero or more printable ASCII [RFC0020] characters (i.e., 495 the range %x20 to %x7E). Note that this excludes tabs, newlines, 496 carriage returns, etc. 498 The ABNF for strings in HTTP headers is: 500 sh-string = DQUOTE *(chr) DQUOTE 501 chr = unescaped / escaped 502 unescaped = %x20-21 / %x23-5B / %x5D-7E 503 escaped = "\" ( DQUOTE / "\" ) 505 In HTTP headers, strings are delimited with double quotes, using a 506 backslash ("\") to escape double quotes and backslashes. For 507 example: 509 Example-StringHeader: "hello world" 511 Note that strings only use DQUOTE as a delimiter; single quotes do 512 not delimit strings. Furthermore, only DQUOTE and "\" can be 513 escaped; other characters after "\" MUST cause parsing to fail. 515 Unicode is not directly supported in strings, because it causes a 516 number of interoperability issues, and - with few exceptions - header 517 values do not require it. 519 When it is necessary for a field value to convey non-ASCII content, a 520 byte sequence (Section 3.3.5) SHOULD be specified, along with a 521 character encoding (preferably [UTF-8]). 523 Parsers MUST support strings with at least 1024 characters. 525 3.3.4. Tokens 527 Tokens are short textual words; their abstract model is identical to 528 their expression in the HTTP header serialisation. 530 The ABNF for tokens in HTTP headers is: 532 sh-token = ALPHA *( tchar / ":" / "/" ) 534 Parsers MUST support tokens with at least 512 characters. 536 Note that a Structured Header token allows the characters as the 537 "token" ABNF rule defined in [RFC7230], with the exceptions that the 538 first character is required to be ALPHA, and ":" and "/" are also 539 allowed. 541 3.3.5. Byte Sequences 543 Byte sequences can be conveyed in Structured Headers. 545 The ABNF for a byte sequence in HTTP headers is: 547 sh-binary = "*" *(base64) "*" 548 base64 = ALPHA / DIGIT / "+" / "/" / "=" 550 In HTTP headers, a byte sequence is delimited with asterisks and 551 encoded using base64 ([RFC4648], Section 4). For example: 553 Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==* 555 Parsers MUST support byte sequences with at least 16384 octets after 556 decoding. 558 3.3.6. Booleans 560 Boolean values can be conveyed in Structured Headers. 562 The ABNF for a Boolean in HTTP headers is: 564 sh-boolean = "?" boolean 565 boolean = "0" / "1" 567 In HTTP headers, a boolean is indicated with a leading "?" character 568 followed by a "1" for a true value or "0" for false. For example: 570 Example-BoolHdr: ?1 572 4. Working With Structured Headers in HTTP Headers 574 This section defines how to serialize and parse Structured Headers in 575 header fields, and protocols compatible with them (e.g., in HTTP/2 576 [RFC7540] before HPACK [RFC7541] is applied). 578 4.1. Serializing Structured Headers 580 Given a structure defined in this specification, return an ASCII 581 string suitable for use in a HTTP header value. 583 1. If the structure is a dictionary or list and its value is empty 584 (i.e., it has no members), do not serialize the field at all 585 (i.e., omit both the field-name and field-value). 587 2. If the structure is a dictionary, let output_string be the result 588 of running Serializing a Dictionary (Section 4.1.2) with the 589 structure. 591 3. Else if the structure is a list, let output_string be the result 592 of running Serializing a List (Section 4.1.1) with the structure. 594 4. Else if the structure is an item, let output_string be the result 595 of running Serializing an Item (Section 4.1.3) with the 596 structure. 598 5. Else, fail serialisation. 600 6. Return output_string converted into an array of bytes, using 601 ASCII encoding [RFC0020]. 603 4.1.1. Serializing a List 605 Given an array of (member-value, parameters) tuples as input_list, 606 return an ASCII string suitable for use in a HTTP header value. 608 1. Let output be an empty string. 610 2. For each (member-value, parameters) of input_list: 612 1. If member-value is an array, append the result of running 613 Serialising an Inner List (Section 4.1.1.1) with (member- 614 value, parameters) to output. 616 2. Otherwise, append the result of running Serializing an Item 617 (Section 4.1.3) with (member-value, parameters) to output. 619 3. If more member-values remain in input_list: 621 1. Append a COMMA to output. 623 2. Append a single WS to output. 625 3. Return output. 627 4.1.1.1. Serialising an Inner List 629 Given an array of (member-value, parameters) tuples as inner_list, 630 and parameters as list_parameters, return an ASCII string suitable 631 for use in a HTTP header value. 633 1. Let output be the string "(". 635 2. For each (member-value, parameters) of inner_list: 637 1. Append the result of running Serializing an Item 638 (Section 4.1.3) with (member-value, parameters) to output. 640 2. If more values remain in inner_list, append a single WS to 641 output. 643 3. Append ")" to output. 645 4. Append the result of running Serializing Parameters 646 Section 4.1.1.2 with list_parameters to output. 648 5. Return output. 650 4.1.1.2. Serializing Parameters 652 Given an ordered dictionary as input_parameters (each member having a 653 param-name and a param-value), return an ASCII string suitable for 654 use in a HTTP header value. 656 1. Let output be an empty string. 658 2. For each parameter-name with a value of param-value in 659 input_parameters: 661 1. Append ";" to output. 663 2. Append the result of running Serializing a Key 664 (Section 4.1.1.3) with param-name to output. 666 3. If param-value is not null: 668 1. Append "=" to output. 670 2. Append the result of running Serializing a bare Item 671 (Section 4.1.3.1) with param-value to output. 673 3. Return output. 675 4.1.1.3. Serializing a Key 677 Given a key as input_key, return an ASCII string suitable for use in 678 a HTTP header value. 680 1. If input_key is not a sequence of characters, or contains 681 characters not in lcalpha, DIGIT, "*", "_", or "-", fail 682 serialisation. 684 2. Let output be an empty string. 686 3. Append input_key to output. 688 4. Return output. 690 4.1.2. Serializing a Dictionary 692 Given an ordered dictionary as input_dictionary (each member having a 693 member-name and a tuple value of (member-value, parameters)), return 694 an ASCII string suitable for use in a HTTP header value. 696 1. Let output be an empty string. 698 2. For each member-name with a value of (member-value, parameters) 699 in input_dictionary: 701 1. Append the result of running Serializing a Key 702 (Section 4.1.1.3) with member's member-name to output. 704 2. Append "=" to output. 706 3. If member-value is an array, append the result of running 707 Serialising an Inner List (Section 4.1.1.1) with (member- 708 value, parameters) to output. 710 4. Otherwise, append the result of running Serializing an Item 711 (Section 4.1.3) with (member-value, parameters) to output. 713 5. If more members remain in input_dictionary: 715 1. Append a COMMA to output. 717 2. Append a single WS to output. 719 3. Return output. 721 4.1.3. Serializing an Item 723 Given an item bare_item and parameters item_parameters as input, 724 return an ASCII string suitable for use in a HTTP header value. 726 1. Let output be an empty string. 728 2. Append the result of running Serializing a Bare Item 729 Section 4.1.3.1 with bare_item to output. 731 3. Append the result of running Serializing Parameters 732 Section 4.1.1.2 with item_parameters to output. 734 4. Return output. 736 4.1.3.1. Serialising a Bare Item 738 Given an item as input_item, return an ASCII string suitable for use 739 in a HTTP header value. 741 1. If input_item is an integer, return the result of running 742 Serializing an Integer (Section 4.1.4) with input_item. 744 2. If input_item is a float, return the result of running 745 Serializing a Float (Section 4.1.5) with input_item. 747 3. If input_item is a string, return the result of running 748 Serializing a String (Section 4.1.6) with input_item. 750 4. If input_item is a token, return the result of running 751 Serializing a Token (Section 4.1.7) with input_item. 753 5. If input_item is a Boolean, return the result of running 754 Serializing a Boolean (Section 4.1.9) with input_item. 756 6. If input_item is a byte sequence, return the result of running 757 Serializing a Byte Sequence (Section 4.1.8) with input_item. 759 7. Otherwise, fail serialisation. 761 4.1.4. Serializing an Integer 763 Given an integer as input_integer, return an ASCII string suitable 764 for use in a HTTP header value. 766 1. If input_integer is not an integer in the range of 767 -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail 768 serialisation. 770 2. Let output be an empty string. 772 3. If input_integer is less than (but not equal to) 0, append "-" to 773 output. 775 4. Append input_integer's numeric value represented in base 10 using 776 only decimal digits to output. 778 5. Return output. 780 4.1.5. Serializing a Float 782 Given a float as input_float, return an ASCII string suitable for use 783 in a HTTP header value. 785 1. Let output be an empty string. 787 2. If input_float is less than (but not equal to) 0, append "-" to 788 output. 790 3. Append input_float's integer component represented in base 10 791 (using only decimal digits) to output; if it is zero, append 792 "0". 794 4. Let integer_digits be the number of characters appended in the 795 previous step. 797 5. If integer_digits is greater than 14, fail serialisation. 799 6. Let digits_avail be 15 minus integer_digits. 801 7. Let fractional_digits_avail be the minimum of digits_avail and 802 6. 804 8. Append "." to output. 806 9. Append at most fractional_digits_avail digits of input_float's 807 fractional component represented in base 10 to output (using 808 only decimal digits, and truncating any remaining digits); if it 809 is zero, append "0". 811 10. Return output. 813 4.1.6. Serializing a String 815 Given a string as input_string, return an ASCII string suitable for 816 use in a HTTP header value. 818 1. If input_string is not a sequence of characters, or contains 819 characters in the range %x00-1f or %x7f (i.e., is not in VCHAR or 820 SP), fail serialisation. 822 2. Let output be an empty string. 824 3. Append DQUOTE to output. 826 4. For each character char in input_string: 828 1. If char is "\" or DQUOTE: 830 1. Append "\" to output. 832 2. Append char to output. 834 5. Append DQUOTE to output. 836 6. Return output. 838 4.1.7. Serializing a Token 840 Given a token as input_token, return an ASCII string suitable for use 841 in a HTTP header value. 843 1. If input_token is not a sequence of characters, or contains 844 characters not allowed by the tchar ABNF rule, fail 845 serialisation. 847 2. Let output be an empty string. 849 3. Append input_token to output. 851 4. Return output. 853 4.1.8. Serializing a Byte Sequence 855 Given a byte sequence as input_bytes, return an ASCII string suitable 856 for use in a HTTP header value. 858 1. If input_bytes is not a sequence of bytes, fail serialisation. 860 2. Let output be an empty string. 862 3. Append "*" to output. 864 4. Append the result of base64-encoding input_bytes as per 865 [RFC4648], Section 4, taking account of the requirements below. 867 5. Append "*" to output. 869 6. Return output. 871 The encoded data is required to be padded with "=", as per [RFC4648], 872 Section 3.2. 874 Likewise, encoded data SHOULD have pad bits set to zero, as per 875 [RFC4648], Section 3.5, unless it is not possible to do so due to 876 implementation constraints. 878 4.1.9. Serializing a Boolean 880 Given a Boolean as input_boolean, return an ASCII string suitable for 881 use in a HTTP header value. 883 1. If input_boolean is not a boolean, fail serialisation. 885 2. Let output be an empty string. 887 3. Append "?" to output. 889 4. If input_boolean is true, append "1" to output. 891 5. If input_boolean is false, append "0" to output. 893 6. Return output. 895 4.2. Parsing Header Fields into Structured Headers 897 When a receiving implementation parses HTTP header fields that are 898 known to be Structured Headers, it is important that care be taken, 899 as there are a number of edge cases that can cause interoperability 900 or even security problems. This section specifies the algorithm for 901 doing so. 903 Given an array of bytes input_bytes that represents the chosen 904 header's field-value (which is empty if that header is not present), 905 and header_type (one of "dictionary", "list", or "item"), return the 906 parsed header value. 908 1. Convert input_bytes into an ASCII string input_string; if 909 conversion fails, fail parsing. 911 2. Discard any leading OWS from input_string. 913 3. If header_type is "list", let output be the result of running 914 Parsing a List (Section 4.2.1) with input_string. 916 4. If header_type is "dictionary", let output be the result of 917 running Parsing a Dictionary (Section 4.2.2) with input_string. 919 5. If header_type is "item", let output be the result of running 920 Parsing an Item (Section 4.2.3) with input_string. 922 6. Discard any leading OWS from input_string. 924 7. If input_string is not empty, fail parsing. 926 8. Otherwise, return output. 928 When generating input_bytes, parsers MUST combine all instances of 929 the target header field into one comma-separated field-value, as per 930 [RFC7230], Section 3.2.2; this assures that the header is processed 931 correctly. 933 For Lists and Dictionaries, this has the effect of correctly 934 concatenating all instances of the header field, as long as 935 individual individual members of the top-level data structure are not 936 split across multiple header instances. 938 Strings split across multiple header instances will have 939 unpredictable results, because comma(s) and whitespace inserted upon 940 combination will become part of the string output by the parser. 941 Since concatenation might be done by an upstream intermediary, the 942 results are not under the control of the serializer or the parser. 944 Tokens, Integers, Floats and Byte Sequences cannot be split across 945 multiple headers because the inserted commas will cause parsing to 946 fail. 948 If parsing fails - including when calling another algorithm - the 949 entire header field's value MUST be ignored (i.e., treated as if the 950 header field were not present in the message). This is intentionally 951 strict, to improve interoperability and safety, and specifications 952 referencing this document are not allowed to loosen this requirement. 954 Note that this requirement does not apply to an implementation that 955 is not parsing the header field; for example, an intermediary is not 956 required to strip a failing header field from a message before 957 forwarding it. 959 4.2.1. Parsing a List 961 Given an ASCII string as input_string, return an array of 962 (item_or_inner_list, parameters) tuples. input_string is modified to 963 remove the parsed value. 965 1. Let members be an empty array. 967 2. While input_string is not empty: 969 1. Append the result of running Parsing an Item or Inner List 970 (Section 4.2.1.1) with input_string to members. 972 2. Discard any leading OWS from input_string. 974 3. If input_string is empty, return members. 976 4. Consume the first character of input_string; if it is not 977 COMMA, fail parsing. 979 5. Discard any leading OWS from input_string. 981 6. If input_string is empty, there is a trailing comma; fail 982 parsing. 984 3. No structured data has been found; return members (which is 985 empty). 987 4.2.1.1. Parsing an Item or Inner List 989 Given an ASCII string as input_string, return the tuple 990 (item_or_inner_list, parameters), where item_or_inner_list can be 991 either a single bare item, or an array of (bare_item, parameters) 992 tuples. input_string is modified to remove the parsed value. 994 1. If the first character of input_string is "(", return the result 995 of running Parsing an Inner List (Section 4.2.1.2) with 996 input_string. 998 2. Return the result of running Parsing an Item (Section 4.2.3) with 999 input_string. 1001 4.2.1.2. Parsing an Inner List 1003 Given an ASCII string as input_string, return the tuple (inner_list, 1004 parameters), where inner_list is an array of (bare_item, parameters) 1005 tuples. input_string is modified to remove the parsed value. 1007 1. Consume the first character of input_string; if it is not "(", 1008 fail parsing. 1010 2. Let inner_list be an empty array. 1012 3. While input_string is not empty: 1014 1. Discard any leading OWS from input_string. 1016 2. If the first character of input_string is ")": 1018 1. Consume the first character of input_string. 1020 2. Let parameters be the result of running Parsing 1021 Parameters (Section 4.2.3.2) with input_string. 1023 3. Return the tuple (inner_list, parameters). 1025 3. Let item be the result of running Parsing an Item 1026 (Section 4.2.3) with input_string. 1028 4. Append item to inner_list. 1030 5. If the first character of input_string is not SP or ")", fail 1031 parsing. 1033 4. The end of the inner list was not found; fail parsing. 1035 4.2.2. Parsing a Dictionary 1037 Given an ASCII string as input_string, return an ordered map whose 1038 values are (item_or_inner_list, parameters) tuples. input_string is 1039 modified to remove the parsed value. 1041 1. Let dictionary be an empty, ordered map. 1043 2. While input_string is not empty: 1045 1. Let this_key be the result of running Parsing a Key 1046 (Section 4.2.3.3) with input_string. 1048 2. If dictionary already contains the name this_key, there is a 1049 duplicate; fail parsing. 1051 3. Consume the first character of input_string; if it is not 1052 "=", fail parsing. 1054 4. Let member be the result of running Parsing an Item or Inner 1055 List (Section 4.2.1.1) with input_string. 1057 5. Add name this_key with value member to dictionary. 1059 6. Discard any leading OWS from input_string. 1061 7. If input_string is empty, return dictionary. 1063 8. Consume the first character of input_string; if it is not 1064 COMMA, fail parsing. 1066 9. Discard any leading OWS from input_string. 1068 10. If input_string is empty, there is a trailing comma; fail 1069 parsing. 1071 3. No structured data has been found; return dictionary (which is 1072 empty). 1074 4.2.3. Parsing an Item 1076 Given an ASCII string as input_string, return a (bare_item, 1077 parameters) tuple. input_string is modified to remove the parsed 1078 value. 1080 1. Let bare_item be the result of running Parsing a Bare Item 1081 (Section 4.2.3.1) with input_string. 1083 2. Let parameters be the result of running Parsing Parameters 1084 (Section 4.2.3.2) with input_string. 1086 3. Return the tuple (bare_item, parameters). 1088 4.2.3.1. Parsing a Bare Item 1090 Given an ASCII string as input_string, return a bare item. 1091 input_string is modified to remove the parsed value. 1093 1. If the first character of input_string is a "-" or a DIGIT, 1094 return the result of running Parsing a Number (Section 4.2.4) 1095 with input_string. 1097 2. If the first character of input_string is a DQUOTE, return the 1098 result of running Parsing a String (Section 4.2.5) with 1099 input_string. 1101 3. If the first character of input_string is "*", return the result 1102 of running Parsing a Byte Sequence (Section 4.2.7) with 1103 input_string. 1105 4. If the first character of input_string is "?", return the result 1106 of running Parsing a Boolean (Section 4.2.8) with input_string. 1108 5. If the first character of input_string is an ALPHA, return the 1109 result of running Parsing a Token (Section 4.2.6) with 1110 input_string. 1112 6. Otherwise, the item type is unrecognized; fail parsing. 1114 4.2.3.2. Parsing Parameters 1116 Given an ASCII string as input_string, return an ordered map whose 1117 values are bare items. input_string is modified to remove the parsed 1118 value. 1120 1. Let parameters be an empty, ordered map. 1122 2. While input_string is not empty: 1124 1. If the first character of input_string is not ";", exit the 1125 loop. 1127 2. Consume a ";" character from the beginning of input_string. 1129 3. Discard any leading OWS from input_string. 1131 4. let param_name be the result of running Parsing a Key 1132 (Section 4.2.3.3) with input_string. 1134 5. If param_name is already present in parameters, there is a 1135 duplicate; fail parsing. 1137 6. Let param_value be a null value. 1139 7. If the first character of input_string is "=": 1141 1. Consume the "=" character at the beginning of 1142 input_string. 1144 2. Let param_value be the result of running Parsing a Bare 1145 Item (Section 4.2.3.1) with input_string. 1147 8. Append key param_name with value param_value to parameters. 1149 3. Return parameters. 1151 4.2.3.3. Parsing a Key from Text 1153 Given an ASCII string as input_string, return a key. input_string is 1154 modified to remove the parsed value. 1156 1. If the first character of input_string is not lcalpha, fail 1157 parsing. 1159 2. Let output_string be an empty string. 1161 3. While input_string is not empty: 1163 1. If the first character of input_string is not one of lcalpha, 1164 DIGIT, "*", "_", or "-", return output_string. 1166 2. Let char be the result of removing the first character of 1167 input_string. 1169 3. Append char to output_string. 1171 4. Return output_string. 1173 4.2.4. Parsing a Number from Text 1175 Given an ASCII string as input_string, return a number. input_string 1176 is modified to remove the parsed value. 1178 NOTE: This algorithm parses both Integers (Section 3.3.1) and Floats 1179 (Section 3.3.2), and returns the corresponding structure. 1181 1. Let type be "integer". 1183 2. Let sign be 1. 1185 3. Let input_number be an empty string. 1187 4. If the first character of input_string is "-", consume it and 1188 set sign to -1. 1190 5. If input_string is empty, there is an empty integer; fail 1191 parsing. 1193 6. If the first character of input_string is not a DIGIT, fail 1194 parsing. 1196 7. While input_string is not empty: 1198 1. Let char be the result of consuming the first character of 1199 input_string. 1201 2. If char is a DIGIT, append it to input_number. 1203 3. Else, if type is "integer" and char is ".", append char to 1204 input_number and set type to "float". 1206 4. Otherwise, prepend char to input_string, and exit the loop. 1208 5. If type is "integer" and input_number contains more than 15 1209 characters, fail parsing. 1211 6. If type is "float" and input_number contains more than 16 1212 characters, fail parsing. 1214 8. If type is "integer": 1216 1. Parse input_number as an integer and let output_number be 1217 the product of the result and sign. 1219 2. If output_number is outside the range defined in 1220 Section 3.3.1, fail parsing. 1222 9. Otherwise: 1224 1. If the final character of input_number is ".", fail parsing. 1226 2. If the number of characters after "." in input_number is 1227 greater than six, fail parsing. 1229 3. Parse input_number as a float and let output_number be the 1230 product of the result and sign. 1232 10. Return output_number. 1234 4.2.5. Parsing a String from Text 1236 Given an ASCII string as input_string, return an unquoted string. 1237 input_string is modified to remove the parsed value. 1239 1. Let output_string be an empty string. 1241 2. If the first character of input_string is not DQUOTE, fail 1242 parsing. 1244 3. Discard the first character of input_string. 1246 4. While input_string is not empty: 1248 1. Let char be the result of consuming the first character of 1249 input_string. 1251 2. If char is a backslash ("\"): 1253 1. If input_string is now empty, fail parsing. 1255 2. Let next_char be the result of consuming the first 1256 character of input_string. 1258 3. If next_char is not DQUOTE or "\", fail parsing. 1260 4. Append next_char to output_string. 1262 3. Else, if char is DQUOTE, return output_string. 1264 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not 1265 in VCHAR or SP), fail parsing. 1267 5. Else, append char to output_string. 1269 5. Reached the end of input_string without finding a closing DQUOTE; 1270 fail parsing. 1272 4.2.6. Parsing a Token from Text 1274 Given an ASCII string as input_string, return a token. input_string 1275 is modified to remove the parsed value. 1277 1. If the first character of input_string is not ALPHA, fail 1278 parsing. 1280 2. Let output_string be an empty string. 1282 3. While input_string is not empty: 1284 1. If the first character of input_string is not allowed by the 1285 tchar ABNF rule, return output_string. 1287 2. Let char be the result of consuming the first character of 1288 input_string. 1290 3. Append char to output_string. 1292 4. Return output_string. 1294 4.2.7. Parsing a Byte Sequence from Text 1296 Given an ASCII string as input_string, return a byte sequence. 1297 input_string is modified to remove the parsed value. 1299 1. If the first character of input_string is not "*", fail parsing. 1301 2. Discard the first character of input_string. 1303 3. If there is not a "*" character before the end of input_string, 1304 fail parsing. 1306 4. Let b64_content be the result of consuming content of 1307 input_string up to but not including the first instance of the 1308 character "*". 1310 5. Consume the "*" character at the beginning of input_string. 1312 6. If b64_content contains a character not included in ALPHA, DIGIT, 1313 "+", "/" and "=", fail parsing. 1315 7. Let binary_content be the result of Base 64 Decoding [RFC4648] 1316 b64_content, synthesizing padding if necessary (note the 1317 requirements about recipient behaviour below). 1319 8. Return binary_content. 1321 Because some implementations of base64 do not allow reject of encoded 1322 data that is not properly "=" padded (see [RFC4648], Section 3.2), 1323 parsers SHOULD NOT fail when it is not present, unless they cannot be 1324 configured to do so. 1326 Because some implementations of base64 do not allow rejection of 1327 encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), 1328 parsers SHOULD NOT fail when it is present, unless they cannot be 1329 configured to do so. 1331 This specification does not relax the requirements in [RFC4648], 1332 Section 3.1 and 3.3; therefore, parsers MUST fail on characters 1333 outside the base64 alphabet, and on line feeds in encoded data. 1335 4.2.8. Parsing a Boolean from Text 1337 Given an ASCII string as input_string, return a Boolean. input_string 1338 is modified to remove the parsed value. 1340 1. If the first character of input_string is not "?", fail parsing. 1342 2. Discard the first character of input_string. 1344 3. If the first character of input_string matches "1", discard the 1345 first character, and return true. 1347 4. If the first character of input_string matches "0", discard the 1348 first character, and return false. 1350 5. No value has matched; fail parsing. 1352 5. IANA Considerations 1354 This draft has no actions for IANA. 1356 6. Security Considerations 1358 The size of most types defined by Structured Headers is not limited; 1359 as a result, extremely large header fields could be an attack vector 1360 (e.g., for resource consumption). Most HTTP implementations limit 1361 the sizes of individual header fields as well as the overall header 1362 block size to mitigate such attacks. 1364 It is possible for parties with the ability to inject new HTTP header 1365 fields to change the meaning of a Structured Header. In some 1366 circumstances, this will cause parsing to fail, but it is not 1367 possible to reliably fail in all such circumstances. 1369 7. References 1371 7.1. Normative References 1373 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1374 RFC 20, DOI 10.17487/RFC0020, October 1969, 1375 . 1377 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1378 Requirement Levels", BCP 14, RFC 2119, 1379 DOI 10.17487/RFC2119, March 1997, 1380 . 1382 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 1383 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 1384 . 1386 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 1387 Specifications: ABNF", STD 68, RFC 5234, 1388 DOI 10.17487/RFC5234, January 2008, 1389 . 1391 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1392 Protocol (HTTP/1.1): Message Syntax and Routing", 1393 RFC 7230, DOI 10.17487/RFC7230, June 2014, 1394 . 1396 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1397 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1398 May 2017, . 1400 7.2. Informative References 1402 [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 1403 IEEE 754-2019, DOI 10.1109/IEEESTD.2019.8766229, 1404 ISBN 978-1-5044-5924-2, July 2019, 1405 . 1407 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1408 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 1409 DOI 10.17487/RFC7231, June 2014, 1410 . 1412 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 1413 DOI 10.17487/RFC7493, March 2015, 1414 . 1416 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 1417 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 1418 DOI 10.17487/RFC7540, May 2015, 1419 . 1421 [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for 1422 HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, 1423 . 1425 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 1426 Interchange Format", STD 90, RFC 8259, 1427 DOI 10.17487/RFC8259, December 2017, 1428 . 1430 [UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO 1431 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November 1432 2003, . 1434 7.3. URIs 1436 [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ 1438 [2] https://httpwg.github.io/ 1440 [3] https://github.com/httpwg/http-extensions/labels/header-structure 1442 [4] https://github.com/httpwg/structured-header-tests 1444 [5] https://github.com/httpwg/wiki/wiki/Structured-Headers 1446 [6] https://github.com/httpwg/structured-header-tests 1448 Appendix A. Acknowledgements 1450 Many thanks to Matthew Kerwin for his detailed feedback and careful 1451 consideration during the development of this specification. 1453 Appendix B. Frequently Asked Questions 1455 B.1. Why not JSON? 1457 Earlier proposals for structured headers were based upon JSON 1458 [RFC8259]. However, constraining its use to make it suitable for 1459 HTTP header fields required senders and recipients to implement 1460 specific additional handling. 1462 For example, JSON has specification issues around large numbers and 1463 objects with duplicate members. Although advice for avoiding these 1464 issues is available (e.g., [RFC7493]), it cannot be relied upon. 1466 Likewise, JSON strings are by default Unicode strings, which have a 1467 number of potential interoperability issues (e.g., in comparison). 1468 Although implementers can be advised to avoid non-ASCII content where 1469 unnecessary, this is difficult to enforce. 1471 Another example is JSON's ability to nest content to arbitrary 1472 depths. Since the resulting memory commitment might be unsuitable 1473 (e.g., in embedded and other limited server deployments), it's 1474 necessary to limit it in some fashion; however, existing JSON 1475 implementations have no such limits, and even if a limit is 1476 specified, it's likely that some header field definition will find a 1477 need to violate it. 1479 Because of JSON's broad adoption and implementation, it is difficult 1480 to impose such additional constraints across all implementations; 1481 some deployments would fail to enforce them, thereby harming 1482 interoperability. In short, if it looks like JSON, people will be 1483 tempted to use a JSON parser / serialiser on header fields. 1485 Since a major goal for Structured Headers is to improve 1486 interoperability and simplify implementation, these concerns led to a 1487 format that requires a dedicated parser and serializer. 1489 Additionally, there were widely shared feelings that JSON doesn't 1490 "look right" in HTTP headers. 1492 B.2. Structured Headers don't "fit" my data. 1494 Structured headers intentionally limits the complexity of data 1495 structures, to assure that it can be processed in a performant manner 1496 with little overhead. This means that work is necessary to fit some 1497 data types into them. 1499 Sometimes, this can be achieved by creating limited substructures in 1500 values, and/or using more than one header. For example, consider: 1502 Example-Thing: name="Widget", cost=89.2, descriptions=(foo bar) 1503 Example-Description: foo; url="https://example.net"; context=123, 1504 bar; url="https://example.org"; context=456 1506 Since the description contains an array of key/value pairs, we use a 1507 List to represent them, with the token for each item in the array 1508 used to identify it in the "descriptions" member of the Example-Thing 1509 header. 1511 When specifying more than one header, it's important to remember to 1512 describe what a processor's behaviour should be when one of the 1513 headers is missing. 1515 If you need to fit arbitrarily complex data into a header, Structured 1516 Headers is probably a poor fit for your use case. 1518 Appendix C. Implementation Notes 1520 A generic implementation of this specification should expose the top- 1521 level parse (Section 4.2) and serialize (Section 4.1) functions. 1522 They need not be functions; for example, it could be implemented as 1523 an object, with methods for each of the different top-level types. 1525 For interoperability, it's important that generic implementations be 1526 complete and follow the algorithms closely; see Section 1.1. To aid 1527 this, a common test suite is being maintained by the community at 1528 https://github.com/httpwg/structured-header-tests [6]. 1530 Implementers should note that dictionaries and parameters are order- 1531 preserving maps. Some headers may not convey meaning in the ordering 1532 of these data types, but it should still be exposed so that 1533 applications which need to use it will have it available. 1535 Likewise, implementations should note that it's important to preserve 1536 the distinction between tokens and strings. While most programming 1537 languages have native types that map to the other types well, it may 1538 be necessary to create a wrapper "token" object or use a parameter on 1539 functions to assure that these types remain separate. 1541 Appendix D. Changes 1543 _RFC Editor: Please remove this section before publication._ 1545 D.1. Since draft-ietf-httpbis-header-structure-13 1547 o Editorial improvements. 1549 o Define "structured header name" and "structured header value" 1550 terms (#908). 1552 o Corrected text about valid characters in strings (#931). 1554 o Removed most instances of the word "textual", as it was redundant 1555 (#915). 1557 o Allowed parameters on Items and Inner Lists (#907). 1559 o Expand the range of characters in token (#961). 1561 D.2. Since draft-ietf-httpbis-header-structure-12 1563 o Editorial improvements. 1565 o Reworked float serialisation (#896). 1567 o Don't add a trailing space in inner-list (#904). 1569 D.3. Since draft-ietf-httpbis-header-structure-11 1571 o Allow * in key (#844). 1573 o Constrain floats to six digits of precision (#848). 1575 o Allow dictionary members to have parameters (#842). 1577 D.4. Since draft-ietf-httpbis-header-structure-10 1579 o Update abstract (#799). 1581 o Input and output are now arrays of bytes (#662). 1583 o Implementations need to preserve difference between token and 1584 string (#790). 1586 o Allow empty dictionaries and lists (#781). 1588 o Change parameterized lists to have primary items (#797). 1590 o Allow inner lists in both dictionaries and lists; removes lists of 1591 lists (#816). 1593 o Subsume Parameterised Lists into Lists (#839). 1595 D.5. Since draft-ietf-httpbis-header-structure-09 1597 o Changed Boolean from T/F to 1/0 (#784). 1599 o Parameters are now ordered maps (#765). 1601 o Clamp integers to 15 digits (#737). 1603 D.6. Since draft-ietf-httpbis-header-structure-08 1605 o Disallow whitespace before items properly (#703). 1607 o Created "key" for use in dictionaries and parameters, rather than 1608 relying on identifier (#702). Identifiers have a separate minimum 1609 supported size. 1611 o Expanded the range of special characters allowed in identifier to 1612 include all of ALPHA, ".", ":", and "%" (#702). 1614 o Use "?" instead of "!" to indicate a Boolean (#719). 1616 o Added "Intentionally Strict Processing" (#684). 1618 o Gave better names for referring specs to use in Parameterised 1619 Lists (#720). 1621 o Added Lists of Lists (#721). 1623 o Rename Identifier to Token (#725). 1625 o Add implementation guidance (#727). 1627 D.7. Since draft-ietf-httpbis-header-structure-07 1629 o Make Dictionaries ordered mappings (#659). 1631 o Changed "binary content" to "byte sequence" to align with Infra 1632 specification (#671). 1634 o Changed "mapping" to "map" for #671. 1636 o Don't fail if byte sequences aren't "=" padded (#658). 1638 o Add Booleans (#683). 1640 o Allow identifiers in items again (#629). 1642 o Disallowed whitespace before items (#703). 1644 o Explain the consequences of splitting a string across multiple 1645 headers (#686). 1647 D.8. Since draft-ietf-httpbis-header-structure-06 1649 o Add a FAQ. 1651 o Allow non-zero pad bits. 1653 o Explicitly check for integers that violate constraints. 1655 D.9. Since draft-ietf-httpbis-header-structure-05 1657 o Reorganise specification to separate parsing out. 1659 o Allow referencing specs to use ABNF. 1661 o Define serialisation algorithms. 1663 o Refine relationship between ABNF, parsing and serialisation 1664 algorithms. 1666 D.10. Since draft-ietf-httpbis-header-structure-04 1668 o Remove identifiers from item. 1670 o Remove most limits on sizes. 1672 o Refine number parsing. 1674 D.11. Since draft-ietf-httpbis-header-structure-03 1676 o Strengthen language around failure handling. 1678 D.12. Since draft-ietf-httpbis-header-structure-02 1680 o Split Numbers into Integers and Floats. 1682 o Define number parsing. 1684 o Tighten up binary parsing and give it an explicit end delimiter. 1686 o Clarify that mappings are unordered. 1688 o Allow zero-length strings. 1690 o Improve string parsing algorithm. 1692 o Improve limits in algorithms. 1694 o Require parsers to combine header fields before processing. 1696 o Throw an error on trailing garbage. 1698 D.13. Since draft-ietf-httpbis-header-structure-01 1700 o Replaced with draft-nottingham-structured-headers. 1702 D.14. Since draft-ietf-httpbis-header-structure-00 1704 o Added signed 64bit integer type. 1706 o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- 1707 unicode-string. 1709 o Change h1_blob delimiter to ":" since "'" is valid t_char 1711 Authors' Addresses 1713 Mark Nottingham 1714 Fastly 1716 Email: mnot@mnot.net 1717 URI: https://www.mnot.net/ 1719 Poul-Henning Kamp 1720 The Varnish Cache Project 1722 Email: phk@varnish-cache.org