idnits 2.17.1 draft-ietf-httpbis-header-structure-13.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The 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 (August 24, 2019) is 1697 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 1341 -- Looks like a reference, but probably isn't: '2' on line 1343 -- Looks like a reference, but probably isn't: '3' on line 1345 -- Looks like a reference, but probably isn't: '4' on line 1347 -- Looks like a reference, but probably isn't: '5' on line 1349 == Missing Reference: 'RFCxxxx' is mentioned on line 259, but not defined == Missing Reference: 'RFC3986' is mentioned on line 271, but not defined -- Looks like a reference, but probably isn't: '6' on line 1351 -- Looks like a reference, but probably isn't: '7' on line 1433 ** 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: 2 errors (**), 0 flaws (~~), 3 warnings (==), 10 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: February 25, 2020 The Varnish Cache Project 6 August 24, 2019 8 Structured Headers for HTTP 9 draft-ietf-httpbis-header-structure-13 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 February 25, 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 Header Data Types . . . . . . . . . . . . . . . . 6 77 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 7 78 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 8 79 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 9 80 3.4. Integers . . . . . . . . . . . . . . . . . . . . . . . . 9 81 3.5. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 9 82 3.6. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 10 83 3.7. Tokens . . . . . . . . . . . . . . . . . . . . . . . . . 11 84 3.8. Byte Sequences . . . . . . . . . . . . . . . . . . . . . 11 85 3.9. Booleans . . . . . . . . . . . . . . . . . . . . . . . . 11 86 4. Working With Structured Headers in Textual HTTP Headers . . . 12 87 4.1. Serializing Structured Headers . . . . . . . . . . . . . 12 88 4.2. Parsing Header Fields into Structured Headers . . . . . . 18 89 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 90 6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 91 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 92 7.1. Normative References . . . . . . . . . . . . . . . . . . 27 93 7.2. Informative References . . . . . . . . . . . . . . . . . 28 94 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 29 95 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 29 96 Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 29 97 B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 29 98 B.2. Structured Headers don't "fit" my data. . . . . . . . . . 30 99 Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 31 100 Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 31 101 D.1. Since draft-ietf-httpbis-header-structure-12 . . . . . . 31 102 D.2. Since draft-ietf-httpbis-header-structure-11 . . . . . . 31 103 D.3. Since draft-ietf-httpbis-header-structure-10 . . . . . . 31 104 D.4. Since draft-ietf-httpbis-header-structure-09 . . . . . . 32 105 D.5. Since draft-ietf-httpbis-header-structure-08 . . . . . . 32 106 D.6. Since draft-ietf-httpbis-header-structure-07 . . . . . . 33 107 D.7. Since draft-ietf-httpbis-header-structure-06 . . . . . . 33 108 D.8. Since draft-ietf-httpbis-header-structure-05 . . . . . . 33 109 D.9. Since draft-ietf-httpbis-header-structure-04 . . . . . . 33 110 D.10. Since draft-ietf-httpbis-header-structure-03 . . . . . . 34 111 D.11. Since draft-ietf-httpbis-header-structure-02 . . . . . . 34 112 D.12. Since draft-ietf-httpbis-header-structure-01 . . . . . . 34 113 D.13. Since draft-ietf-httpbis-header-structure-00 . . . . . . 34 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 Section 8.3.1 of [RFC7231], 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 serializers 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 definitions of new HTTP header field values to address these 129 problems. In particular, it defines a generic, abstract model for 130 header field values, along with a concrete serialisation for 131 expressing that model in textual HTTP [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 Section 2 describes how to specify a Structured Header. 149 Section 3 defines a number of abstract data types that can be used in 150 Structured Headers. Those abstract types can be serialized into and 151 parsed from textual HTTP headers using the algorithms described in 152 Section 4. 154 1.1. Intentionally Strict Processing 156 This specification intentionally defines strict parsing and 157 serialisation behaviours using step-by-step algorithms; the only 158 error handling defined is to fail the operation altogether. 160 It is designed to encourage faithful implementation and therefore 161 good interoperability. Therefore, an implementation that tried to be 162 "helpful" by being more tolerant of input would make interoperability 163 worse, since that would create pressure on other implementations to 164 implement similar (but likely subtly different) workarounds. 166 In other words, strict processing is an intentional feature of this 167 specification; it allows non-conformant input to be discovered and 168 corrected by the producer early, and avoids both interoperability and 169 security issues that might otherwise result. 171 Note that as a result of this strictness, if a header field is 172 appended to by multiple parties (e.g., intermediaries, or different 173 components in the sender), an error in one party's value is likely to 174 cause the entire header field to fail parsing. 176 1.2. Notational Conventions 178 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 179 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 180 "OPTIONAL" in this document are to be interpreted as described in BCP 181 14 [RFC2119] [RFC8174] when, and only when, they appear in all 182 capitals, as shown here. 184 This document uses algorithms to specify parsing and serialisation 185 behaviours, and the Augmented Backus-Naur Form (ABNF) notation of 186 [RFC5234] to illustrate expected syntax in textual HTTP header 187 fields. In doing so, uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE 188 rules from [RFC5234]. It also includes the OWS rule from [RFC7230]. 190 When parsing from textual HTTP header fields, implementations MUST 191 follow the algorithms, but MAY vary in implementation so as the 192 behaviours are indistinguishable from specified behaviour. If there 193 is disagreement between the parsing algorithms and ABNF, the 194 specified algorithms take precedence. In some places, the algorithms 195 are "greedy" with whitespace, but this should not affect conformance. 197 For serialisation to textual header fields, the ABNF illustrates the 198 range of acceptable wire representations with as much fidelity as 199 possible, and the algorithms define the recommended way to produce 200 them. Implementations MAY vary from the specified behaviour so long 201 as the output still matches the ABNF. 203 2. Defining New Structured Headers 205 To define a HTTP header as a structured header, its specification 206 needs to: 208 o Reference this specification. Recipients and generators of the 209 header need to know that the requirements of this document are in 210 effect. 212 o Specify the header field's allowed syntax for values, in terms of 213 the types described in Section 3, along with their associated 214 semantics. Syntax definitions are encouraged to use the ABNF 215 rules beginning with "sh-" defined in this specification; other 216 rules in this specification are not intended for use outside it. 218 o Specify any additional constraints upon the syntax of the 219 structures used, as well as the consequences when those 220 constraints are violated. When Structured Headers parsing fails, 221 the header is ignored (see Section 4.2); in most situations, 222 header-specific constraints should do likewise. 224 Note that a header field definition cannot relax the requirements of 225 this specification because doing so would preclude handling by 226 generic software; they can only add additional constraints (for 227 example, on the numeric range of integers and floats, the format of 228 strings and tokens, the types allowed in a dictionary's values, or 229 the number of items in a list). Likewise, header field definitions 230 can only use Structured Headers for the entire header field value, 231 not a portion thereof. 233 This specification defines minimums for the length or number of 234 various structures supported by Structured Headers implementations. 235 It does not specify maximum sizes in most cases, but header authors 236 should be aware that HTTP implementations do impose various limits on 237 the size of individual header fields, the total number of fields, 238 and/or the size of the entire header block. 240 For example, a fictitious Foo-Example header field might be specified 241 as: 243 42. Foo-Example Header 245 The Foo-Example HTTP header field conveys information about how 246 much Foo the message has. 248 Foo-Example is a Structured Header [RFCxxxx]. Its value MUST be a 249 dictionary (Section Y.Y of [RFCxxxx]). Its ABNF is: 251 Foo-Example = sh-dictionary 253 The dictionary MUST contain: 255 * Exactly one member whose name is "foo", and whose value is an 256 integer (Section Y.Y of [RFCxxxx]), indicating the number of foos 257 in the message. 258 * Exactly one member whose name is "barUrl", and whose value is a 259 list of strings (Section Y.Y of [RFCxxxx]), conveying the Bar URLs 260 for the message. See below for processing requirements. 262 If the parsed header field does not contain both, it MUST be 263 ignored. 265 "foo" MUST be between 0 and 10, inclusive; other values MUST cause 266 the header to be ignored. 268 "barUrl" contains one or more URI-references (Section 4.1 of 269 [RFC3986], Section 4.1). If barURL is not a valid URI-reference, 270 it MUST be ignored. If barURL is a relative reference (Section 4.2 271 of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before 272 being used. 274 For example: 276 Foo-Example: foo=2, barUrl=("https://bar.example.com/") 278 3. Structured Header Data Types 280 This section defines the abstract value types that can be composed 281 into Structured Headers. The ABNF provided represents the on-wire 282 format in textual HTTP headers. 284 3.1. Lists 286 Lists are arrays of zero or more members, each of which can be an 287 item (Section 3.3) or an inner list (an array of zero or more items). 289 Each member of the top-level list can also have associated parameters 290 - an ordered map of key-value pairs where the keys are short, textual 291 strings and the values are items (Section 3.3). There can be zero or 292 more parameters on a member, and their keys are required to be unique 293 within that scope. 295 The ABNF for lists is: 297 sh-list = list-member *( OWS "," OWS list-member ) 298 list-member = ( sh-item / inner-list ) *parameter 299 inner-list = "(" OWS [ sh-item *( SP sh-item ) OWS ] ")" 300 parameter = OWS ";" OWS param-name [ "=" param-value ] 301 param-name = key 302 key = lcalpha *( lcalpha / DIGIT / "_" / "-" / "*" ) 303 lcalpha = %x61-7A ; a-z 304 param-value = sh-item 306 In textual HTTP headers, each member is separated by a comma and 307 optional whitespace. For example, a header field whose value is 308 defined as a list of strings could look like: 310 Example-StrListHeader: "foo", "bar", "It was the best of times." 312 In textual HTTP headers, inner lists are denoted by surrounding 313 parenthesis, and have their values delimited by a single space. A 314 header field whose value is defined as a list of lists of strings 315 could look like: 317 Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () 319 Note that the last member in this example is an empty inner list. 321 In textual HTTP headers, members' parameters are separated from the 322 member and each other by semicolons. For example: 324 Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w 326 In textual HTTP headers, an empty list is denoted by not serialising 327 the header at all. 329 Parsers MUST support lists containing at least 1024 members, support 330 members with at least 256 parameters, support inner-lists containing 331 at least 256 members, and support parameter keys with at least 64 332 characters. 334 Header specifications can constrain the types of individual list 335 values (including that of individual inner-list members and 336 parameters) if necessary. 338 3.2. Dictionaries 340 Dictionaries are ordered maps of name-value pairs, where the names 341 are short, textual strings and the values are items (Section 3.3) or 342 arrays of items. There can be zero or more members, and their names 343 are required to be unique within the scope of the dictionary they 344 occur within. 346 Each member of the dictionary can also have associated parameters - 347 an ordered map of key-value pairs where the keys are short, textual 348 strings and the values are items (Section 3.3). There can be zero or 349 more parameters on a member, and their keys are required to be unique 350 within that scope. 352 Implementations MUST provide access to dictionaries both by index and 353 by name. Specifications MAY use either means of accessing the 354 members. 356 The ABNF for dictionaries in textual HTTP headers is: 358 sh-dictionary = dict-member *( OWS "," OWS dict-member ) 359 dict-member = member-name "=" member-value *parameter 360 member-name = key 361 member-value = sh-item / inner-list 363 In textual HTTP headers, members are separated by a comma with 364 optional whitespace, while names and values are separated by "=" 365 (without whitespace). For example: 367 Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=* 369 A dictionary with a member whose value is an inner-list of tokens: 371 Example-DictListHeader: rating=1.5, feelings=(joy sadness) 373 A dictionary with a mix of singular and list values, some with 374 parameters: 376 Example-MixDict: a=(1,2), b=3, c=4;aa=bb, d=(5,6);valid=?T 377 As with lists, an empty dictionary is represented in textual HTTP 378 headers by omitting the entire header field. 380 Typically, a header field specification will define the semantics 381 using individual member names, as well as whether their presence is 382 required or optional. Recipients MUST ignore names that are 383 undefined or unknown, unless the header field's specification 384 specifically disallows them. 386 Parsers MUST support dictionaries containing at least 1024 name/value 387 pairs, and names with at least 64 characters. 389 3.3. Items 391 An item is can be a integer (Section 3.4), float (Section 3.5), 392 string (Section 3.6), token (Section 3.7), byte sequence 393 (Section 3.8), or Boolean (Section 3.9). 395 The ABNF for items in textual HTTP headers is: 397 sh-item = sh-integer / sh-float / sh-string / sh-token / sh-binary 398 / sh-boolean 400 3.4. Integers 402 Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 403 inclusive (i.e., up to fifteen digits, signed), for IEEE 754 404 compatibility ([IEEE754]). 406 The ABNF for integers in textual HTTP headers is: 408 sh-integer = ["-"] 1*15DIGIT 410 For example: 412 Example-IntegerHeader: 42 414 Note that commas in integers are used in this section's prose only 415 for readability; they are not valid in the wire format. 417 3.5. Floats 419 Floats are decimal numbers with an integer and a fractional 420 component. The fractional component has at most six digits of 421 precision. Additionally, like integers, it can have no more than 422 fifteen digits in total, which in some cases further constrains its 423 precision. 425 The ABNF for floats in textual HTTP headers is: 427 sh-float = ["-"] (1*9DIGIT "." 1*6DIGIT / 428 10DIGIT "." 1*5DIGIT / 429 11DIGIT "." 1*4DIGIT / 430 12DIGIT "." 1*3DIGIT / 431 13DIGIT "." 1*2DIGIT / 432 14DIGIT "." 1DIGIT ) 434 For example, a header whose value is defined as a float could look 435 like: 437 Example-FloatHeader: 4.5 439 3.6. Strings 441 Strings are zero or more printable ASCII [RFC0020] characters (i.e., 442 the range 0x20 to 0x7E). Note that this excludes tabs, newlines, 443 carriage returns, etc. 445 The ABNF for strings in textual HTTP headers is: 447 sh-string = DQUOTE *(chr) DQUOTE 448 chr = unescaped / escaped 449 unescaped = %x20-21 / %x23-5B / %x5D-7E 450 escaped = "\" ( DQUOTE / "\" ) 452 In textual HTTP headers, strings are delimited with double quotes, 453 using a backslash ("\") to escape double quotes and backslashes. For 454 example: 456 Example-StringHeader: "hello world" 458 Note that strings only use DQUOTE as a delimiter; single quotes do 459 not delimit strings. Furthermore, only DQUOTE and "\" can be 460 escaped; other sequences MUST cause parsing to fail. 462 Unicode is not directly supported in this document, because it causes 463 a number of interoperability issues, and - with few exceptions - 464 header values do not require it. 466 When it is necessary for a field value to convey non-ASCII string 467 content, a byte sequence (Section 3.8) SHOULD be specified, along 468 with a character encoding (preferably UTF-8). 470 Parsers MUST support strings with at least 1024 characters. 472 3.7. Tokens 474 Tokens are short textual words; their abstract model is identical to 475 their expression in the textual HTTP serialisation. 477 The ABNF for tokens in textual HTTP headers is: 479 sh-token = ALPHA 480 *( ALPHA / DIGIT / "_" / "-" / "." / ":" / "%" 481 / "*" / "/" ) 483 Parsers MUST support tokens with at least 512 characters. 485 Note that a Structured Header token is not the same as the "token" 486 ABNF rule defined in [RFC7230]. 488 3.8. Byte Sequences 490 Byte sequences can be conveyed in Structured Headers. 492 The ABNF for a byte sequence in textual HTTP headers is: 494 sh-binary = "*" *(base64) "*" 495 base64 = ALPHA / DIGIT / "+" / "/" / "=" 497 In textual HTTP headers, a byte sequence is delimited with asterisks 498 and encoded using base64 ([RFC4648], Section 4). For example: 500 Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==* 502 Parsers MUST support byte sequences with at least 16384 octets after 503 decoding. 505 3.9. Booleans 507 Boolean values can be conveyed in Structured Headers. 509 The ABNF for a Boolean in textual HTTP headers is: 511 sh-boolean = "?" boolean 512 boolean = "0" / "1" 514 In textual HTTP headers, a boolean is indicated with a leading "?" 515 character. For example: 517 Example-BoolHdr: ?1 519 4. Working With Structured Headers in Textual HTTP Headers 521 This section defines how to serialize and parse Structured Headers in 522 textual header fields, and protocols compatible with them (e.g., in 523 HTTP/2 [RFC7540] before HPACK [RFC7541] is applied). 525 4.1. Serializing Structured Headers 527 Given a structure defined in this specification, return an ASCII 528 string suitable for use in a textual HTTP header value. 530 1. If the structure is a dictionary or list and its value is empty 531 (i.e., it has no members), do not send the serialize field at all 532 (i.e., omit both the field-name and field-value). 534 2. If the structure is a dictionary, let output_string be the result 535 of Serializing a Dictionary (Section 4.1.2). 537 3. Else if the structure is a list, let output_string be the result 538 of Serializing a List (Section 4.1.1). 540 4. Else if the structure is an item, let output_string be the result 541 of Serializing an Item (Section 4.1.3). 543 5. Else, fail serialisation. 545 6. Return output_string converted into an array of bytes, using 546 ASCII encoding [RFC0020]. 548 4.1.1. Serializing a List 550 Given a list of (member-value, parameters) as input_list, return an 551 ASCII string suitable for use in a textual HTTP header value. 553 1. Let output be an empty string. 555 2. For each (member-value, parameters) of input_list: 557 1. If member-value is an array, append the result of applying 558 Serialising an Inner List (Section 4.1.1.1) with member-value 559 to output. 561 2. Otherwise, append the result of applying Serializing an Item 562 (Section 4.1.3) with member-value to output. 564 3. Append the result of Serializing Parameters Section 4.1.1.2 565 with parameters to output. 567 4. If more member-values remain in input_plist: 569 1. Append a COMMA to output. 571 2. Append a single WS to output. 573 3. Return output. 575 4.1.1.1. Serialising an Inner List 577 Given an array as inner_list, return an ASCII string suitable for use 578 in a textual HTTP header value. 580 1. Let output be the string "(". 582 2. For each member-value of inner_list: 584 1. Append the result of applying Serializing an Item 585 (Section 4.1.3) with member-value to output. 587 2. If inner_list is not empty, append a single WS to output. 589 3. Append ")" to output. 591 4. Return output. 593 4.1.1.2. Serializing Parameters 595 Given an ordered dictionary as input_parameters (each member having a 596 param-name and a param-value), return an ASCII string suitable for 597 use in a textual HTTP header value. 599 1. Let output be an empty string. 601 2. For each parameter-name with a value of param-value in 602 input_parameters: 604 1. Append ";" to output. 606 2. Append the result of applying Serializing a Key 607 (Section 4.1.1.3) with param-name to output. 609 3. If param-value is not null: 611 1. Append "=" to output. 613 2. Append the result of applying Serializing an Item 614 (Section 4.1.3) with param-value to output. 616 3. Return output. 618 4.1.1.3. Serializing a Key 620 Given a key as input_key, return an ASCII string suitable for use in 621 a textual HTTP header value. 623 1. If input_key is not a sequence of characters, or contains 624 characters not in lcalpha, DIGIT, "*", "_", or "-", fail 625 serialisation. 627 2. Let output be an empty string. 629 3. Append input_key to output. 631 4. Return output. 633 4.1.2. Serializing a Dictionary 635 Given an ordered dictionary as input_dictionary (each member having a 636 member-name and a tuple value of (member-value, parameters)), return 637 an ASCII string suitable for use in a textual HTTP header value. 639 1. Let output be an empty string. 641 2. For each member-name with a value of (member-value, parameters) 642 in input_dictionary: 644 1. Append the result of applying Serializing a Key 645 (Section 4.1.1.3) with member's member-name to output. 647 2. Append "=" to output. 649 3. If member-value is an array, append the result of applying 650 Serialising an Inner List (Section 4.1.1.1) with member-value 651 to output. 653 4. Otherwise, append the result of applying Serializing an Item 654 (Section 4.1.3) with member-value to output. 656 5. Append the result of Serializing Parameters Section 4.1.1.2 657 with parameters to output. 659 6. If more members remain in input_dictionary: 661 1. Append a COMMA to output. 663 2. Append a single WS to output. 665 3. Return output. 667 4.1.3. Serializing an Item 669 Given an item as input_item, return an ASCII string suitable for use 670 in a textual HTTP header value. 672 1. If input_item is an integer, return the result of applying 673 Serializing an Integer (Section 4.1.4) to input_item. 675 2. If input_item is a float, return the result of applying 676 Serializing a Float (Section 4.1.5) to input_item. 678 3. If input_item is a string, return the result of applying 679 Serializing a String (Section 4.1.6) to input_item. 681 4. If input_item is a token, return the result of Serializing a 682 Token (Section 4.1.7) to input_item. 684 5. If input_item is a Boolean, return the result of applying 685 Serializing a Boolean (Section 4.1.9) to input_item. 687 6. If input_item is a byte sequence, return the result of applying 688 Serializing a Byte Sequence (Section 4.1.8) to input_item. 690 7. Otherwise, fail serialisation. 692 4.1.4. Serializing an Integer 694 Given an integer as input_integer, return an ASCII string suitable 695 for use in a textual HTTP header value. 697 1. If input_integer is not an integer in the range of 698 -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail 699 serialisation. 701 2. Let output be an empty string. 703 3. If input_integer is less than (but not equal to) 0, append "-" to 704 output. 706 4. Append input_integer's numeric value represented in base 10 using 707 only decimal digits to output. 709 5. Return output. 711 4.1.5. Serializing a Float 713 Given a float as input_float, return an ASCII string suitable for use 714 in a textual HTTP header value. 716 1. Let output be an empty string. 718 2. If input_float is less than (but not equal to) 0, append "-" to 719 output. 721 3. Append input_float's integer component represented in base 10 722 (using only decimal digits) to output; if it is zero, append 723 "0". 725 4. Let integer_digits be the number of characters appended in the 726 previous step. 728 5. If integer_digits is greater than 14, fail serialisation. 730 6. Let digits_avail be 15 minus integer_digits. 732 7. Let fractional_digits_avail be the minimum of digits_avail and 733 6. 735 8. Append "." to output. 737 9. Append at most fractional_digits_avail digits of input_float's 738 fractional component represented in base 10 to output (using 739 only decimal digits, and truncating any remaining digits); if it 740 is zero, append "0". 742 10. Return output. 744 4.1.6. Serializing a String 746 Given a string as input_string, return an ASCII string suitable for 747 use in a textual HTTP header value. 749 1. If input_string is not a sequence of characters, or contains 750 characters outside the range %x00-1f or %x7f (i.e., is not in 751 VCHAR or SP), fail serialisation. 753 2. Let output be an empty string. 755 3. Append DQUOTE to output. 757 4. For each character char in input_string: 759 1. If char is "\" or DQUOTE: 761 1. Append "\" to output. 763 2. Append char to output. 765 5. Append DQUOTE to output. 767 6. Return output. 769 4.1.7. Serializing a Token 771 Given a token as input_token, return an ASCII string suitable for use 772 in a textual HTTP header value. 774 1. If input_token is not a sequence of characters, or contains 775 characters not in ALPHA, DIGIT, "_", "-", ".", ":", "%", "*" or 776 "/", fail serialisation. 778 2. Let output be an empty string. 780 3. Append input_token to output. 782 4. Return output. 784 4.1.8. Serializing a Byte Sequence 786 Given a byte sequence as input_bytes, return an ASCII string suitable 787 for use in a textual HTTP header value. 789 1. If input_bytes is not a sequence of bytes, fail serialisation. 791 2. Let output be an empty string. 793 3. Append "*" to output. 795 4. Append the result of base64-encoding input_bytes as per 796 [RFC4648], Section 4, taking account of the requirements below. 798 5. Append "*" to output. 800 6. Return output. 802 The encoded data is required to be padded with "=", as per [RFC4648], 803 Section 3.2. 805 Likewise, encoded data SHOULD have pad bits set to zero, as per 806 [RFC4648], Section 3.5, unless it is not possible to do so due to 807 implementation constraints. 809 4.1.9. Serializing a Boolean 811 Given a Boolean as input_boolean, return an ASCII string suitable for 812 use in a textual HTTP header value. 814 1. If input_boolean is not a boolean, fail serialisation. 816 2. Let output be an empty string. 818 3. Append "?" to output. 820 4. If input_boolean is true, append "1" to output. 822 5. If input_boolean is false, append "0" to output. 824 6. Return output. 826 4.2. Parsing Header Fields into Structured Headers 828 When a receiving implementation parses textual HTTP header fields 829 that are known to be Structured Headers, it is important that care be 830 taken, as there are a number of edge cases that can cause 831 interoperability or even security problems. This section specifies 832 the algorithm for doing so. 834 Given an array of bytes input_bytes that represents the chosen 835 header's field-value (which is an empty string if that header is not 836 present), and header_type (one of "dictionary", "list", or "item"), 837 return the parsed header value. 839 1. Convert input_bytes into an ASCII string input_string; if 840 conversion fails, fail parsing. 842 2. Discard any leading OWS from input_string. 844 3. If header_type is "list", let output be the result of Parsing a 845 List from Text (Section 4.2.1). 847 4. If header_type is "dictionary", let output be the result of 848 Parsing a Dictionary from Text (Section 4.2.2). 850 5. If header_type is "item", let output be the result of Parsing an 851 Item from Text (Section 4.2.3). 853 6. Discard any leading OWS from input_string. 855 7. If input_string is not empty, fail parsing. 857 8. Otherwise, return output. 859 When generating input_bytes, parsers MUST combine all instances of 860 the target header field into one comma-separated field-value, as per 861 [RFC7230], Section 3.2.2; this assures that the header is processed 862 correctly. 864 For Lists and Dictionaries, this has the effect of correctly 865 concatenating all instances of the header field, as long as 866 individual individual members of the top-level data structure are not 867 split across multiple header instances. 869 Strings split across multiple header instances will have 870 unpredictable results, because comma(s) and whitespace inserted upon 871 combination will become part of the string output by the parser. 872 Since concatenation might be done by an upstream intermediary, the 873 results are not under the control of the serializer or the parser. 875 Tokens, Integers, Floats and Byte Sequences cannot be split across 876 multiple headers because the inserted commas will cause parsing to 877 fail. 879 If parsing fails - including when calling another algorithm - the 880 entire header field's value MUST be ignored (i.e., treated as if the 881 header field were not present in the message). This is intentionally 882 strict, to improve interoperability and safety, and specifications 883 referencing this document are not allowed to loosen this requirement. 885 Note that this requirement does not apply to an implementation that 886 is not parsing the header field; for example, an intermediary is not 887 required to strip a failing header field from a message before 888 forwarding it. 890 4.2.1. Parsing a List from Text 892 Given an ASCII string as input_string, return an array of (member, 893 parameters). input_string is modified to remove the parsed value. 895 1. Let members be an empty array. 897 2. While input_string is not empty: 899 1. Let member be the result of running Parsing a Parameterized 900 Member from Text (Section 4.2.1.1) with input_string. 902 2. Append member to members. 904 3. Discard any leading OWS from input_string. 906 4. If input_string is empty, return members. 908 5. Consume the first character of input_string; if it is not 909 COMMA, fail parsing. 911 6. Discard any leading OWS from input_string. 913 7. If input_string is empty, there is a trailing comma; fail 914 parsing. 916 3. No structured data has been found; return members (which is 917 empty). 919 4.2.1.1. Parsing a Parameterized Member from Text 921 Given an ASCII string as input_string, return a member (either a list 922 of items, or a single item) with an ordered map of parameters. 923 input_string is modified to remove the parsed value. 925 1. If the first character of input_string is "(", let member be the 926 result of running Parsing an Inner List (Section 4.2.1.2) with 927 input_string. 929 2. Else, let member be the result of running Parsing an Item 930 (Section 4.2.3) with input_string. 932 3. Let parameters be an empty, ordered map. 934 4. While input_string is not empty: 936 1. Discard any leading OWS from input_string. 938 2. If the first character of input_string is not ";", exit the 939 loop. 941 3. Consume a ";" character from the beginning of input_string. 943 4. Discard any leading OWS from input_string. 945 5. let param_name be the result of Parsing a key from Text 946 (Section 4.2.1.3) from input_string. 948 6. If param_name is already present in parameters, there is a 949 duplicate; fail parsing. 951 7. Let param_value be a null value. 953 8. If the first character of input_string is "=": 955 1. Consume the "=" character at the beginning of 956 input_string. 958 2. Let param_value be the result of Parsing an Item from 959 Text (Section 4.2.3) from input_string. 961 9. Append key param_name with value param_value to parameters. 963 5. Return the tuple (member, parameters). 965 4.2.1.2. Parsing an Inner List 967 Given an ASCII string as input_string, return an array of items. 968 input_string is modified to remove the parsed value. 970 1. Consume the first character of input_string; if it is not "(", 971 fail parsing. 973 2. Let inner_list be an empty array. 975 3. While input_string is not empty: 977 1. Discard any leading OWS from input_string. 979 2. If the first character of input_string is ")": 981 1. Consume the first character of input_string. 983 2. Return inner_list. 985 3. Let item be the result of running Parsing an Item from Text 986 (Section 4.2.3) with input_string. 988 4. Append item to inner_list. 990 5. If the first character of input_string is not SP or ")", fail 991 parsing. 993 4. The end of the inner list was not found; fail parsing. 995 4.2.1.3. Parsing a Key from Text 997 Given an ASCII string as input_string, return a key. input_string is 998 modified to remove the parsed value. 1000 1. If the first character of input_string is not lcalpha, fail 1001 parsing. 1003 2. Let output_string be an empty string. 1005 3. While input_string is not empty: 1007 1. If the first character of input_string is not one of lcalpha, 1008 DIGIT, "*", "_", or "-", return output_string. 1010 2. Let char be the result of removing the first character of 1011 input_string. 1013 3. Append char to output_string. 1015 4. Return output_string. 1017 4.2.2. Parsing a Dictionary from Text 1019 Given an ASCII string as input_string, return an ordered map of (key, 1020 item). input_string is modified to remove the parsed value. 1022 1. Let dictionary be an empty, ordered map. 1024 2. While input_string is not empty: 1026 1. Let this_key be the result of running Parsing a Key from 1027 Text (Section 4.2.1.3) with input_string. 1029 2. If dictionary already contains the name this_key, there is a 1030 duplicate; fail parsing. 1032 3. Consume the first character of input_string; if it is not 1033 "=", fail parsing. 1035 4. Let member be the result of running Parsing a Parameterized 1036 Member from Text (Section 4.2.1.1) with input_string. 1038 5. Add name this_key with value member to dictionary. 1040 6. Discard any leading OWS from input_string. 1042 7. If input_string is empty, return dictionary. 1044 8. Consume the first character of input_string; if it is not 1045 COMMA, fail parsing. 1047 9. Discard any leading OWS from input_string. 1049 10. If input_string is empty, there is a trailing comma; fail 1050 parsing. 1052 3. No structured data has been found; return dictionary (which is 1053 empty). 1055 4.2.3. Parsing an Item from Text 1057 Given an ASCII string as input_string, return an item. input_string 1058 is modified to remove the parsed value. 1060 1. If the first character of input_string is a "-" or a DIGIT, 1061 process input_string as a number (Section 4.2.4) and return the 1062 result. 1064 2. If the first character of input_string is a DQUOTE, process 1065 input_string as a string (Section 4.2.5) and return the result. 1067 3. If the first character of input_string is "*", process 1068 input_string as a byte sequence (Section 4.2.7) and return the 1069 result. 1071 4. If the first character of input_string is "?", process 1072 input_string as a Boolean (Section 4.2.8) and return the result. 1074 5. If the first character of input_string is an ALPHA, process 1075 input_string as a token (Section 4.2.6) and return the result. 1077 6. Otherwise, the item type is unrecognized; fail parsing. 1079 4.2.4. Parsing a Number from Text 1081 Given an ASCII string as input_string, return a number. input_string 1082 is modified to remove the parsed value. 1084 NOTE: This algorithm parses both Integers (Section 3.4) and Floats 1085 (Section 3.5), and returns the corresponding structure. 1087 1. Let type be "integer". 1089 2. Let sign be 1. 1091 3. Let input_number be an empty string. 1093 4. If the first character of input_string is "-", consume it and 1094 set sign to -1. 1096 5. If input_string is empty, there is an empty integer; fail 1097 parsing. 1099 6. If the first character of input_string is not a DIGIT, fail 1100 parsing. 1102 7. While input_string is not empty: 1104 1. Let char be the result of consuming the first character of 1105 input_string. 1107 2. If char is a DIGIT, append it to input_number. 1109 3. Else, if type is "integer" and char is ".", append char to 1110 input_number and set type to "float". 1112 4. Otherwise, prepend char to input_string, and exit the loop. 1114 5. If type is "integer" and input_number contains more than 15 1115 characters, fail parsing. 1117 6. If type is "float" and input_number contains more than 16 1118 characters, fail parsing. 1120 8. If type is "integer": 1122 1. Parse input_number as an integer and let output_number be 1123 the product of the result and sign. 1125 2. If output_number is outside the range defined in 1126 Section 3.4, fail parsing. 1128 9. Otherwise: 1130 1. If the final character of input_number is ".", fail parsing. 1132 2. If the number of characters after "." in input_number is 1133 greater than six, fail parsing. 1135 3. Parse input_number as a float and let output_number be the 1136 product of the result and sign. 1138 10. Return output_number. 1140 4.2.5. Parsing a String from Text 1142 Given an ASCII string as input_string, return an unquoted string. 1143 input_string is modified to remove the parsed value. 1145 1. Let output_string be an empty string. 1147 2. If the first character of input_string is not DQUOTE, fail 1148 parsing. 1150 3. Discard the first character of input_string. 1152 4. While input_string is not empty: 1154 1. Let char be the result of consuming the first character of 1155 input_string. 1157 2. If char is a backslash ("\"): 1159 1. If input_string is now empty, fail parsing. 1161 2. Let next_char be the result of consuming the first 1162 character of input_string. 1164 3. If next_char is not DQUOTE or "\", fail parsing. 1166 4. Append next_char to output_string. 1168 3. Else, if char is DQUOTE, return output_string. 1170 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not 1171 in VCHAR or SP), fail parsing. 1173 5. Else, append char to output_string. 1175 5. Reached the end of input_string without finding a closing DQUOTE; 1176 fail parsing. 1178 4.2.6. Parsing a Token from Text 1180 Given an ASCII string as input_string, return a token. input_string 1181 is modified to remove the parsed value. 1183 1. If the first character of input_string is not ALPHA, fail 1184 parsing. 1186 2. Let output_string be an empty string. 1188 3. While input_string is not empty: 1190 1. If the first character of input_string is not one of ALPHA, 1191 DIGIT, "_", "-", ".", ":", "%", "*" or "/", return 1192 output_string. 1194 2. Let char be the result of consuming the first character of 1195 input_string. 1197 3. Append char to output_string. 1199 4. Return output_string. 1201 4.2.7. Parsing a Byte Sequence from Text 1203 Given an ASCII string as input_string, return a byte sequence. 1204 input_string is modified to remove the parsed value. 1206 1. If the first character of input_string is not "*", fail parsing. 1208 2. Discard the first character of input_string. 1210 3. If there is not a "*" character before the end of input_string, 1211 fail parsing. 1213 4. Let b64_content be the result of consuming content of 1214 input_string up to but not including the first instance of the 1215 character "*". 1217 5. Consume the "*" character at the beginning of input_string. 1219 6. If b64_content contains a character not included in ALPHA, DIGIT, 1220 "+", "/" and "=", fail parsing. 1222 7. Let binary_content be the result of Base 64 Decoding [RFC4648] 1223 b64_content, synthesizing padding if necessary (note the 1224 requirements about recipient behaviour below). 1226 8. Return binary_content. 1228 Because some implementations of base64 do not allow reject of encoded 1229 data that is not properly "=" padded (see [RFC4648], Section 3.2), 1230 parsers SHOULD NOT fail when it is not present, unless they cannot be 1231 configured to do so. 1233 Because some implementations of base64 do not allow rejection of 1234 encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), 1235 parsers SHOULD NOT fail when it is present, unless they cannot be 1236 configured to do so. 1238 This specification does not relax the requirements in [RFC4648], 1239 Section 3.1 and 3.3; therefore, parsers MUST fail on characters 1240 outside the base64 alphabet, and on line feeds in encoded data. 1242 4.2.8. Parsing a Boolean from Text 1244 Given an ASCII string as input_string, return a Boolean. input_string 1245 is modified to remove the parsed value. 1247 1. If the first character of input_string is not "?", fail parsing. 1249 2. Discard the first character of input_string. 1251 3. If the first character of input_string matches "1", discard the 1252 first character, and return true. 1254 4. If the first character of input_string matches "0", discard the 1255 first character, and return false. 1257 5. No value has matched; fail parsing. 1259 5. IANA Considerations 1261 This draft has no actions for IANA. 1263 6. Security Considerations 1265 The size of most types defined by Structured Headers is not limited; 1266 as a result, extremely large header fields could be an attack vector 1267 (e.g., for resource consumption). Most HTTP implementations limit 1268 the sizes of individual header fields as well as the overall header 1269 block size to mitigate such attacks. 1271 It is possible for parties with the ability to inject new HTTP header 1272 fields to change the meaning of a Structured Header. In some 1273 circumstances, this will cause parsing to fail, but it is not 1274 possible to reliably fail in all such circumstances. 1276 7. References 1278 7.1. Normative References 1280 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1281 RFC 20, DOI 10.17487/RFC0020, October 1969, 1282 . 1284 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1285 Requirement Levels", BCP 14, RFC 2119, 1286 DOI 10.17487/RFC2119, March 1997, 1287 . 1289 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 1290 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 1291 . 1293 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 1294 Specifications: ABNF", STD 68, RFC 5234, 1295 DOI 10.17487/RFC5234, January 2008, 1296 . 1298 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1299 Protocol (HTTP/1.1): Message Syntax and Routing", 1300 RFC 7230, DOI 10.17487/RFC7230, June 2014, 1301 . 1303 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1304 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1305 May 2017, . 1307 7.2. Informative References 1309 [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 1310 IEEE 754-2008, DOI 10.1109/IEEESTD.2008.4610935, 1311 ISBN 978-0-7381-5752-8, August 2008, 1312 . 1314 See also http://grouper.ieee.org/groups/754/ [6]. 1316 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1317 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 1318 DOI 10.17487/RFC7231, June 2014, 1319 . 1321 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 1322 DOI 10.17487/RFC7493, March 2015, 1323 . 1325 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 1326 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 1327 DOI 10.17487/RFC7540, May 2015, 1328 . 1330 [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for 1331 HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, 1332 . 1334 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 1335 Interchange Format", STD 90, RFC 8259, 1336 DOI 10.17487/RFC8259, December 2017, 1337 . 1339 7.3. URIs 1341 [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ 1343 [2] https://httpwg.github.io/ 1345 [3] https://github.com/httpwg/http-extensions/labels/header-structure 1347 [4] https://github.com/httpwg/structured-header-tests 1349 [5] https://github.com/httpwg/wiki/wiki/Structured-Headers 1351 [6] https://github.com/httpwg/structured-header-tests 1353 Appendix A. Acknowledgements 1355 Many thanks to Matthew Kerwin for his detailed feedback and careful 1356 consideration during the development of this specification. 1358 Appendix B. Frequently Asked Questions 1360 B.1. Why not JSON? 1362 Earlier proposals for structured headers were based upon JSON 1363 [RFC8259]. However, constraining its use to make it suitable for 1364 HTTP header fields required senders and recipients to implement 1365 specific additional handling. 1367 For example, JSON has specification issues around large numbers and 1368 objects with duplicate members. Although advice for avoiding these 1369 issues is available (e.g., [RFC7493]), it cannot be relied upon. 1371 Likewise, JSON strings are by default Unicode strings, which have a 1372 number of potential interoperability issues (e.g., in comparison). 1373 Although implementers can be advised to avoid non-ASCII content where 1374 unnecessary, this is difficult to enforce. 1376 Another example is JSON's ability to nest content to arbitrary 1377 depths. Since the resulting memory commitment might be unsuitable 1378 (e.g., in embedded and other limited server deployments), it's 1379 necessary to limit it in some fashion; however, existing JSON 1380 implementations have no such limits, and even if a limit is 1381 specified, it's likely that some header field definition will find a 1382 need to violate it. 1384 Because of JSON's broad adoption and implementation, it is difficult 1385 to impose such additional constraints across all implementations; 1386 some deployments would fail to enforce them, thereby harming 1387 interoperability. In short, if it looks like JSON, people will be 1388 tempted to use a JSON parser / serialiser on header fields. 1390 Since a major goal for Structured Headers is to improve 1391 interoperability and simplify implementation, these concerns led to a 1392 format that requires a dedicated parser and serializer. 1394 Additionally, there were widely shared feelings that JSON doesn't 1395 "look right" in HTTP headers. 1397 B.2. Structured Headers don't "fit" my data. 1399 Structured headers intentionally limits the complexity of data 1400 structures, to assure that it can be processed in a performant manner 1401 with little overhead. This means that work is necessary to fit some 1402 data types into them. 1404 Sometimes, this can be achieved by creating limited substructures in 1405 values, and/or using more than one header. For example, consider: 1407 Example-Thing: name="Widget", cost=89.2, descriptions=(foo bar) 1408 Example-Description: foo; url="https://example.net"; context=123, 1409 bar; url="https://example.org"; context=456 1411 Since the description contains an array of key/value pairs, we use a 1412 List to represent them, with the token for each item in the array 1413 used to identify it in the "descriptions" member of the Example-Thing 1414 header. 1416 When specifying more than one header, it's important to remember to 1417 describe what a processor's behaviour should be when one of the 1418 headers is missing. 1420 If you need to fit arbitrarily complex data into a header, Structured 1421 Headers is probably a poor fit for your use case. 1423 Appendix C. Implementation Notes 1425 A generic implementation of this specification should expose the top- 1426 level parse (Section 4.2) and serialize (Section 4.1) functions. 1427 They need not be functions; for example, it could be implemented as 1428 an object, with methods for each of the different top-level types. 1430 For interoperability, it's important that generic implementations be 1431 complete and follow the algorithms closely; see Section 1.1. To aid 1432 this, a common test suite is being maintained by the community at 1433 https://github.com/httpwg/structured-header-tests [7]. 1435 Implementers should note that dictionaries and parameters are order- 1436 preserving maps. Some headers may not convey meaning in the ordering 1437 of these data types, but it should still be exposed so that 1438 applications which need to use it will have it available. 1440 Likewise, implementations should note that it's important to preserve 1441 the distinction between tokens and strings. While most programming 1442 languages have native types that map to the other types well, it may 1443 be necessary to create a wrapper "token" object or use a parameter on 1444 functions to assure that these types remain separate. 1446 Appendix D. Changes 1448 _RFC Editor: Please remove this section before publication._ 1450 D.1. Since draft-ietf-httpbis-header-structure-12 1452 o Editorial improvements. 1454 o Reworked float serialisation (#896). 1456 D.2. Since draft-ietf-httpbis-header-structure-11 1458 o Allow * in key (#844). 1460 o Constrain floats to six digits of precision (#848). 1462 o Allow dictionary members to have parameters (#842). 1464 D.3. Since draft-ietf-httpbis-header-structure-10 1466 o Update abstract (#799). 1468 o Input and output are now arrays of bytes (#662). 1470 o Implementations need to preserve difference between token and 1471 string (#790). 1473 o Allow empty dictionaries and lists (#781). 1475 o Change parameterized lists to have primary items (#797). 1477 o Allow inner lists in both dictionaries and lists; removes lists of 1478 lists (#816). 1480 o Subsume Parameterised Lists into Lists (#839). 1482 D.4. Since draft-ietf-httpbis-header-structure-09 1484 o Changed Boolean from T/F to 1/0 (#784). 1486 o Parameters are now ordered maps (#765). 1488 o Clamp integers to 15 digits (#737). 1490 D.5. Since draft-ietf-httpbis-header-structure-08 1492 o Disallow whitespace before items properly (#703). 1494 o Created "key" for use in dictionaries and parameters, rather than 1495 relying on identifier (#702). Identifiers have a separate minimum 1496 supported size. 1498 o Expanded the range of special characters allowed in identifier to 1499 include all of ALPHA, ".", ":", and "%" (#702). 1501 o Use "?" instead of "!" to indicate a Boolean (#719). 1503 o Added "Intentionally Strict Processing" (#684). 1505 o Gave better names for referring specs to use in Parameterised 1506 Lists (#720). 1508 o Added Lists of Lists (#721). 1510 o Rename Identifier to Token (#725). 1512 o Add implementation guidance (#727). 1514 D.6. Since draft-ietf-httpbis-header-structure-07 1516 o Make Dictionaries ordered mappings (#659). 1518 o Changed "binary content" to "byte sequence" to align with Infra 1519 specification (#671). 1521 o Changed "mapping" to "map" for #671. 1523 o Don't fail if byte sequences aren't "=" padded (#658). 1525 o Add Booleans (#683). 1527 o Allow identifiers in items again (#629). 1529 o Disallowed whitespace before items (#703). 1531 o Explain the consequences of splitting a string across multiple 1532 headers (#686). 1534 D.7. Since draft-ietf-httpbis-header-structure-06 1536 o Add a FAQ. 1538 o Allow non-zero pad bits. 1540 o Explicitly check for integers that violate constraints. 1542 D.8. Since draft-ietf-httpbis-header-structure-05 1544 o Reorganise specification to separate parsing out. 1546 o Allow referencing specs to use ABNF. 1548 o Define serialisation algorithms. 1550 o Refine relationship between ABNF, parsing and serialisation 1551 algorithms. 1553 D.9. Since draft-ietf-httpbis-header-structure-04 1555 o Remove identifiers from item. 1557 o Remove most limits on sizes. 1559 o Refine number parsing. 1561 D.10. Since draft-ietf-httpbis-header-structure-03 1563 o Strengthen language around failure handling. 1565 D.11. Since draft-ietf-httpbis-header-structure-02 1567 o Split Numbers into Integers and Floats. 1569 o Define number parsing. 1571 o Tighten up binary parsing and give it an explicit end delimiter. 1573 o Clarify that mappings are unordered. 1575 o Allow zero-length strings. 1577 o Improve string parsing algorithm. 1579 o Improve limits in algorithms. 1581 o Require parsers to combine header fields before processing. 1583 o Throw an error on trailing garbage. 1585 D.12. Since draft-ietf-httpbis-header-structure-01 1587 o Replaced with draft-nottingham-structured-headers. 1589 D.13. Since draft-ietf-httpbis-header-structure-00 1591 o Added signed 64bit integer type. 1593 o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- 1594 unicode-string. 1596 o Change h1_blob delimiter to ":" since "'" is valid t_char 1598 Authors' Addresses 1600 Mark Nottingham 1601 Fastly 1603 Email: mnot@mnot.net 1604 URI: https://www.mnot.net/ 1605 Poul-Henning Kamp 1606 The Varnish Cache Project 1608 Email: phk@varnish-cache.org