idnits 2.17.00 (12 Aug 2021) /tmp/idnits10281/draft-ietf-httpbis-header-structure-11.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** There is 1 instance of too long lines in the document, the longest one being 1 character in excess of 72. ** The abstract seems to contain references ([2], [3], [4], [5], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (July 8, 2019) is 1047 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 1292 -- Looks like a reference, but probably isn't: '2' on line 1294 -- Looks like a reference, but probably isn't: '3' on line 1296 -- Looks like a reference, but probably isn't: '4' on line 1298 -- Looks like a reference, but probably isn't: '5' on line 1300 == Missing Reference: 'RFCxxxx' is mentioned on line 253, but not defined == Missing Reference: 'RFC3986' is mentioned on line 266, but not defined -- Looks like a reference, but probably isn't: '6' on line 1302 -- Looks like a reference, but probably isn't: '7' on line 1384 Summary: 2 errors (**), 0 flaws (~~), 3 warnings (==), 8 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: January 9, 2020 The Varnish Cache Project 6 July 8, 2019 8 Structured Headers for HTTP 9 draft-ietf-httpbis-header-structure-11 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 January 9, 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 . . . . . . . . . . . . . . . . . . . . . . . . . . 6 78 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 7 79 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 8 80 3.4. Integers . . . . . . . . . . . . . . . . . . . . . . . . 8 81 3.5. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 9 82 3.6. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 9 83 3.7. Tokens . . . . . . . . . . . . . . . . . . . . . . . . . 10 84 3.8. Byte Sequences . . . . . . . . . . . . . . . . . . . . . 10 85 3.9. Booleans . . . . . . . . . . . . . . . . . . . . . . . . 11 86 4. Working With Structured Headers in Textual HTTP Headers . . . 11 87 4.1. Serializing Structured Headers . . . . . . . . . . . . . 11 88 4.2. Parsing Header Fields into Structured Headers . . . . . . 17 89 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 26 90 6. Security Considerations . . . . . . . . . . . . . . . . . . . 26 91 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 26 92 7.1. Normative References . . . . . . . . . . . . . . . . . . 26 93 7.2. Informative References . . . . . . . . . . . . . . . . . 27 94 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28 95 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 28 96 Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 28 97 B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 28 98 B.2. Structured Headers don't "fit" my data. . . . . . . . . . 29 99 Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 29 100 Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 30 101 D.1. Since draft-ietf-httpbis-header-structure-10 . . . . . . 30 102 D.2. Since draft-ietf-httpbis-header-structure-09 . . . . . . 30 103 D.3. Since draft-ietf-httpbis-header-structure-08 . . . . . . 31 104 D.4. Since draft-ietf-httpbis-header-structure-07 . . . . . . 31 105 D.5. Since draft-ietf-httpbis-header-structure-06 . . . . . . 32 106 D.6. Since draft-ietf-httpbis-header-structure-05 . . . . . . 32 107 D.7. Since draft-ietf-httpbis-header-structure-04 . . . . . . 32 108 D.8. Since draft-ietf-httpbis-header-structure-03 . . . . . . 32 109 D.9. Since draft-ietf-httpbis-header-structure-02 . . . . . . 32 110 D.10. Since draft-ietf-httpbis-header-structure-01 . . . . . . 33 111 D.11. Since draft-ietf-httpbis-header-structure-00 . . . . . . 33 112 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 33 114 1. Introduction 116 Specifying the syntax of new HTTP header fields is an onerous task; 117 even with the guidance in [RFC7231], Section 8.3.1, there are many 118 decisions - and pitfalls - for a prospective HTTP header field 119 author. 121 Once a header field is defined, bespoke parsers and serializers often 122 need to be written, because each header has slightly different 123 handling of what looks like common syntax. 125 This document introduces a set of common data structures for use in 126 definitions of new HTTP header field values to address these 127 problems. In particular, it defines a generic, abstract model for 128 header field values, along with a concrete serialisation for 129 expressing that model in textual HTTP [RFC7230] header fields. 131 HTTP headers that are defined as "Structured Headers" use the types 132 defined in this specification to define their syntax and basic 133 handling rules, thereby simplifying both their definition by 134 specification writers and handling by implementations. 136 Additionally, future versions of HTTP can define alternative 137 serialisations of the abstract model of these structures, allowing 138 headers that use it to be transmitted more efficiently without being 139 redefined. 141 Note that it is not a goal of this document to redefine the syntax of 142 existing HTTP headers; the mechanisms described herein are only 143 intended to be used with headers that explicitly opt into them. 145 Section 2 describes how to specify a Structured Header. 147 Section 3 defines a number of abstract data types that can be used in 148 Structured Headers. Those abstract types can be serialized into and 149 parsed from textual HTTP headers using the algorithms described in 150 Section 4. 152 1.1. Intentionally Strict Processing 154 This specification intentionally defines strict parsing and 155 serialisation behaviours using step-by-step algorithms; the only 156 error handling defined is to fail the operation altogether. 158 It is designed to encourage faithful implementation and therefore 159 good interoperability. Therefore, an implementation that tried to be 160 "helpful" by being more tolerant of input would make interoperability 161 worse, since that would create pressure on other implementations to 162 implement similar (but likely subtly different) workarounds. 164 In other words, strict processing is an intentional feature of this 165 specification; it allows non-conformant input to be discovered and 166 corrected by the producer early, and avoids both interoperability and 167 security issues that might otherwise result. 169 Note that as a result of this strictness, if a header field is 170 appended to by multiple parties (e.g., intermediaries, or different 171 components in the sender), an error in one party's value is likely to 172 cause the entire header field to fail parsing. 174 1.2. Notational Conventions 176 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 177 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 178 "OPTIONAL" in this document are to be interpreted as described in BCP 179 14 [RFC2119] [RFC8174] when, and only when, they appear in all 180 capitals, as shown here. 182 This document uses algorithms to specify parsing and serialisation 183 behaviours, and the Augmented Backus-Naur Form (ABNF) notation of 184 [RFC5234] to illustrate expected syntax in textual HTTP header 185 fields. In doing so, uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE 186 rules from [RFC5234]. It also includes the OWS rule from [RFC7230]. 188 When parsing from textual HTTP header fields, implementations MUST 189 follow the algorithms, but MAY vary in implementation so as the 190 behaviours are indistinguishable from specified behaviour. If there 191 is disagreement between the parsing algorithms and ABNF, the 192 specified algorithms take precedence. In some places, the algorithms 193 are "greedy" with whitespace, but this should not affect conformance. 195 For serialisation to textual header fields, the ABNF illustrates the 196 range of acceptable wire representations with as much fidelity as 197 possible, and the algorithms define the recommended way to produce 198 them. Implementations MAY vary from the specified behaviour so long 199 as the output still matches the ABNF. 201 2. Defining New Structured Headers 203 To define a HTTP header as a structured header, its specification 204 needs to: 206 o Reference this specification. Recipients and generators of the 207 header need to know that the requirements of this document are in 208 effect. 210 o Specify the header field's allowed syntax for values, in terms of 211 the types described in Section 3, along with their associated 212 semantics. Syntax definitions are encouraged to use the ABNF 213 rules beginning with "sh-" defined in this specification. 215 o Specify any additional constraints upon the syntax of the 216 structured used, as well as the consequences when those 217 constraints are violated. When Structured Headers parsing fails, 218 the header is discarded (see Section 4.2); in most situations, 219 header-specific constraints should do likewise. 221 Note that a header field definition cannot relax the requirements of 222 this specification because doing so would preclude handling by 223 generic software; they can only add additional constraints (for 224 example, on the numeric range of integers and floats, the format of 225 strings and tokens, or the number of items in a list). Likewise, 226 header field definitions should use Structured Headers for the entire 227 header field value, not a portion thereof. 229 This specification defines minimums for the length or number of 230 various structures supported by Structured Headers implementations. 231 It does not specify maximum sizes in most cases, but header authors 232 should be aware that HTTP implementations do impose various limits on 233 the size of individual header fields, the total number of fields, 234 and/or the size of the entire header block. 236 For example, 237 42. Foo-Example Header 239 The Foo-Example HTTP header field conveys information about how 240 much Foo the message has. 242 Foo-Example is a Structured Header [RFCxxxx]. Its value MUST be a 243 dictionary ([RFCxxxx], Section Y.Y). Its ABNF is: 245 Foo-Example = sh-dictionary 247 The dictionary MUST contain: 249 * Exactly one member whose name is "foo", and whose value is an 250 integer ([RFCxxxx], Section Y.Y), indicating the number of foos 251 in the message. 252 * Exactly one member whose name is "barUrl", and whose value is a 253 string ([RFCxxxx], Section Y.Y), conveying the Bar URL for the 254 message. See below for processing requirements. 256 If the parsed header field does not contain both, it MUST be 257 ignored. 259 "foo" MUST be between 0 and 10, inclusive; other values MUST cause 260 the header to be ignored. 262 "barUrl" contains a URI-reference ([RFC3986], Section 4.1). 264 If barURL is not a valid URI-reference, it MUST be ignored. 265 If barURL is a relative reference ([RFC3986], Section 4.2), 266 it MUST be resolved ([RFC3986], Section 5) before being used. 268 3. Structured Header Data Types 270 This section defines the abstract value types that can be composed 271 into Structured Headers. The ABNF provided represents the on-wire 272 format in HTTP. 274 3.1. Lists 276 Lists are arrays of zero or more members, each of which can be an 277 item (Section 3.3) or an inner list (an array of zero or more items). 279 Each member of the top-level list can also have associated parameters 280 - an ordered map of key-value pairs where the keys are short, textual 281 strings and the values are items (Section 3.3). There can be zero or 282 more parameters on a member, and their keys are required to be unique 283 within that scope. 285 The ABNF for lists is: 287 sh-list = list-member *( OWS "," OWS list-member ) 288 list-member = ( sh-item / inner-list ) *parameter 289 inner-list = "(" OWS [ sh-item *( SP sh-item ) OWS ] ")" 290 parameter = OWS ";" OWS param-name [ "=" param-value ] 291 param-name = key 292 key = lcalpha *( lcalpha / DIGIT / "_" / "-" ) 293 lcalpha = %x61-7A ; a-z 294 param-value = sh-item 296 In textual HTTP headers, each member is separated by a comma and 297 optional whitespace. For example, a header field whose value is 298 defined as a list of strings could look like: 300 Example-StrListHeader: "foo", "bar", "It was the best of times." 302 In textual HTTP headers, inner lists are denoted by surrounding 303 parenthesis, and have their values delimited by a single space. A 304 header field whose value is defined as a list of lists of strings 305 could look like: 307 Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () 309 Note that the last member in this example is an empty inner list. 311 In textual HTTP headers, members' parameters are separated from the 312 member and each other by semicolons. For example: 314 Example-ParamListHeader: abc_123;a=1;b=2; cdef_456, (ghi jkl);q="9";r="w" 316 Parsers MUST support lists containing at least 1024 members, support 317 members with at least 256 parameters, support inner-lists containing 318 at least 256 members, and support parameter keys with at least 64 319 characters. 321 Header specifications can constrain the types of individual list 322 values (including that of individual inner-list members and 323 parameters) if necessary. 325 3.2. Dictionaries 327 Dictionaries are ordered maps of name-value pairs, where the names 328 are short, textual strings and the values are items (Section 3.3) or 329 arrays of items. There can be zero or more members, and their names 330 are required to be unique within the scope of the dictionary they 331 occur within. 333 Implementations MUST provide access to dictionaries both by index and 334 by name. Specifications MAY use either means of accessing the 335 members. 337 The ABNF for dictionaries in textual HTTP headers is: 339 sh-dictionary = dict-member *( OWS "," OWS dict-member ) 340 dict-member = member-name "=" member-value 341 member-name = key 342 member-value = sh-item / inner-list 344 In textual HTTP headers, members are separated by a comma with 345 optional whitespace, while names and values are separated by "=" 346 (without whitespace). For example: 348 Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=* 350 A dictionary with a member whose value is an inner-list of tokens: 352 Example-DictListHeader: rating=1.5, feelings=(joy sadness) 354 Typically, a header field specification will define the semantics of 355 individual member names, as well as whether their presence is 356 required or optional. Recipients MUST ignore names that are 357 undefined or unknown, unless the header field's specification 358 specifically disallows them. 360 Parsers MUST support dictionaries containing at least 1024 name/value 361 pairs, and names with at least 64 characters. 363 3.3. Items 365 An item is can be a integer (Section 3.4), float (Section 3.5), 366 string (Section 3.6), token (Section 3.7), byte sequence 367 (Section 3.8), or Boolean (Section 3.9). 369 The ABNF for items in textual HTTP headers is: 371 sh-item = sh-integer / sh-float / sh-string / sh-token / sh-binary 372 / sh-boolean 374 3.4. Integers 376 Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 377 inclusive (i.e., up to fifteen digits, signed), for IEEE 754 378 compatibility ([IEEE754]). 380 The ABNF for integers in textual HTTP headers is: 382 sh-integer = ["-"] 1*15DIGIT 384 For example: 386 Example-IntegerHeader: 42 388 Note that commas in integers are used in this section's prose only 389 for readability; they are not valid in the wire format. 391 3.5. Floats 393 Floats are integers with a fractional part, that can be stored as 394 IEEE 754 double precision numbers (binary64) ([IEEE754]). 396 The ABNF for floats in textual HTTP headers is: 398 sh-float = ["-"] ( 399 DIGIT "." 1*14DIGIT / 400 2DIGIT "." 1*13DIGIT / 401 3DIGIT "." 1*12DIGIT / 402 4DIGIT "." 1*11DIGIT / 403 5DIGIT "." 1*10DIGIT / 404 6DIGIT "." 1*9DIGIT / 405 7DIGIT "." 1*8DIGIT / 406 8DIGIT "." 1*7DIGIT / 407 9DIGIT "." 1*6DIGIT / 408 10DIGIT "." 1*5DIGIT / 409 11DIGIT "." 1*4DIGIT / 410 12DIGIT "." 1*3DIGIT / 411 13DIGIT "." 1*2DIGIT / 412 14DIGIT "." 1DIGIT ) 414 For example, a header whose value is defined as a float could look 415 like: 417 Example-FloatHeader: 4.5 419 3.6. Strings 421 Strings are zero or more printable ASCII [RFC0020] characters (i.e., 422 the range 0x20 to 0x7E). Note that this excludes tabs, newlines, 423 carriage returns, etc. 425 The ABNF for strings in textual HTTP headers is: 427 sh-string = DQUOTE *(chr) DQUOTE 428 chr = unescaped / escaped 429 unescaped = %x20-21 / %x23-5B / %x5D-7E 430 escaped = "\" ( DQUOTE / "\" ) 432 In textual HTTP headers, strings are delimited with double quotes, 433 using a backslash ("\") to escape double quotes and backslashes. For 434 example: 436 Example-StringHeader: "hello world" 438 Note that strings only use DQUOTE as a delimiter; single quotes do 439 not delimit strings. Furthermore, only DQUOTE and "\" can be 440 escaped; other sequences MUST cause parsing to fail. 442 Unicode is not directly supported in this document, because it causes 443 a number of interoperability issues, and - with few exceptions - 444 header values do not require it. 446 When it is necessary for a field value to convey non-ASCII string 447 content, a byte sequence (Section 3.8) SHOULD be specified, along 448 with a character encoding (preferably UTF-8). 450 Parsers MUST support strings with at least 1024 characters. 452 3.7. Tokens 454 Tokens are short textual words; their abstract model is identical to 455 their expression in the textual HTTP serialisation. 457 The ABNF for tokens in textual HTTP headers is: 459 sh-token = ALPHA 460 *( ALPHA / DIGIT / "_" / "-" / "." / ":" / "%" 461 / "*" / "/" ) 463 Parsers MUST support tokens with at least 512 characters. 465 Note that a Structured Header token is not the same as the "token" 466 ABNF rule defined in [RFC7230]. 468 3.8. Byte Sequences 470 Byte sequences can be conveyed in Structured Headers. 472 The ABNF for a byte sequence in textual HTTP headers is: 474 sh-binary = "*" *(base64) "*" 475 base64 = ALPHA / DIGIT / "+" / "/" / "=" 477 In textual HTTP headers, a byte sequence is delimited with asterisks 478 and encoded using base64 ([RFC4648], Section 4). For example: 480 Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==* 482 Parsers MUST support byte sequences with at least 16384 octets after 483 decoding. 485 3.9. Booleans 487 Boolean values can be conveyed in Structured Headers. 489 The ABNF for a Boolean in textual HTTP headers is: 491 sh-boolean = "?" boolean 492 boolean = "0" / "1" 494 In textual HTTP headers, a boolean is indicated with a leading "?" 495 character. For example: 497 Example-BoolHdr: ?1 499 4. Working With Structured Headers in Textual HTTP Headers 501 This section defines how to serialize and parse Structured Headers in 502 textual header fields, and protocols compatible with them (e.g., in 503 HTTP/2 [RFC7540] before HPACK [RFC7541] is applied). 505 4.1. Serializing Structured Headers 507 Given a structure defined in this specification: 509 1. If the structure is a dictionary or list and its value is empty 510 (i.e., it has no members), do not send the serialize field at all 511 (i.e., omit both the field-name and field-value). 513 2. If the structure is a dictionary, let output_string be the result 514 of Serializing a Dictionary (Section 4.1.2). 516 3. Else if the structure is a list, let output_string be the result 517 of Serializing a List Section 4.1.1. 519 4. Else if the structure is an item, let output_string be the result 520 of Serializing an Item (Section 4.1.3). 522 5. Else, fail serialisation. 524 6. Return output_string converted into an array of bytes, using 525 ASCII encoding [RFC0020]. 527 4.1.1. Serializing a List 529 Given a list of (member, parameters) as input_list: 531 1. Let output be an empty string. 533 2. For each (member, parameters) of input_list: 535 1. If member is an array, let mem_value be the result of 536 applying Serialising an Inner List (Section 4.1.1.1) to 537 member. 539 2. Otherwise, let mem_value be the result of applying 540 Serializing an Item (Section 4.1.3) to member. 542 3. Append mem_value to output. 544 4. For each parameter in parameters: 546 1. Append ";" to output. 548 2. Let name be the result of applying Serializing a Key 549 (Section 4.1.1.2) to parameter's param-name. 551 3. Append name to output. 553 4. If parameter has a param-value: 555 1. Let value be the result of applying Serializing an 556 Item (Section 4.1.3) to parameter's param-value. 558 2. Append "=" to output. 560 3. Append value to output. 562 5. If more members remain in input_plist: 564 1. Append a COMMA to output. 566 2. Append a single WS to output. 568 3. Return output. 570 4.1.1.1. Serialising an Inner List 572 Given an array inner_list: 574 1. Let output be the string "(". 576 2. For each member mem of inner_list: 578 1. Let value be the result of applying Serializing an Item 579 (Section 4.1.3) to mem. 581 2. Append value to output. 583 3. If inner_list is not empty, append a single WS to output. 585 3. Append ")" to output. 587 4. Return output. 589 4.1.1.2. Serializing a Key 591 Given a key as input_key: 593 1. If input_key is not a sequence of characters, or contains 594 characters not allowed in the ABNF for key, fail serialisation. 596 2. Let output be an empty string. 598 3. Append input_key to output. 600 4. Return output. 602 4.1.2. Serializing a Dictionary 604 Given a dictionary as input_dictionary: 606 1. Let output be an empty string. 608 2. For each member mem of input_dictionary: 610 1. Let name be the result of applying Serializing a Key 611 (Section 4.1.1.2) to mem's member-name. 613 2. Append name to output. 615 3. Append "=" to output. 617 4. If mem is an array, let value be the result of applying 618 Serialising an Inner List (Section 4.1.1.1) to mem. 620 5. Otherwise, let value be the result of applying Serializing an 621 Item (Section 4.1.3) to mem. 623 6. Append value to output. 625 7. If more members remain in input_dictionary: 627 1. Append a COMMA to output. 629 2. Append a single WS to output. 631 3. Return output. 633 4.1.3. Serializing an Item 635 Given an item as input_item: 637 1. If input_item is an integer, return the result of applying 638 Serializing an Integer (Section 4.1.4) to input_item. 640 2. If input_item is a float, return the result of applying 641 Serializing a Float (Section 4.1.5) to input_item. 643 3. If input_item is a string, return the result of applying 644 Serializing a String (Section 4.1.6) to input_item. 646 4. If input_item is a token, return the result of Serializing a 647 Token (Section 4.1.7) to input_item. 649 5. If input_item is a Boolean, return the result of applying 650 Serializing a Boolean (Section 4.1.9) to input_item. 652 6. If input_item is a byte sequence, return the result of applying 653 Serializing a Byte Sequence (Section 4.1.8) to input_item. 655 7. Otherwise, fail serialisation. 657 4.1.4. Serializing an Integer 659 Given an integer as input_integer: 661 1. If input_integer is not an integer in the range of 662 -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail 663 serialisation. 665 2. Let output be an empty string. 667 3. If input_integer is less than (but not equal to) 0, append "-" to 668 output. 670 4. Append input_integer's numeric value represented in base 10 using 671 only decimal digits to output. 673 5. Return output. 675 4.1.5. Serializing a Float 677 Given a float as input_float: 679 1. If input_float is not a IEEE 754 double precision number, fail 680 serialisation. 682 2. Let output be an empty string. 684 3. If input_float is less than (but not equal to) 0, append "-" to 685 output. 687 4. Append input_float's integer component represented in base 10 688 using only decimal digits to output; if it is zero, append "0". 690 5. Append "." to output. 692 6. Append input_float's decimal component represented in base 10 693 using only decimal digits to output; if it is zero, append "0". 695 7. Return output. 697 4.1.6. Serializing a String 699 Given a string as input_string: 701 1. If input_string is not a sequence of characters, or contains 702 characters outside the range allowed by VCHAR or SP, fail 703 serialisation. 705 2. Let output be an empty string. 707 3. Append DQUOTE to output. 709 4. For each character char in input_string: 711 1. If char is "\" or DQUOTE: 713 1. Append "\" to output. 715 2. Append char to output. 717 5. Append DQUOTE to output. 719 6. Return output. 721 4.1.7. Serializing a Token 723 Given a token as input_token: 725 1. If input_token is not a sequence of characters, or contains 726 characters not allowed in Section 3.7}, fail serialisation. 728 2. Let output be an empty string. 730 3. Append input_token to output. 732 4. Return output. 734 4.1.8. Serializing a Byte Sequence 736 Given a byte sequence as input_bytes: 738 1. If input_bytes is not a sequence of bytes, fail serialisation. 740 2. Let output be an empty string. 742 3. Append "*" to output. 744 4. Append the result of base64-encoding input_bytes as per 745 [RFC4648], Section 4, taking account of the requirements below. 747 5. Append "*" to output. 749 6. Return output. 751 The encoded data is required to be padded with "=", as per [RFC4648], 752 Section 3.2. 754 Likewise, encoded data SHOULD have pad bits set to zero, as per 755 [RFC4648], Section 3.5, unless it is not possible to do so due to 756 implementation constraints. 758 4.1.9. Serializing a Boolean 760 Given a Boolean as input_boolean: 762 1. If input_boolean is not a boolean, fail serialisation. 764 2. Let output be an empty string. 766 3. Append "?" to output. 768 4. If input_boolean is true, append "1" to output. 770 5. If input_boolean is false, append "0" to output. 772 6. Return output. 774 4.2. Parsing Header Fields into Structured Headers 776 When a receiving implementation parses textual HTTP header fields 777 that are known to be Structured Headers, it is important that care be 778 taken, as there are a number of edge cases that can cause 779 interoperability or even security problems. This section specifies 780 the algorithm for doing so. 782 Given an array of bytes input_bytes that represents the chosen 783 header's field-value (which is an empty string if that header is not 784 present), and header_type (one of "dictionary", "list", or "item"), 785 return the parsed header value. 787 1. Convert input_bytes into an ASCII string input_string; if 788 conversion fails, fail parsing. 790 2. Discard any leading OWS from input_string. 792 3. If header_type is "list", let output be the result of Parsing a 793 List from Text (Section 4.2.1). 795 4. If header_type is "dictionary", let output be the result of 796 Parsing a Dictionary from Text (Section 4.2.2). 798 5. If header_type is "item", let output be the result of Parsing an 799 Item from Text (Section 4.2.4). 801 6. Discard any leading OWS from input_string. 803 7. If input_string is not empty, fail parsing. 805 8. Otherwise, return output. 807 When generating input_bytes, parsers MUST combine all instances of 808 the target header field into one comma-separated field-value, as per 809 [RFC7230], Section 3.2.2; this assures that the header is processed 810 correctly. 812 For Lists and Dictionaries, this has the effect of correctly 813 concatenating all instances of the header field, as long as 814 individual individual members of the top-level data structure are not 815 split across multiple header instances. 817 Strings split across multiple header instances will have 818 unpredictable results, because comma(s) and whitespace inserted upon 819 combination will become part of the string output by the parser. 820 Since concatenation might be done by an upstream intermediary, the 821 results are not under the control of the serializer or the parser. 823 Tokens, Integers, Floats and Byte Sequences cannot be split across 824 multiple headers because the inserted commas will cause parsing to 825 fail. 827 If parsing fails - including when calling another algorithm - the 828 entire header field's value MUST be discarded. This is intentionally 829 strict, to improve interoperability and safety, and specifications 830 referencing this document are not allowed to loosen this requirement. 832 4.2.1. Parsing a List from Text 834 Given an ASCII string input_string, return an array of (member, 835 parameters). input_string is modified to remove the parsed value. 837 1. Let members be an empty array. 839 2. While input_string is not empty: 841 1. Let member be the result of running Parsing a Parameterized 842 Member from Text (Section 4.2.1.1) with input_string. 844 2. Append member to members. 846 3. Discard any leading OWS from input_string. 848 4. If input_string is empty, return members. 850 5. Consume the first character of input_string; if it is not 851 COMMA, fail parsing. 853 6. Discard any leading OWS from input_string. 855 7. If input_string is empty, there is a trailing comma; fail 856 parsing. 858 3. No structured data has been found; return members (which is 859 empty). 861 4.2.1.1. Parsing a Parameterized Member from Text 863 Given an ASCII string input_string, return an token with an ordered 864 map of parameters. input_string is modified to remove the parsed 865 value. 867 1. If the first character of input_string is "(", let member be the 868 result of running Parsing an Inner List (Section 4.2.1.2) with 869 input_string. 871 2. Else, let member be the result of running Parsing an Item 872 (Section 4.2.4) with input_string. 874 3. Let parameters be an empty, ordered map. 876 4. In a loop: 878 1. Discard any leading OWS from input_string. 880 2. If the first character of input_string is not ";", exit the 881 loop. 883 3. Consume a ";" character from the beginning of input_string. 885 4. Discard any leading OWS from input_string. 887 5. let param_name be the result of Parsing a key from Text 888 (Section 4.2.3) from input_string. 890 6. If param_name is already present in parameters, there is a 891 duplicate; fail parsing. 893 7. Let param_value be a null value. 895 8. If the first character of input_string is "=": 897 1. Consume the "=" character at the beginning of 898 input_string. 900 2. Let param_value be the result of Parsing an Item from 901 Text (Section 4.2.4) from input_string. 903 9. Append key param_name with value param_value to parameters. 905 5. Return the tuple (member, parameters). 907 4.2.1.2. Parsing an Inner List 909 Given an ASCII string input_string, return an array of items. 910 input_string is modified to remove the parsed value. 912 1. Consume the first character of input_string; if it is not "(", 913 fail parsing. 915 2. Let inner_list be an empty array. 917 3. While input_string is not empty: 919 1. Discard any leading OWS from input_string. 921 2. If the first character of input_string is ")": 923 1. Consume the first character of input_string. 925 2. Return inner_list. 927 3. Let item be the result of running Parsing an Item from Text 928 (Section 4.2.4) with input_string. 930 4. Append item to inner_list. 932 5. If the first character of input_string is not SP or ")", fail 933 parsing. 935 4. The end of the inner list was not found; fail parsing. 937 4.2.2. Parsing a Dictionary from Text 939 Given an ASCII string input_string, return an ordered map of (key, 940 item). input_string is modified to remove the parsed value. 942 1. Let dictionary be an empty, ordered map. 944 2. While input_string is not empty: 946 1. Let this_key be the result of running Parsing a Key from 947 Text (Section 4.2.3) with input_string. 949 2. If dictionary already contains the name this_key, there is a 950 duplicate; fail parsing. 952 3. Consume the first character of input_string; if it is not 953 "=", fail parsing. 955 4. If the first character of input_string is "(", let 956 this_value be the result of running Parsing an Inner List 957 (Section 4.2.1.2) with input_string. 959 5. Else, let this_value be the result of running Parsing an 960 Item (Section 4.2.4) with input_string. 962 6. Add name this_key with value this_value to dictionary. 964 7. Discard any leading OWS from input_string. 966 8. If input_string is empty, return dictionary. 968 9. Consume the first character of input_string; if it is not 969 COMMA, fail parsing. 971 10. Discard any leading OWS from input_string. 973 11. If input_string is empty, there is a trailing comma; fail 974 parsing. 976 3. No structured data has been found; return dictionary (which is 977 empty). 979 4.2.3. Parsing a Key from Text 981 Given an ASCII string input_string, return a key. input_string is 982 modified to remove the parsed value. 984 1. If the first character of input_string is not lcalpha, fail 985 parsing. 987 2. Let output_string be an empty string. 989 3. While input_string is not empty: 991 1. Let char be the result of removing the first character of 992 input_string. 994 2. If char is not one of lcalpha, DIGIT, "_", or "-": 996 1. Prepend char to input_string. 998 2. Return output_string. 1000 3. Append char to output_string. 1002 4. Return output_string. 1004 4.2.4. Parsing an Item from Text 1006 Given an ASCII string input_string, return an item. input_string is 1007 modified to remove the parsed value. 1009 1. If the first character of input_string is a "-" or a DIGIT, 1010 process input_string as a number (Section 4.2.5) and return the 1011 result. 1013 2. If the first character of input_string is a DQUOTE, process 1014 input_string as a string (Section 4.2.6) and return the result. 1016 3. If the first character of input_string is "*", process 1017 input_string as a byte sequence (Section 4.2.8) and return the 1018 result. 1020 4. If the first character of input_string is "?", process 1021 input_string as a Boolean (Section 4.2.9) and return the result. 1023 5. If the first character of input_string is an ALPHA, process 1024 input_string as a token (Section 4.2.7) and return the result. 1026 6. Otherwise, the item type is unrecognized; fail parsing. 1028 4.2.5. Parsing a Number from Text 1030 Given an ASCII string input_string, return a number. input_string is 1031 modified to remove the parsed value. 1033 NOTE: This algorithm parses both Integers Section 3.4 and Floats 1034 Section 3.5, and returns the corresponding structure. 1036 1. Let type be "integer". 1038 2. Let sign be 1. 1040 3. Let input_number be an empty string. 1042 4. If the first character of input_string is "-", consume it and 1043 set sign to -1. 1045 5. If input_string is empty, there is an empty integer; fail 1046 parsing. 1048 6. If the first character of input_string is not a DIGIT, fail 1049 parsing. 1051 7. While input_string is not empty: 1053 1. Let char be the result of consuming the first character of 1054 input_string. 1056 2. If char is a DIGIT, append it to input_number. 1058 3. Else, if type is "integer" and char is ".", append char to 1059 input_number and set type to "float". 1061 4. Otherwise, prepend char to input_string, and exit the loop. 1063 5. If type is "integer" and input_number contains more than 15 1064 characters, fail parsing. 1066 6. If type is "float" and input_number contains more than 16 1067 characters, fail parsing. 1069 8. If type is "integer": 1071 1. Parse input_number as an integer and let output_number be 1072 the product of the result and sign. 1074 2. If output_number is outside the range defined in 1075 Section 3.4, fail parsing. 1077 9. Otherwise: 1079 1. If the final character of input_number is ".", fail parsing. 1081 2. Parse input_number as a float and let output_number be the 1082 product of the result and sign. 1084 10. Return output_number. 1086 4.2.6. Parsing a String from Text 1088 Given an ASCII string input_string, return an unquoted string. 1089 input_string is modified to remove the parsed value. 1091 1. Let output_string be an empty string. 1093 2. If the first character of input_string is not DQUOTE, fail 1094 parsing. 1096 3. Discard the first character of input_string. 1098 4. While input_string is not empty: 1100 1. Let char be the result of consuming the first character of 1101 input_string. 1103 2. If char is a backslash ("\"): 1105 1. If input_string is now empty, fail parsing. 1107 2. Else: 1109 1. Let next_char be the result of consuming the first 1110 character of input_string. 1112 2. If next_char is not DQUOTE or "\", fail parsing. 1114 3. Append next_char to output_string. 1116 3. Else, if char is DQUOTE, return output_string. 1118 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not 1119 in VCHAR or SP), fail parsing. 1121 5. Else, append char to output_string. 1123 5. Reached the end of input_string without finding a closing DQUOTE; 1124 fail parsing. 1126 4.2.7. Parsing a Token from Text 1128 Given an ASCII string input_string, return a token. input_string is 1129 modified to remove the parsed value. 1131 1. If the first character of input_string is not ALPHA, fail 1132 parsing. 1134 2. Let output_string be an empty string. 1136 3. While input_string is not empty: 1138 1. Let char be the result of consuming the first character of 1139 input_string. 1141 2. If char is not one of ALPHA, DIGIT, "_", "-", ".", ":", "%", 1142 "*" or "/": 1144 1. Prepend char to input_string. 1146 2. Return output_string. 1148 3. Append char to output_string. 1150 4. Return output_string. 1152 4.2.8. Parsing a Byte Sequence from Text 1154 Given an ASCII string input_string, return a byte sequence. 1155 input_string is modified to remove the parsed value. 1157 1. If the first character of input_string is not "*", fail parsing. 1159 2. Discard the first character of input_string. 1161 3. If there is not a "*" character before the end of input_string, 1162 fail parsing. 1164 4. Let b64_content be the result of consuming content of 1165 input_string up to but not including the first instance of the 1166 character "*". 1168 5. Consume the "*" character at the beginning of input_string. 1170 6. If b64_content contains a character not included in ALPHA, DIGIT, 1171 "+", "/" and "=", fail parsing. 1173 7. Let binary_content be the result of Base 64 Decoding [RFC4648] 1174 b64_content, synthesizing padding if necessary (note the 1175 requirements about recipient behaviour below). 1177 8. Return binary_content. 1179 Because some implementations of base64 do not allow reject of encoded 1180 data that is not properly "=" padded (see [RFC4648], Section 3.2), 1181 parsers SHOULD NOT fail when it is not present, unless they cannot be 1182 configured to do so. 1184 Because some implementations of base64 do not allow rejection of 1185 encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), 1186 parsers SHOULD NOT fail when it is present, unless they cannot be 1187 configured to do so. 1189 This specification does not relax the requirements in [RFC4648], 1190 Section 3.1 and 3.3; therefore, parsers MUST fail on characters 1191 outside the base64 alphabet, and on line feeds in encoded data. 1193 4.2.9. Parsing a Boolean from Text 1195 Given an ASCII string input_string, return a Boolean. input_string is 1196 modified to remove the parsed value. 1198 1. If the first character of input_string is not "?", fail parsing. 1200 2. Discard the first character of input_string. 1202 3. If the first character of input_string matches "1", discard the 1203 first character, and return true. 1205 4. If the first character of input_string matches "0", discard the 1206 first character, and return false. 1208 5. No value has matched; fail parsing. 1210 5. IANA Considerations 1212 This draft has no actions for IANA. 1214 6. Security Considerations 1216 The size of most types defined by Structured Headers is not limited; 1217 as a result, extremely large header fields could be an attack vector 1218 (e.g., for resource consumption). Most HTTP implementations limit 1219 the sizes of individual header fields as well as the overall header 1220 block size to mitigate such attacks. 1222 It is possible for parties with the ability to inject new HTTP header 1223 fields to change the meaning of a Structured Header. In some 1224 circumstances, this will cause parsing to fail, but it is not 1225 possible to reliably fail in all such circumstances. 1227 7. References 1229 7.1. Normative References 1231 [RFC0020] Cerf, V., "ASCII format for network interchange", STD 80, 1232 RFC 20, DOI 10.17487/RFC0020, October 1969, 1233 . 1235 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 1236 Requirement Levels", BCP 14, RFC 2119, 1237 DOI 10.17487/RFC2119, March 1997, 1238 . 1240 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 1241 Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, 1242 . 1244 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 1245 Specifications: ABNF", STD 68, RFC 5234, 1246 DOI 10.17487/RFC5234, January 2008, 1247 . 1249 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1250 Protocol (HTTP/1.1): Message Syntax and Routing", 1251 RFC 7230, DOI 10.17487/RFC7230, June 2014, 1252 . 1254 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1255 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 1256 May 2017, . 1258 7.2. Informative References 1260 [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 1261 IEEE 754-2008, DOI 10.1109/IEEESTD.2008.4610935, 1262 ISBN 978-0-7381-5752-8, August 2008, 1263 . 1265 See also http://grouper.ieee.org/groups/754/ [6]. 1267 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 1268 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 1269 DOI 10.17487/RFC7231, June 2014, 1270 . 1272 [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, 1273 DOI 10.17487/RFC7493, March 2015, 1274 . 1276 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 1277 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 1278 DOI 10.17487/RFC7540, May 2015, 1279 . 1281 [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for 1282 HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, 1283 . 1285 [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data 1286 Interchange Format", STD 90, RFC 8259, 1287 DOI 10.17487/RFC8259, December 2017, 1288 . 1290 7.3. URIs 1292 [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ 1294 [2] https://httpwg.github.io/ 1296 [3] https://github.com/httpwg/http-extensions/labels/header-structure 1298 [4] https://github.com/httpwg/structured-header-tests 1300 [5] https://github.com/httpwg/wiki/wiki/Structured-Headers 1302 [6] https://github.com/httpwg/structured-header-tests 1304 Appendix A. Acknowledgements 1306 Many thanks to Matthew Kerwin for his detailed feedback and careful 1307 consideration during the development of this specification. 1309 Appendix B. Frequently Asked Questions 1311 B.1. Why not JSON? 1313 Earlier proposals for structured headers were based upon JSON 1314 [RFC8259]. However, constraining its use to make it suitable for 1315 HTTP header fields required senders and recipients to implement 1316 specific additional handling. 1318 For example, JSON has specification issues around large numbers and 1319 objects with duplicate members. Although advice for avoiding these 1320 issues is available (e.g., [RFC7493]), it cannot be relied upon. 1322 Likewise, JSON strings are by default Unicode strings, which have a 1323 number of potential interoperability issues (e.g., in comparison). 1324 Although implementers can be advised to avoid non-ASCII content where 1325 unnecessary, this is difficult to enforce. 1327 Another example is JSON's ability to nest content to arbitrary 1328 depths. Since the resulting memory commitment might be unsuitable 1329 (e.g., in embedded and other limited server deployments), it's 1330 necessary to limit it in some fashion; however, existing JSON 1331 implementations have no such limits, and even if a limit is 1332 specified, it's likely that some header field definition will find a 1333 need to violate it. 1335 Because of JSON's broad adoption and implementation, it is difficult 1336 to impose such additional constraints across all implementations; 1337 some deployments would fail to enforce them, thereby harming 1338 interoperability. In short, if it looks like JSON, people will be 1339 tempted to use a JSON parser / serialiser on header fields. 1341 Since a major goal for Structured Headers is to improve 1342 interoperability and simplify implementation, these concerns led to a 1343 format that requires a dedicated parser and serializer. 1345 Additionally, there were widely shared feelings that JSON doesn't 1346 "look right" in HTTP headers. 1348 B.2. Structured Headers don't "fit" my data. 1350 Structured headers intentionally limits the complexity of data 1351 structures, to assure that it can be processed in a performant manner 1352 with little overhead. This means that work is necessary to fit some 1353 data types into them. 1355 Sometimes, this can be achieved by creating limited substructures in 1356 values, and/or using more than one header. For example, consider: 1358 Example-Thing: name="Widget", cost=89.2, descriptions=(foo bar) 1359 Example-Description: foo; url="https://example.net"; context=123, 1360 bar; url="https://example.org"; context=456 1362 Since the description contains an array of key/value pairs, we use a 1363 List to represent them, with the token for each item in the array 1364 used to identify it in the "descriptions" member of the Example-Thing 1365 header. 1367 When specifying more than one header, it's important to remember to 1368 describe what a processor's behaviour should be when one of the 1369 headers is missing. 1371 If you need to fit arbitrarily complex data into a header, Structured 1372 Headers is probably a poor fit for your use case. 1374 Appendix C. Implementation Notes 1376 A generic implementation of this specification should expose the top- 1377 level parse (Section 4.2) and serialize (Section 4.1) functions. 1378 They need not be functions; for example, it could be implemented as 1379 an object, with methods for each of the different top-level types. 1381 For interoperability, it's important that generic implementations be 1382 complete and follow the algorithms closely; see Section 1.1. To aid 1383 this, a common test suite is being maintained by the community; see 1384 https://github.com/httpwg/structured-header-tests [7]. 1386 Implementers should note that dictionaries and parameters are order- 1387 preserving maps. Some headers may not convey meaning in the ordering 1388 of these data types, but it should still be exposed so that 1389 applications which need to use it will have it available. 1391 Likewise, implementations should note that it's important to preserve 1392 the distinction between tokens and strings. While most programming 1393 languages have native types that map to the other types well, it may 1394 be necessary to create a wrapper "token" object or use a parameter on 1395 functions to assure that these types remain separate. 1397 Appendix D. Changes 1399 _RFC Editor: Please remove this section before publication._ 1401 D.1. Since draft-ietf-httpbis-header-structure-10 1403 o Update abstract (#799). 1405 o Input and output are now arrays of bytes (#662). 1407 o Implementations need to preserve difference between token and 1408 string (#790). 1410 o Allow empty dictionaries and lists (#781). 1412 o Change parameterized lists to have primary items (#797). 1414 o Allow inner lists in both dictionaries and lists; removes lists of 1415 lists (#816). 1417 o Subsume Parameterised Lists into Lists (#839). 1419 D.2. Since draft-ietf-httpbis-header-structure-09 1421 o Changed Boolean from T/F to 1/0 (#784). 1423 o Parameters are now ordered maps (#765). 1425 o Clamp integers to 15 digits (#737). 1427 D.3. Since draft-ietf-httpbis-header-structure-08 1429 o Disallow whitespace before items properly (#703). 1431 o Created "key" for use in dictionaries and parameters, rather than 1432 relying on identifier (#702). Identifiers have a separate minimum 1433 supported size. 1435 o Expanded the range of special characters allowed in identifier to 1436 include all of ALPHA, ".", ":", and "%" (#702). 1438 o Use "?" instead of "!" to indicate a Boolean (#719). 1440 o Added "Intentionally Strict Processing" (#684). 1442 o Gave better names for referring specs to use in Parameterised 1443 Lists (#720). 1445 o Added Lists of Lists (#721). 1447 o Rename Identifier to Token (#725). 1449 o Add implementation guidance (#727). 1451 D.4. Since draft-ietf-httpbis-header-structure-07 1453 o Make Dictionaries ordered mappings (#659). 1455 o Changed "binary content" to "byte sequence" to align with Infra 1456 specification (#671). 1458 o Changed "mapping" to "map" for #671. 1460 o Don't fail if byte sequences aren't "=" padded (#658). 1462 o Add Booleans (#683). 1464 o Allow identifiers in items again (#629). 1466 o Disallowed whitespace before items (#703). 1468 o Explain the consequences of splitting a string across multiple 1469 headers (#686). 1471 D.5. Since draft-ietf-httpbis-header-structure-06 1473 o Add a FAQ. 1475 o Allow non-zero pad bits. 1477 o Explicitly check for integers that violate constraints. 1479 D.6. Since draft-ietf-httpbis-header-structure-05 1481 o Reorganise specification to separate parsing out. 1483 o Allow referencing specs to use ABNF. 1485 o Define serialisation algorithms. 1487 o Refine relationship between ABNF, parsing and serialisation 1488 algorithms. 1490 D.7. Since draft-ietf-httpbis-header-structure-04 1492 o Remove identifiers from item. 1494 o Remove most limits on sizes. 1496 o Refine number parsing. 1498 D.8. Since draft-ietf-httpbis-header-structure-03 1500 o Strengthen language around failure handling. 1502 D.9. Since draft-ietf-httpbis-header-structure-02 1504 o Split Numbers into Integers and Floats. 1506 o Define number parsing. 1508 o Tighten up binary parsing and give it an explicit end delimiter. 1510 o Clarify that mappings are unordered. 1512 o Allow zero-length strings. 1514 o Improve string parsing algorithm. 1516 o Improve limits in algorithms. 1518 o Require parsers to combine header fields before processing. 1520 o Throw an error on trailing garbage. 1522 D.10. Since draft-ietf-httpbis-header-structure-01 1524 o Replaced with draft-nottingham-structured-headers. 1526 D.11. Since draft-ietf-httpbis-header-structure-00 1528 o Added signed 64bit integer type. 1530 o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- 1531 unicode-string. 1533 o Change h1_blob delimiter to ":" since "'" is valid t_char 1535 Authors' Addresses 1537 Mark Nottingham 1538 Fastly 1540 Email: mnot@mnot.net 1541 URI: https://www.mnot.net/ 1543 Poul-Henning Kamp 1544 The Varnish Cache Project 1546 Email: phk@varnish-cache.org