| draft-ietf-httpbis-header-structure-12.txt | draft-ietf-httpbis-header-structure-13.txt | |||
|---|---|---|---|---|
| HTTP M. Nottingham | HTTP M. Nottingham | |||
| Internet-Draft Fastly | Internet-Draft Fastly | |||
| Intended status: Standards Track P-H. Kamp | Intended status: Standards Track P-H. Kamp | |||
| Expires: February 20, 2020 The Varnish Cache Project | Expires: February 25, 2020 The Varnish Cache Project | |||
| August 19, 2019 | August 24, 2019 | |||
| Structured Headers for HTTP | Structured Headers for HTTP | |||
| draft-ietf-httpbis-header-structure-12 | draft-ietf-httpbis-header-structure-13 | |||
| Abstract | Abstract | |||
| This document describes a set of data types and associated algorithms | This document describes a set of data types and associated algorithms | |||
| that are intended to make it easier and safer to define and handle | that are intended to make it easier and safer to define and handle | |||
| HTTP header fields. It is intended for use by specifications of new | HTTP header fields. It is intended for use by specifications of new | |||
| HTTP header fields that wish to use a common syntax that is more | HTTP header fields that wish to use a common syntax that is more | |||
| restrictive than traditional HTTP field values. | restrictive than traditional HTTP field values. | |||
| Note to Readers | Note to Readers | |||
| skipping to change at page 2, line 10 ¶ | skipping to change at page 2, line 10 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on February 20, 2020. | This Internet-Draft will expire on February 25, 2020. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2019 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| skipping to change at page 2, line 34 ¶ | skipping to change at page 2, line 34 ¶ | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 | 1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 | |||
| 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 | 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 | |||
| 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 | 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 | |||
| 3. Structured Header Data Types . . . . . . . . . . . . . . . . 6 | 3. Structured Header Data Types . . . . . . . . . . . . . . . . 6 | |||
| 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 6 | 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 7 | |||
| 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 8 | 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 9 | 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 3.4. Integers . . . . . . . . . . . . . . . . . . . . . . . . 9 | 3.4. Integers . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 3.5. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 9 | 3.5. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 3.6. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 3.6. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 3.7. Tokens . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 3.7. Tokens . . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 3.8. Byte Sequences . . . . . . . . . . . . . . . . . . . . . 11 | 3.8. Byte Sequences . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 3.9. Booleans . . . . . . . . . . . . . . . . . . . . . . . . 11 | 3.9. Booleans . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 4. Working With Structured Headers in Textual HTTP Headers . . . 11 | 4. Working With Structured Headers in Textual HTTP Headers . . . 12 | |||
| 4.1. Serializing Structured Headers . . . . . . . . . . . . . 11 | 4.1. Serializing Structured Headers . . . . . . . . . . . . . 12 | |||
| 4.2. Parsing Header Fields into Structured Headers . . . . . . 18 | 4.2. Parsing Header Fields into Structured Headers . . . . . . 18 | |||
| 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 | 6. Security Considerations . . . . . . . . . . . . . . . . . . . 27 | |||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 27 | 7.1. Normative References . . . . . . . . . . . . . . . . . . 27 | |||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 28 | 7.2. Informative References . . . . . . . . . . . . . . . . . 28 | |||
| 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 28 | 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 29 | |||
| Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 29 | Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 29 | |||
| Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 29 | Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 29 | |||
| B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 29 | B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 29 | |||
| B.2. Structured Headers don't "fit" my data. . . . . . . . . . 30 | B.2. Structured Headers don't "fit" my data. . . . . . . . . . 30 | |||
| Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 30 | Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 31 | |||
| Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 31 | Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 31 | |||
| D.1. Since draft-ietf-httpbis-header-structure-11 . . . . . . 31 | D.1. Since draft-ietf-httpbis-header-structure-12 . . . . . . 31 | |||
| D.2. Since draft-ietf-httpbis-header-structure-10 . . . . . . 31 | D.2. Since draft-ietf-httpbis-header-structure-11 . . . . . . 31 | |||
| D.3. Since draft-ietf-httpbis-header-structure-09 . . . . . . 31 | D.3. Since draft-ietf-httpbis-header-structure-10 . . . . . . 31 | |||
| D.4. Since draft-ietf-httpbis-header-structure-08 . . . . . . 31 | D.4. Since draft-ietf-httpbis-header-structure-09 . . . . . . 32 | |||
| D.5. Since draft-ietf-httpbis-header-structure-07 . . . . . . 32 | D.5. Since draft-ietf-httpbis-header-structure-08 . . . . . . 32 | |||
| D.6. Since draft-ietf-httpbis-header-structure-06 . . . . . . 32 | D.6. Since draft-ietf-httpbis-header-structure-07 . . . . . . 33 | |||
| D.7. Since draft-ietf-httpbis-header-structure-05 . . . . . . 32 | D.7. Since draft-ietf-httpbis-header-structure-06 . . . . . . 33 | |||
| D.8. Since draft-ietf-httpbis-header-structure-04 . . . . . . 33 | D.8. Since draft-ietf-httpbis-header-structure-05 . . . . . . 33 | |||
| D.9. Since draft-ietf-httpbis-header-structure-03 . . . . . . 33 | D.9. Since draft-ietf-httpbis-header-structure-04 . . . . . . 33 | |||
| D.10. Since draft-ietf-httpbis-header-structure-02 . . . . . . 33 | D.10. Since draft-ietf-httpbis-header-structure-03 . . . . . . 34 | |||
| D.11. Since draft-ietf-httpbis-header-structure-01 . . . . . . 33 | D.11. Since draft-ietf-httpbis-header-structure-02 . . . . . . 34 | |||
| D.12. Since draft-ietf-httpbis-header-structure-00 . . . . . . 33 | D.12. Since draft-ietf-httpbis-header-structure-01 . . . . . . 34 | |||
| D.13. Since draft-ietf-httpbis-header-structure-00 . . . . . . 34 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 34 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 34 | |||
| 1. Introduction | 1. Introduction | |||
| Specifying the syntax of new HTTP header fields is an onerous task; | Specifying the syntax of new HTTP header fields is an onerous task; | |||
| even with the guidance in [RFC7231], Section 8.3.1, there are many | even with the guidance in Section 8.3.1 of [RFC7231], there are many | |||
| decisions - and pitfalls - for a prospective HTTP header field | decisions - and pitfalls - for a prospective HTTP header field | |||
| author. | author. | |||
| Once a header field is defined, bespoke parsers and serializers often | Once a header field is defined, bespoke parsers and serializers often | |||
| need to be written, because each header has slightly different | need to be written, because each header has slightly different | |||
| handling of what looks like common syntax. | handling of what looks like common syntax. | |||
| This document introduces a set of common data structures for use in | This document introduces a set of common data structures for use in | |||
| definitions of new HTTP header field values to address these | definitions of new HTTP header field values to address these | |||
| problems. In particular, it defines a generic, abstract model for | problems. In particular, it defines a generic, abstract model for | |||
| skipping to change at page 5, line 30 ¶ | skipping to change at page 5, line 30 ¶ | |||
| To define a HTTP header as a structured header, its specification | To define a HTTP header as a structured header, its specification | |||
| needs to: | needs to: | |||
| o Reference this specification. Recipients and generators of the | o Reference this specification. Recipients and generators of the | |||
| header need to know that the requirements of this document are in | header need to know that the requirements of this document are in | |||
| effect. | effect. | |||
| o Specify the header field's allowed syntax for values, in terms of | o Specify the header field's allowed syntax for values, in terms of | |||
| the types described in Section 3, along with their associated | the types described in Section 3, along with their associated | |||
| semantics. Syntax definitions are encouraged to use the ABNF | semantics. Syntax definitions are encouraged to use the ABNF | |||
| rules beginning with "sh-" defined in this specification. | rules beginning with "sh-" defined in this specification; other | |||
| rules in this specification are not intended for use outside it. | ||||
| o Specify any additional constraints upon the syntax of the | o Specify any additional constraints upon the syntax of the | |||
| structured used, as well as the consequences when those | structures used, as well as the consequences when those | |||
| constraints are violated. When Structured Headers parsing fails, | constraints are violated. When Structured Headers parsing fails, | |||
| the header is discarded (see Section 4.2); in most situations, | the header is ignored (see Section 4.2); in most situations, | |||
| header-specific constraints should do likewise. | header-specific constraints should do likewise. | |||
| Note that a header field definition cannot relax the requirements of | Note that a header field definition cannot relax the requirements of | |||
| this specification because doing so would preclude handling by | this specification because doing so would preclude handling by | |||
| generic software; they can only add additional constraints (for | generic software; they can only add additional constraints (for | |||
| example, on the numeric range of integers and floats, the format of | example, on the numeric range of integers and floats, the format of | |||
| strings and tokens, or the number of items in a list). Likewise, | strings and tokens, the types allowed in a dictionary's values, or | |||
| header field definitions should use Structured Headers for the entire | the number of items in a list). Likewise, header field definitions | |||
| header field value, not a portion thereof. | can only use Structured Headers for the entire header field value, | |||
| not a portion thereof. | ||||
| This specification defines minimums for the length or number of | This specification defines minimums for the length or number of | |||
| various structures supported by Structured Headers implementations. | various structures supported by Structured Headers implementations. | |||
| It does not specify maximum sizes in most cases, but header authors | It does not specify maximum sizes in most cases, but header authors | |||
| should be aware that HTTP implementations do impose various limits on | should be aware that HTTP implementations do impose various limits on | |||
| the size of individual header fields, the total number of fields, | the size of individual header fields, the total number of fields, | |||
| and/or the size of the entire header block. | and/or the size of the entire header block. | |||
| For example, | For example, a fictitious Foo-Example header field might be specified | |||
| as: | ||||
| 42. Foo-Example Header | 42. Foo-Example Header | |||
| The Foo-Example HTTP header field conveys information about how | The Foo-Example HTTP header field conveys information about how | |||
| much Foo the message has. | much Foo the message has. | |||
| Foo-Example is a Structured Header [RFCxxxx]. Its value MUST be a | Foo-Example is a Structured Header [RFCxxxx]. Its value MUST be a | |||
| dictionary ([RFCxxxx], Section Y.Y). Its ABNF is: | dictionary (Section Y.Y of [RFCxxxx]). Its ABNF is: | |||
| Foo-Example = sh-dictionary | Foo-Example = sh-dictionary | |||
| The dictionary MUST contain: | The dictionary MUST contain: | |||
| * Exactly one member whose name is "foo", and whose value is an | * Exactly one member whose name is "foo", and whose value is an | |||
| integer ([RFCxxxx], Section Y.Y), indicating the number of foos | integer (Section Y.Y of [RFCxxxx]), indicating the number of foos | |||
| in the message. | in the message. | |||
| * Exactly one member whose name is "barUrl", and whose value is a | * Exactly one member whose name is "barUrl", and whose value is a | |||
| string ([RFCxxxx], Section Y.Y), conveying the Bar URL for the | list of strings (Section Y.Y of [RFCxxxx]), conveying the Bar URLs | |||
| message. See below for processing requirements. | for the message. See below for processing requirements. | |||
| If the parsed header field does not contain both, it MUST be | If the parsed header field does not contain both, it MUST be | |||
| ignored. | ignored. | |||
| "foo" MUST be between 0 and 10, inclusive; other values MUST cause | "foo" MUST be between 0 and 10, inclusive; other values MUST cause | |||
| the header to be ignored. | the header to be ignored. | |||
| "barUrl" contains a URI-reference ([RFC3986], Section 4.1). | "barUrl" contains one or more URI-references (Section 4.1 of | |||
| [RFC3986], Section 4.1). If barURL is not a valid URI-reference, | ||||
| it MUST be ignored. If barURL is a relative reference (Section 4.2 | ||||
| of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | ||||
| being used. | ||||
| If barURL is not a valid URI-reference, it MUST be ignored. | For example: | |||
| If barURL is a relative reference ([RFC3986], Section 4.2), | ||||
| it MUST be resolved ([RFC3986], Section 5) before being used. | Foo-Example: foo=2, barUrl=("https://bar.example.com/") | |||
| 3. Structured Header Data Types | 3. Structured Header Data Types | |||
| This section defines the abstract value types that can be composed | This section defines the abstract value types that can be composed | |||
| into Structured Headers. The ABNF provided represents the on-wire | into Structured Headers. The ABNF provided represents the on-wire | |||
| format in HTTP. | format in textual HTTP headers. | |||
| 3.1. Lists | 3.1. Lists | |||
| Lists are arrays of zero or more members, each of which can be an | Lists are arrays of zero or more members, each of which can be an | |||
| item (Section 3.3) or an inner list (an array of zero or more items). | item (Section 3.3) or an inner list (an array of zero or more items). | |||
| Each member of the top-level list can also have associated parameters | Each member of the top-level list can also have associated parameters | |||
| - an ordered map of key-value pairs where the keys are short, textual | - an ordered map of key-value pairs where the keys are short, textual | |||
| strings and the values are items (Section 3.3). There can be zero or | strings and the values are items (Section 3.3). There can be zero or | |||
| more parameters on a member, and their keys are required to be unique | more parameters on a member, and their keys are required to be unique | |||
| skipping to change at page 7, line 36 ¶ | skipping to change at page 7, line 45 ¶ | |||
| header field whose value is defined as a list of lists of strings | header field whose value is defined as a list of lists of strings | |||
| could look like: | could look like: | |||
| Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () | Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () | |||
| Note that the last member in this example is an empty inner list. | Note that the last member in this example is an empty inner list. | |||
| In textual HTTP headers, members' parameters are separated from the | In textual HTTP headers, members' parameters are separated from the | |||
| member and each other by semicolons. For example: | member and each other by semicolons. For example: | |||
| Example-ParamListHeader: abc_123;a=1;b=2; cdef_456, (ghi jkl);q="9";r="w" | Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi jkl);q="9";r=w | |||
| In textual HTTP headers, an empty list is denoted by not serialising | In textual HTTP headers, an empty list is denoted by not serialising | |||
| the header at all. | the header at all. | |||
| Parsers MUST support lists containing at least 1024 members, support | Parsers MUST support lists containing at least 1024 members, support | |||
| members with at least 256 parameters, support inner-lists containing | members with at least 256 parameters, support inner-lists containing | |||
| at least 256 members, and support parameter keys with at least 64 | at least 256 members, and support parameter keys with at least 64 | |||
| characters. | characters. | |||
| Header specifications can constrain the types of individual list | Header specifications can constrain the types of individual list | |||
| skipping to change at page 11, line 49 ¶ | skipping to change at page 12, line 13 ¶ | |||
| Example-BoolHdr: ?1 | Example-BoolHdr: ?1 | |||
| 4. Working With Structured Headers in Textual HTTP Headers | 4. Working With Structured Headers in Textual HTTP Headers | |||
| This section defines how to serialize and parse Structured Headers in | This section defines how to serialize and parse Structured Headers in | |||
| textual header fields, and protocols compatible with them (e.g., in | textual header fields, and protocols compatible with them (e.g., in | |||
| HTTP/2 [RFC7540] before HPACK [RFC7541] is applied). | HTTP/2 [RFC7540] before HPACK [RFC7541] is applied). | |||
| 4.1. Serializing Structured Headers | 4.1. Serializing Structured Headers | |||
| Given a structure defined in this specification: | Given a structure defined in this specification, return an ASCII | |||
| string suitable for use in a textual HTTP header value. | ||||
| 1. If the structure is a dictionary or list and its value is empty | 1. If the structure is a dictionary or list and its value is empty | |||
| (i.e., it has no members), do not send the serialize field at all | (i.e., it has no members), do not send the serialize field at all | |||
| (i.e., omit both the field-name and field-value). | (i.e., omit both the field-name and field-value). | |||
| 2. If the structure is a dictionary, let output_string be the result | 2. If the structure is a dictionary, let output_string be the result | |||
| of Serializing a Dictionary (Section 4.1.2). | of Serializing a Dictionary (Section 4.1.2). | |||
| 3. Else if the structure is a list, let output_string be the result | 3. Else if the structure is a list, let output_string be the result | |||
| of Serializing a List (Section 4.1.1). | of Serializing a List (Section 4.1.1). | |||
| skipping to change at page 12, line 25 ¶ | skipping to change at page 12, line 36 ¶ | |||
| 4. Else if the structure is an item, let output_string be the result | 4. Else if the structure is an item, let output_string be the result | |||
| of Serializing an Item (Section 4.1.3). | of Serializing an Item (Section 4.1.3). | |||
| 5. Else, fail serialisation. | 5. Else, fail serialisation. | |||
| 6. Return output_string converted into an array of bytes, using | 6. Return output_string converted into an array of bytes, using | |||
| ASCII encoding [RFC0020]. | ASCII encoding [RFC0020]. | |||
| 4.1.1. Serializing a List | 4.1.1. Serializing a List | |||
| Given a list of (member, parameters) as input_list: | Given a list of (member-value, parameters) as input_list, return an | |||
| ASCII string suitable for use in a textual HTTP header value. | ||||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each (member, parameters) of input_list: | 2. For each (member-value, parameters) of input_list: | |||
| 1. If member is an array, let mem_value be the result of | ||||
| applying Serialising an Inner List (Section 4.1.1.1) to | ||||
| member. | ||||
| 2. Otherwise, let mem_value be the result of applying | 1. If member-value is an array, append the result of applying | |||
| Serializing an Item (Section 4.1.3) to member. | Serialising an Inner List (Section 4.1.1.1) with member-value | |||
| to output. | ||||
| 3. Append mem_value to output. | 2. Otherwise, append the result of applying Serializing an Item | |||
| (Section 4.1.3) with member-value to output. | ||||
| 4. Append the result of Serializing Parameters Section 4.1.1.2 | 3. Append the result of Serializing Parameters Section 4.1.1.2 | |||
| with parameters to output. | with parameters to output. | |||
| 5. If more members remain in input_plist: | 4. If more member-values remain in input_plist: | |||
| 1. Append a COMMA to output. | 1. Append a COMMA to output. | |||
| 2. Append a single WS to output. | 2. Append a single WS to output. | |||
| 3. Return output. | 3. Return output. | |||
| 4.1.1.1. Serialising an Inner List | 4.1.1.1. Serialising an Inner List | |||
| Given an array inner_list: | Given an array as inner_list, return an ASCII string suitable for use | |||
| in a textual HTTP header value. | ||||
| 1. Let output be the string "(". | 1. Let output be the string "(". | |||
| 2. For each member mem of inner_list: | 2. For each member-value of inner_list: | |||
| 1. Let value be the result of applying Serializing an Item | ||||
| (Section 4.1.3) to mem. | ||||
| 2. Append value to output. | 1. Append the result of applying Serializing an Item | |||
| (Section 4.1.3) with member-value to output. | ||||
| 3. If inner_list is not empty, append a single WS to output. | 2. If inner_list is not empty, append a single WS to output. | |||
| 3. Append ")" to output. | 3. Append ")" to output. | |||
| 4. Return output. | 4. Return output. | |||
| 4.1.1.2. Serializing Parameters | 4.1.1.2. Serializing Parameters | |||
| Given an ordered dictionary parameters: | Given an ordered dictionary as input_parameters (each member having a | |||
| param-name and a param-value), return an ASCII string suitable for | ||||
| use in a textual HTTP header value. | ||||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each parameter in parameters: | 2. For each parameter-name with a value of param-value in | |||
| input_parameters: | ||||
| 3. Append ";" to output. | ||||
| 4. Let name be the result of applying Serializing a Key | ||||
| (Section 4.1.1.3) to parameter's param-name. | ||||
| 5. Append name to output. | 1. Append ";" to output. | |||
| 6. If parameter has a param-value: | 2. Append the result of applying Serializing a Key | |||
| (Section 4.1.1.3) with param-name to output. | ||||
| 1. Let value be the result of applying Serializing an Item | 3. If param-value is not null: | |||
| (Section 4.1.3) to parameter's param-value. | ||||
| 2. Append "=" to output. | 1. Append "=" to output. | |||
| 3. Append value to output. | 2. Append the result of applying Serializing an Item | |||
| (Section 4.1.3) with param-value to output. | ||||
| 7. Return output. | 3. Return output. | |||
| 4.1.1.3. Serializing a Key | 4.1.1.3. Serializing a Key | |||
| Given a key as input_key: | Given a key as input_key, return an ASCII string suitable for use in | |||
| a textual HTTP header value. | ||||
| 1. If input_key is not a sequence of characters, or contains | 1. If input_key is not a sequence of characters, or contains | |||
| characters not allowed in the ABNF for key, fail serialisation. | characters not in lcalpha, DIGIT, "*", "_", or "-", fail | |||
| serialisation. | ||||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. Append input_key to output. | 3. Append input_key to output. | |||
| 4. Return output. | 4. Return output. | |||
| 4.1.2. Serializing a Dictionary | 4.1.2. Serializing a Dictionary | |||
| Given a dictionary as input_dictionary: | Given an ordered dictionary as input_dictionary (each member having a | |||
| member-name and a tuple value of (member-value, parameters)), return | ||||
| an ASCII string suitable for use in a textual HTTP header value. | ||||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each (member, parameters) of input_dictionary: | 2. For each member-name with a value of (member-value, parameters) | |||
| in input_dictionary: | ||||
| 1. Let name be the result of applying Serializing a Key | ||||
| (Section 4.1.1.3) to member's member-name. | ||||
| 2. Append name to output. | ||||
| 3. Append "=" to output. | 1. Append the result of applying Serializing a Key | |||
| (Section 4.1.1.3) with member's member-name to output. | ||||
| 4. If member is an array, let value be the result of applying | 2. Append "=" to output. | |||
| Serialising an Inner List (Section 4.1.1.1) to member. | ||||
| 5. Otherwise, let value be the result of applying Serializing an | 3. If member-value is an array, append the result of applying | |||
| Item (Section 4.1.3) to member. | Serialising an Inner List (Section 4.1.1.1) with member-value | |||
| to output. | ||||
| 6. Append value to output. | 4. Otherwise, append the result of applying Serializing an Item | |||
| (Section 4.1.3) with member-value to output. | ||||
| 7. Append the result of Serializing Parameters Section 4.1.1.2 | 5. Append the result of Serializing Parameters Section 4.1.1.2 | |||
| with parameters to output. | with parameters to output. | |||
| 8. If more members remain in input_dictionary: | 6. If more members remain in input_dictionary: | |||
| 1. Append a COMMA to output. | 1. Append a COMMA to output. | |||
| 2. Append a single WS to output. | 2. Append a single WS to output. | |||
| 3. Return output. | 3. Return output. | |||
| 4.1.3. Serializing an Item | 4.1.3. Serializing an Item | |||
| Given an item as input_item: | Given an item as input_item, return an ASCII string suitable for use | |||
| in a textual HTTP header value. | ||||
| 1. If input_item is an integer, return the result of applying | 1. If input_item is an integer, return the result of applying | |||
| Serializing an Integer (Section 4.1.4) to input_item. | Serializing an Integer (Section 4.1.4) to input_item. | |||
| 2. If input_item is a float, return the result of applying | 2. If input_item is a float, return the result of applying | |||
| Serializing a Float (Section 4.1.5) to input_item. | Serializing a Float (Section 4.1.5) to input_item. | |||
| 3. If input_item is a string, return the result of applying | 3. If input_item is a string, return the result of applying | |||
| Serializing a String (Section 4.1.6) to input_item. | Serializing a String (Section 4.1.6) to input_item. | |||
| skipping to change at page 15, line 31 ¶ | skipping to change at page 15, line 34 ¶ | |||
| 5. If input_item is a Boolean, return the result of applying | 5. If input_item is a Boolean, return the result of applying | |||
| Serializing a Boolean (Section 4.1.9) to input_item. | Serializing a Boolean (Section 4.1.9) to input_item. | |||
| 6. If input_item is a byte sequence, return the result of applying | 6. If input_item is a byte sequence, return the result of applying | |||
| Serializing a Byte Sequence (Section 4.1.8) to input_item. | Serializing a Byte Sequence (Section 4.1.8) to input_item. | |||
| 7. Otherwise, fail serialisation. | 7. Otherwise, fail serialisation. | |||
| 4.1.4. Serializing an Integer | 4.1.4. Serializing an Integer | |||
| Given an integer as input_integer: | Given an integer as input_integer, return an ASCII string suitable | |||
| for use in a textual HTTP header value. | ||||
| 1. If input_integer is not an integer in the range of | 1. If input_integer is not an integer in the range of | |||
| -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | |||
| serialisation. | serialisation. | |||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. If input_integer is less than (but not equal to) 0, append "-" to | 3. If input_integer is less than (but not equal to) 0, append "-" to | |||
| output. | output. | |||
| 4. Append input_integer's numeric value represented in base 10 using | 4. Append input_integer's numeric value represented in base 10 using | |||
| only decimal digits to output. | only decimal digits to output. | |||
| 5. Return output. | 5. Return output. | |||
| 4.1.5. Serializing a Float | 4.1.5. Serializing a Float | |||
| Given a float as input_float: | Given a float as input_float, return an ASCII string suitable for use | |||
| in a textual HTTP header value. | ||||
| 1. If input_float's fractional component has more than six digits of | 1. Let output be an empty string. | |||
| precision, fail serialisation. | ||||
| 2. If the number of digits of precision in input_float's fractional | 2. If input_float is less than (but not equal to) 0, append "-" to | |||
| component plus those in its integer component add to more than | output. | |||
| fifteen digits, fail serialisation. | ||||
| 3. Let output be an empty string. | 3. Append input_float's integer component represented in base 10 | |||
| (using only decimal digits) to output; if it is zero, append | ||||
| "0". | ||||
| 4. If input_float is less than (but not equal to) 0, append "-" to | 4. Let integer_digits be the number of characters appended in the | |||
| output. | previous step. | |||
| 5. Append input_float's integer component represented in base 10 | 5. If integer_digits is greater than 14, fail serialisation. | |||
| using only decimal digits to output; if it is zero, append "0". | ||||
| 6. Append "." to output. | 6. Let digits_avail be 15 minus integer_digits. | |||
| 7. Append input_float's fractional component represented in base 10 | 7. Let fractional_digits_avail be the minimum of digits_avail and | |||
| using only decimal digits to output; if it is zero, append "0". | 6. | |||
| 8. Return output. | 8. Append "." to output. | |||
| 9. Append at most fractional_digits_avail digits of input_float's | ||||
| fractional component represented in base 10 to output (using | ||||
| only decimal digits, and truncating any remaining digits); if it | ||||
| is zero, append "0". | ||||
| 10. Return output. | ||||
| 4.1.6. Serializing a String | 4.1.6. Serializing a String | |||
| Given a string as input_string: | Given a string as input_string, return an ASCII string suitable for | |||
| use in a textual HTTP header value. | ||||
| 1. If input_string is not a sequence of characters, or contains | 1. If input_string is not a sequence of characters, or contains | |||
| characters outside the range allowed by VCHAR or SP, fail | characters outside the range %x00-1f or %x7f (i.e., is not in | |||
| serialisation. | VCHAR or SP), fail serialisation. | |||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. Append DQUOTE to output. | 3. Append DQUOTE to output. | |||
| 4. For each character char in input_string: | 4. For each character char in input_string: | |||
| 1. If char is "\" or DQUOTE: | 1. If char is "\" or DQUOTE: | |||
| 1. Append "\" to output. | 1. Append "\" to output. | |||
| 2. Append char to output. | 2. Append char to output. | |||
| 5. Append DQUOTE to output. | 5. Append DQUOTE to output. | |||
| 6. Return output. | 6. Return output. | |||
| 4.1.7. Serializing a Token | 4.1.7. Serializing a Token | |||
| Given a token as input_token: | Given a token as input_token, return an ASCII string suitable for use | |||
| in a textual HTTP header value. | ||||
| 1. If input_token is not a sequence of characters, or contains | 1. If input_token is not a sequence of characters, or contains | |||
| characters not allowed in Section 3.7, fail serialisation. | characters not in ALPHA, DIGIT, "_", "-", ".", ":", "%", "*" or | |||
| "/", fail serialisation. | ||||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. Append input_token to output. | 3. Append input_token to output. | |||
| 4. Return output. | 4. Return output. | |||
| 4.1.8. Serializing a Byte Sequence | 4.1.8. Serializing a Byte Sequence | |||
| Given a byte sequence as input_bytes: | Given a byte sequence as input_bytes, return an ASCII string suitable | |||
| for use in a textual HTTP header value. | ||||
| 1. If input_bytes is not a sequence of bytes, fail serialisation. | 1. If input_bytes is not a sequence of bytes, fail serialisation. | |||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. Append "*" to output. | 3. Append "*" to output. | |||
| 4. Append the result of base64-encoding input_bytes as per | 4. Append the result of base64-encoding input_bytes as per | |||
| [RFC4648], Section 4, taking account of the requirements below. | [RFC4648], Section 4, taking account of the requirements below. | |||
| skipping to change at page 17, line 40 ¶ | skipping to change at page 18, line 11 ¶ | |||
| The encoded data is required to be padded with "=", as per [RFC4648], | The encoded data is required to be padded with "=", as per [RFC4648], | |||
| Section 3.2. | Section 3.2. | |||
| Likewise, encoded data SHOULD have pad bits set to zero, as per | Likewise, encoded data SHOULD have pad bits set to zero, as per | |||
| [RFC4648], Section 3.5, unless it is not possible to do so due to | [RFC4648], Section 3.5, unless it is not possible to do so due to | |||
| implementation constraints. | implementation constraints. | |||
| 4.1.9. Serializing a Boolean | 4.1.9. Serializing a Boolean | |||
| Given a Boolean as input_boolean: | Given a Boolean as input_boolean, return an ASCII string suitable for | |||
| use in a textual HTTP header value. | ||||
| 1. If input_boolean is not a boolean, fail serialisation. | 1. If input_boolean is not a boolean, fail serialisation. | |||
| 2. Let output be an empty string. | 2. Let output be an empty string. | |||
| 3. Append "?" to output. | 3. Append "?" to output. | |||
| 4. If input_boolean is true, append "1" to output. | 4. If input_boolean is true, append "1" to output. | |||
| 5. If input_boolean is false, append "0" to output. | 5. If input_boolean is false, append "0" to output. | |||
| skipping to change at page 18, line 30 ¶ | skipping to change at page 18, line 51 ¶ | |||
| 2. Discard any leading OWS from input_string. | 2. Discard any leading OWS from input_string. | |||
| 3. If header_type is "list", let output be the result of Parsing a | 3. If header_type is "list", let output be the result of Parsing a | |||
| List from Text (Section 4.2.1). | List from Text (Section 4.2.1). | |||
| 4. If header_type is "dictionary", let output be the result of | 4. If header_type is "dictionary", let output be the result of | |||
| Parsing a Dictionary from Text (Section 4.2.2). | Parsing a Dictionary from Text (Section 4.2.2). | |||
| 5. If header_type is "item", let output be the result of Parsing an | 5. If header_type is "item", let output be the result of Parsing an | |||
| Item from Text (Section 4.2.4). | Item from Text (Section 4.2.3). | |||
| 6. Discard any leading OWS from input_string. | 6. Discard any leading OWS from input_string. | |||
| 7. If input_string is not empty, fail parsing. | 7. If input_string is not empty, fail parsing. | |||
| 8. Otherwise, return output. | 8. Otherwise, return output. | |||
| When generating input_bytes, parsers MUST combine all instances of | When generating input_bytes, parsers MUST combine all instances of | |||
| the target header field into one comma-separated field-value, as per | the target header field into one comma-separated field-value, as per | |||
| [RFC7230], Section 3.2.2; this assures that the header is processed | [RFC7230], Section 3.2.2; this assures that the header is processed | |||
| skipping to change at page 19, line 10 ¶ | skipping to change at page 19, line 32 ¶ | |||
| unpredictable results, because comma(s) and whitespace inserted upon | unpredictable results, because comma(s) and whitespace inserted upon | |||
| combination will become part of the string output by the parser. | combination will become part of the string output by the parser. | |||
| Since concatenation might be done by an upstream intermediary, the | Since concatenation might be done by an upstream intermediary, the | |||
| results are not under the control of the serializer or the parser. | results are not under the control of the serializer or the parser. | |||
| Tokens, Integers, Floats and Byte Sequences cannot be split across | Tokens, Integers, Floats and Byte Sequences cannot be split across | |||
| multiple headers because the inserted commas will cause parsing to | multiple headers because the inserted commas will cause parsing to | |||
| fail. | fail. | |||
| If parsing fails - including when calling another algorithm - the | If parsing fails - including when calling another algorithm - the | |||
| entire header field's value MUST be discarded. This is intentionally | entire header field's value MUST be ignored (i.e., treated as if the | |||
| header field were not present in the message). This is intentionally | ||||
| strict, to improve interoperability and safety, and specifications | strict, to improve interoperability and safety, and specifications | |||
| referencing this document are not allowed to loosen this requirement. | referencing this document are not allowed to loosen this requirement. | |||
| Note that this requirement does not apply to an implementation that | ||||
| is not parsing the header field; for example, an intermediary is not | ||||
| required to strip a failing header field from a message before | ||||
| forwarding it. | ||||
| 4.2.1. Parsing a List from Text | 4.2.1. Parsing a List from Text | |||
| Given an ASCII string input_string, return an array of (member, | Given an ASCII string as input_string, return an array of (member, | |||
| parameters). input_string is modified to remove the parsed value. | parameters). input_string is modified to remove the parsed value. | |||
| 1. Let members be an empty array. | 1. Let members be an empty array. | |||
| 2. While input_string is not empty: | 2. While input_string is not empty: | |||
| 1. Let member be the result of running Parsing a Parameterized | 1. Let member be the result of running Parsing a Parameterized | |||
| Member from Text (Section 4.2.1.1) with input_string. | Member from Text (Section 4.2.1.1) with input_string. | |||
| 2. Append member to members. | 2. Append member to members. | |||
| skipping to change at page 19, line 45 ¶ | skipping to change at page 20, line 24 ¶ | |||
| 6. Discard any leading OWS from input_string. | 6. Discard any leading OWS from input_string. | |||
| 7. If input_string is empty, there is a trailing comma; fail | 7. If input_string is empty, there is a trailing comma; fail | |||
| parsing. | parsing. | |||
| 3. No structured data has been found; return members (which is | 3. No structured data has been found; return members (which is | |||
| empty). | empty). | |||
| 4.2.1.1. Parsing a Parameterized Member from Text | 4.2.1.1. Parsing a Parameterized Member from Text | |||
| Given an ASCII string input_string, return an token with an ordered | Given an ASCII string as input_string, return a member (either a list | |||
| map of parameters. input_string is modified to remove the parsed | of items, or a single item) with an ordered map of parameters. | |||
| value. | input_string is modified to remove the parsed value. | |||
| 1. If the first character of input_string is "(", let member be the | 1. If the first character of input_string is "(", let member be the | |||
| result of running Parsing an Inner List (Section 4.2.1.2) with | result of running Parsing an Inner List (Section 4.2.1.2) with | |||
| input_string. | input_string. | |||
| 2. Else, let member be the result of running Parsing an Item | 2. Else, let member be the result of running Parsing an Item | |||
| (Section 4.2.4) with input_string. | (Section 4.2.3) with input_string. | |||
| 3. Let parameters be an empty, ordered map. | 3. Let parameters be an empty, ordered map. | |||
| 4. In a loop: | 4. While input_string is not empty: | |||
| 1. Discard any leading OWS from input_string. | 1. Discard any leading OWS from input_string. | |||
| 2. If the first character of input_string is not ";", exit the | 2. If the first character of input_string is not ";", exit the | |||
| loop. | loop. | |||
| 3. Consume a ";" character from the beginning of input_string. | 3. Consume a ";" character from the beginning of input_string. | |||
| 4. Discard any leading OWS from input_string. | 4. Discard any leading OWS from input_string. | |||
| 5. let param_name be the result of Parsing a key from Text | 5. let param_name be the result of Parsing a key from Text | |||
| (Section 4.2.3) from input_string. | (Section 4.2.1.3) from input_string. | |||
| 6. If param_name is already present in parameters, there is a | 6. If param_name is already present in parameters, there is a | |||
| duplicate; fail parsing. | duplicate; fail parsing. | |||
| 7. Let param_value be a null value. | 7. Let param_value be a null value. | |||
| 8. If the first character of input_string is "=": | 8. If the first character of input_string is "=": | |||
| 1. Consume the "=" character at the beginning of | 1. Consume the "=" character at the beginning of | |||
| input_string. | input_string. | |||
| 2. Let param_value be the result of Parsing an Item from | 2. Let param_value be the result of Parsing an Item from | |||
| Text (Section 4.2.4) from input_string. | Text (Section 4.2.3) from input_string. | |||
| 9. Append key param_name with value param_value to parameters. | 9. Append key param_name with value param_value to parameters. | |||
| 5. Return the tuple (member, parameters). | 5. Return the tuple (member, parameters). | |||
| 4.2.1.2. Parsing an Inner List | 4.2.1.2. Parsing an Inner List | |||
| Given an ASCII string input_string, return an array of items. | Given an ASCII string as input_string, return an array of items. | |||
| input_string is modified to remove the parsed value. | input_string is modified to remove the parsed value. | |||
| 1. Consume the first character of input_string; if it is not "(", | 1. Consume the first character of input_string; if it is not "(", | |||
| fail parsing. | fail parsing. | |||
| 2. Let inner_list be an empty array. | 2. Let inner_list be an empty array. | |||
| 3. While input_string is not empty: | 3. While input_string is not empty: | |||
| 1. Discard any leading OWS from input_string. | 1. Discard any leading OWS from input_string. | |||
| 2. If the first character of input_string is ")": | 2. If the first character of input_string is ")": | |||
| 1. Consume the first character of input_string. | 1. Consume the first character of input_string. | |||
| 2. Return inner_list. | 2. Return inner_list. | |||
| 3. Let item be the result of running Parsing an Item from Text | 3. Let item be the result of running Parsing an Item from Text | |||
| (Section 4.2.4) with input_string. | (Section 4.2.3) with input_string. | |||
| 4. Append item to inner_list. | 4. Append item to inner_list. | |||
| 5. If the first character of input_string is not SP or ")", fail | 5. If the first character of input_string is not SP or ")", fail | |||
| parsing. | parsing. | |||
| 4. The end of the inner list was not found; fail parsing. | 4. The end of the inner list was not found; fail parsing. | |||
| 4.2.1.3. Parsing a Key from Text | ||||
| Given an ASCII string as input_string, return a key. input_string is | ||||
| modified to remove the parsed value. | ||||
| 1. If the first character of input_string is not lcalpha, fail | ||||
| parsing. | ||||
| 2. Let output_string be an empty string. | ||||
| 3. While input_string is not empty: | ||||
| 1. If the first character of input_string is not one of lcalpha, | ||||
| DIGIT, "*", "_", or "-", return output_string. | ||||
| 2. Let char be the result of removing the first character of | ||||
| input_string. | ||||
| 3. Append char to output_string. | ||||
| 4. Return output_string. | ||||
| 4.2.2. Parsing a Dictionary from Text | 4.2.2. Parsing a Dictionary from Text | |||
| Given an ASCII string input_string, return an ordered map of (key, | Given an ASCII string as input_string, return an ordered map of (key, | |||
| item). input_string is modified to remove the parsed value. | item). input_string is modified to remove the parsed value. | |||
| 1. Let dictionary be an empty, ordered map. | 1. Let dictionary be an empty, ordered map. | |||
| 2. While input_string is not empty: | 2. While input_string is not empty: | |||
| 1. Let this_key be the result of running Parsing a Key from | 1. Let this_key be the result of running Parsing a Key from | |||
| Text (Section 4.2.3) with input_string. | Text (Section 4.2.1.3) with input_string. | |||
| 2. If dictionary already contains the name this_key, there is a | 2. If dictionary already contains the name this_key, there is a | |||
| duplicate; fail parsing. | duplicate; fail parsing. | |||
| 3. Consume the first character of input_string; if it is not | 3. Consume the first character of input_string; if it is not | |||
| "=", fail parsing. | "=", fail parsing. | |||
| 4. Let member be the result of running Parsing a Parameterized | 4. Let member be the result of running Parsing a Parameterized | |||
| Member from Text (Section 4.2.1.1) with input_string. | Member from Text (Section 4.2.1.1) with input_string. | |||
| skipping to change at page 22, line 13 ¶ | skipping to change at page 23, line 16 ¶ | |||
| COMMA, fail parsing. | COMMA, fail parsing. | |||
| 9. Discard any leading OWS from input_string. | 9. Discard any leading OWS from input_string. | |||
| 10. If input_string is empty, there is a trailing comma; fail | 10. If input_string is empty, there is a trailing comma; fail | |||
| parsing. | parsing. | |||
| 3. No structured data has been found; return dictionary (which is | 3. No structured data has been found; return dictionary (which is | |||
| empty). | empty). | |||
| 4.2.3. Parsing a Key from Text | 4.2.3. Parsing an Item from Text | |||
| Given an ASCII string input_string, return a key. input_string is | ||||
| modified to remove the parsed value. | ||||
| 1. If the first character of input_string is not lcalpha, fail | ||||
| parsing. | ||||
| 2. Let output_string be an empty string. | ||||
| 3. While input_string is not empty: | ||||
| 1. Let char be the result of removing the first character of | ||||
| input_string. | ||||
| 2. If char is not one of lcalpha, DIGIT, "*", "_", or "-": | ||||
| 1. Prepend char to input_string. | ||||
| 2. Return output_string. | ||||
| 3. Append char to output_string. | ||||
| 4. Return output_string. | ||||
| 4.2.4. Parsing an Item from Text | ||||
| Given an ASCII string input_string, return an item. input_string is | Given an ASCII string as input_string, return an item. input_string | |||
| modified to remove the parsed value. | is modified to remove the parsed value. | |||
| 1. If the first character of input_string is a "-" or a DIGIT, | 1. If the first character of input_string is a "-" or a DIGIT, | |||
| process input_string as a number (Section 4.2.5) and return the | process input_string as a number (Section 4.2.4) and return the | |||
| result. | result. | |||
| 2. If the first character of input_string is a DQUOTE, process | 2. If the first character of input_string is a DQUOTE, process | |||
| input_string as a string (Section 4.2.6) and return the result. | input_string as a string (Section 4.2.5) and return the result. | |||
| 3. If the first character of input_string is "*", process | 3. If the first character of input_string is "*", process | |||
| input_string as a byte sequence (Section 4.2.8) and return the | input_string as a byte sequence (Section 4.2.7) and return the | |||
| result. | result. | |||
| 4. If the first character of input_string is "?", process | 4. If the first character of input_string is "?", process | |||
| input_string as a Boolean (Section 4.2.9) and return the result. | input_string as a Boolean (Section 4.2.8) and return the result. | |||
| 5. If the first character of input_string is an ALPHA, process | 5. If the first character of input_string is an ALPHA, process | |||
| input_string as a token (Section 4.2.7) and return the result. | input_string as a token (Section 4.2.6) and return the result. | |||
| 6. Otherwise, the item type is unrecognized; fail parsing. | 6. Otherwise, the item type is unrecognized; fail parsing. | |||
| 4.2.5. Parsing a Number from Text | 4.2.4. Parsing a Number from Text | |||
| Given an ASCII string input_string, return a number. input_string is | Given an ASCII string as input_string, return a number. input_string | |||
| modified to remove the parsed value. | is modified to remove the parsed value. | |||
| NOTE: This algorithm parses both Integers (Section 3.4) and Floats | NOTE: This algorithm parses both Integers (Section 3.4) and Floats | |||
| (Section 3.5), and returns the corresponding structure. | (Section 3.5), and returns the corresponding structure. | |||
| 1. Let type be "integer". | 1. Let type be "integer". | |||
| 2. Let sign be 1. | 2. Let sign be 1. | |||
| 3. Let input_number be an empty string. | 3. Let input_number be an empty string. | |||
| skipping to change at page 24, line 25 ¶ | skipping to change at page 25, line 5 ¶ | |||
| 1. If the final character of input_number is ".", fail parsing. | 1. If the final character of input_number is ".", fail parsing. | |||
| 2. If the number of characters after "." in input_number is | 2. If the number of characters after "." in input_number is | |||
| greater than six, fail parsing. | greater than six, fail parsing. | |||
| 3. Parse input_number as a float and let output_number be the | 3. Parse input_number as a float and let output_number be the | |||
| product of the result and sign. | product of the result and sign. | |||
| 10. Return output_number. | 10. Return output_number. | |||
| 4.2.6. Parsing a String from Text | 4.2.5. Parsing a String from Text | |||
| Given an ASCII string input_string, return an unquoted string. | Given an ASCII string as input_string, return an unquoted string. | |||
| input_string is modified to remove the parsed value. | input_string is modified to remove the parsed value. | |||
| 1. Let output_string be an empty string. | 1. Let output_string be an empty string. | |||
| 2. If the first character of input_string is not DQUOTE, fail | 2. If the first character of input_string is not DQUOTE, fail | |||
| parsing. | parsing. | |||
| 3. Discard the first character of input_string. | 3. Discard the first character of input_string. | |||
| 4. While input_string is not empty: | 4. While input_string is not empty: | |||
| 1. Let char be the result of consuming the first character of | 1. Let char be the result of consuming the first character of | |||
| input_string. | input_string. | |||
| 2. If char is a backslash ("\"): | 2. If char is a backslash ("\"): | |||
| 1. If input_string is now empty, fail parsing. | 1. If input_string is now empty, fail parsing. | |||
| 2. Else: | 2. Let next_char be the result of consuming the first | |||
| character of input_string. | ||||
| 1. Let next_char be the result of consuming the first | ||||
| character of input_string. | ||||
| 2. If next_char is not DQUOTE or "\", fail parsing. | 3. If next_char is not DQUOTE or "\", fail parsing. | |||
| 3. Append next_char to output_string. | 4. Append next_char to output_string. | |||
| 3. Else, if char is DQUOTE, return output_string. | 3. Else, if char is DQUOTE, return output_string. | |||
| 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not | 4. Else, if char is in the range %x00-1f or %x7f (i.e., is not | |||
| in VCHAR or SP), fail parsing. | in VCHAR or SP), fail parsing. | |||
| 5. Else, append char to output_string. | 5. Else, append char to output_string. | |||
| 5. Reached the end of input_string without finding a closing DQUOTE; | 5. Reached the end of input_string without finding a closing DQUOTE; | |||
| fail parsing. | fail parsing. | |||
| 4.2.7. Parsing a Token from Text | 4.2.6. Parsing a Token from Text | |||
| Given an ASCII string input_string, return a token. input_string is | Given an ASCII string as input_string, return a token. input_string | |||
| modified to remove the parsed value. | is modified to remove the parsed value. | |||
| 1. If the first character of input_string is not ALPHA, fail | 1. If the first character of input_string is not ALPHA, fail | |||
| parsing. | parsing. | |||
| 2. Let output_string be an empty string. | 2. Let output_string be an empty string. | |||
| 3. While input_string is not empty: | 3. While input_string is not empty: | |||
| 1. Let char be the result of consuming the first character of | 1. If the first character of input_string is not one of ALPHA, | |||
| input_string. | DIGIT, "_", "-", ".", ":", "%", "*" or "/", return | |||
| output_string. | ||||
| 2. If char is not one of ALPHA, DIGIT, "_", "-", ".", ":", "%", | ||||
| "*" or "/": | ||||
| 1. Prepend char to input_string. | ||||
| 2. Return output_string. | 2. Let char be the result of consuming the first character of | |||
| input_string. | ||||
| 3. Append char to output_string. | 3. Append char to output_string. | |||
| 4. Return output_string. | 4. Return output_string. | |||
| 4.2.8. Parsing a Byte Sequence from Text | 4.2.7. Parsing a Byte Sequence from Text | |||
| Given an ASCII string input_string, return a byte sequence. | Given an ASCII string as input_string, return a byte sequence. | |||
| input_string is modified to remove the parsed value. | input_string is modified to remove the parsed value. | |||
| 1. If the first character of input_string is not "*", fail parsing. | 1. If the first character of input_string is not "*", fail parsing. | |||
| 2. Discard the first character of input_string. | 2. Discard the first character of input_string. | |||
| 3. If there is not a "*" character before the end of input_string, | 3. If there is not a "*" character before the end of input_string, | |||
| fail parsing. | fail parsing. | |||
| 4. Let b64_content be the result of consuming content of | 4. Let b64_content be the result of consuming content of | |||
| skipping to change at page 26, line 37 ¶ | skipping to change at page 27, line 11 ¶ | |||
| Because some implementations of base64 do not allow rejection of | Because some implementations of base64 do not allow rejection of | |||
| encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), | encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), | |||
| parsers SHOULD NOT fail when it is present, unless they cannot be | parsers SHOULD NOT fail when it is present, unless they cannot be | |||
| configured to do so. | configured to do so. | |||
| This specification does not relax the requirements in [RFC4648], | This specification does not relax the requirements in [RFC4648], | |||
| Section 3.1 and 3.3; therefore, parsers MUST fail on characters | Section 3.1 and 3.3; therefore, parsers MUST fail on characters | |||
| outside the base64 alphabet, and on line feeds in encoded data. | outside the base64 alphabet, and on line feeds in encoded data. | |||
| 4.2.9. Parsing a Boolean from Text | 4.2.8. Parsing a Boolean from Text | |||
| Given an ASCII string input_string, return a Boolean. input_string is | Given an ASCII string as input_string, return a Boolean. input_string | |||
| modified to remove the parsed value. | is modified to remove the parsed value. | |||
| 1. If the first character of input_string is not "?", fail parsing. | 1. If the first character of input_string is not "?", fail parsing. | |||
| 2. Discard the first character of input_string. | 2. Discard the first character of input_string. | |||
| 3. If the first character of input_string matches "1", discard the | 3. If the first character of input_string matches "1", discard the | |||
| first character, and return true. | first character, and return true. | |||
| 4. If the first character of input_string matches "0", discard the | 4. If the first character of input_string matches "0", discard the | |||
| first character, and return false. | first character, and return false. | |||
| skipping to change at page 30, line 40 ¶ | skipping to change at page 31, line 14 ¶ | |||
| Appendix C. Implementation Notes | Appendix C. Implementation Notes | |||
| A generic implementation of this specification should expose the top- | A generic implementation of this specification should expose the top- | |||
| level parse (Section 4.2) and serialize (Section 4.1) functions. | level parse (Section 4.2) and serialize (Section 4.1) functions. | |||
| They need not be functions; for example, it could be implemented as | They need not be functions; for example, it could be implemented as | |||
| an object, with methods for each of the different top-level types. | an object, with methods for each of the different top-level types. | |||
| For interoperability, it's important that generic implementations be | For interoperability, it's important that generic implementations be | |||
| complete and follow the algorithms closely; see Section 1.1. To aid | complete and follow the algorithms closely; see Section 1.1. To aid | |||
| this, a common test suite is being maintained by the community; see | this, a common test suite is being maintained by the community at | |||
| https://github.com/httpwg/structured-header-tests [7]. | https://github.com/httpwg/structured-header-tests [7]. | |||
| Implementers should note that dictionaries and parameters are order- | Implementers should note that dictionaries and parameters are order- | |||
| preserving maps. Some headers may not convey meaning in the ordering | preserving maps. Some headers may not convey meaning in the ordering | |||
| of these data types, but it should still be exposed so that | of these data types, but it should still be exposed so that | |||
| applications which need to use it will have it available. | applications which need to use it will have it available. | |||
| Likewise, implementations should note that it's important to preserve | Likewise, implementations should note that it's important to preserve | |||
| the distinction between tokens and strings. While most programming | the distinction between tokens and strings. While most programming | |||
| languages have native types that map to the other types well, it may | languages have native types that map to the other types well, it may | |||
| be necessary to create a wrapper "token" object or use a parameter on | be necessary to create a wrapper "token" object or use a parameter on | |||
| functions to assure that these types remain separate. | functions to assure that these types remain separate. | |||
| Appendix D. Changes | Appendix D. Changes | |||
| _RFC Editor: Please remove this section before publication._ | _RFC Editor: Please remove this section before publication._ | |||
| D.1. Since draft-ietf-httpbis-header-structure-11 | D.1. Since draft-ietf-httpbis-header-structure-12 | |||
| o Editorial improvements. | ||||
| o Reworked float serialisation (#896). | ||||
| D.2. Since draft-ietf-httpbis-header-structure-11 | ||||
| o Allow * in key (#844). | o Allow * in key (#844). | |||
| o Constrain floats to six digits of precision (#848). | o Constrain floats to six digits of precision (#848). | |||
| o Allow dictionary members to have parameters (#842). | o Allow dictionary members to have parameters (#842). | |||
| D.2. Since draft-ietf-httpbis-header-structure-10 | D.3. Since draft-ietf-httpbis-header-structure-10 | |||
| o Update abstract (#799). | o Update abstract (#799). | |||
| o Input and output are now arrays of bytes (#662). | o Input and output are now arrays of bytes (#662). | |||
| o Implementations need to preserve difference between token and | o Implementations need to preserve difference between token and | |||
| string (#790). | string (#790). | |||
| o Allow empty dictionaries and lists (#781). | o Allow empty dictionaries and lists (#781). | |||
| o Change parameterized lists to have primary items (#797). | o Change parameterized lists to have primary items (#797). | |||
| o Allow inner lists in both dictionaries and lists; removes lists of | o Allow inner lists in both dictionaries and lists; removes lists of | |||
| lists (#816). | lists (#816). | |||
| o Subsume Parameterised Lists into Lists (#839). | o Subsume Parameterised Lists into Lists (#839). | |||
| D.3. Since draft-ietf-httpbis-header-structure-09 | D.4. Since draft-ietf-httpbis-header-structure-09 | |||
| o Changed Boolean from T/F to 1/0 (#784). | o Changed Boolean from T/F to 1/0 (#784). | |||
| o Parameters are now ordered maps (#765). | o Parameters are now ordered maps (#765). | |||
| o Clamp integers to 15 digits (#737). | o Clamp integers to 15 digits (#737). | |||
| D.4. Since draft-ietf-httpbis-header-structure-08 | D.5. Since draft-ietf-httpbis-header-structure-08 | |||
| o Disallow whitespace before items properly (#703). | o Disallow whitespace before items properly (#703). | |||
| o Created "key" for use in dictionaries and parameters, rather than | o Created "key" for use in dictionaries and parameters, rather than | |||
| relying on identifier (#702). Identifiers have a separate minimum | relying on identifier (#702). Identifiers have a separate minimum | |||
| supported size. | supported size. | |||
| o Expanded the range of special characters allowed in identifier to | o Expanded the range of special characters allowed in identifier to | |||
| include all of ALPHA, ".", ":", and "%" (#702). | include all of ALPHA, ".", ":", and "%" (#702). | |||
| skipping to change at page 32, line 18 ¶ | skipping to change at page 33, line 5 ¶ | |||
| o Gave better names for referring specs to use in Parameterised | o Gave better names for referring specs to use in Parameterised | |||
| Lists (#720). | Lists (#720). | |||
| o Added Lists of Lists (#721). | o Added Lists of Lists (#721). | |||
| o Rename Identifier to Token (#725). | o Rename Identifier to Token (#725). | |||
| o Add implementation guidance (#727). | o Add implementation guidance (#727). | |||
| D.5. Since draft-ietf-httpbis-header-structure-07 | D.6. Since draft-ietf-httpbis-header-structure-07 | |||
| o Make Dictionaries ordered mappings (#659). | o Make Dictionaries ordered mappings (#659). | |||
| o Changed "binary content" to "byte sequence" to align with Infra | o Changed "binary content" to "byte sequence" to align with Infra | |||
| specification (#671). | specification (#671). | |||
| o Changed "mapping" to "map" for #671. | o Changed "mapping" to "map" for #671. | |||
| o Don't fail if byte sequences aren't "=" padded (#658). | o Don't fail if byte sequences aren't "=" padded (#658). | |||
| o Add Booleans (#683). | o Add Booleans (#683). | |||
| o Allow identifiers in items again (#629). | o Allow identifiers in items again (#629). | |||
| o Disallowed whitespace before items (#703). | o Disallowed whitespace before items (#703). | |||
| o Explain the consequences of splitting a string across multiple | o Explain the consequences of splitting a string across multiple | |||
| headers (#686). | headers (#686). | |||
| D.6. Since draft-ietf-httpbis-header-structure-06 | D.7. Since draft-ietf-httpbis-header-structure-06 | |||
| o Add a FAQ. | o Add a FAQ. | |||
| o Allow non-zero pad bits. | o Allow non-zero pad bits. | |||
| o Explicitly check for integers that violate constraints. | o Explicitly check for integers that violate constraints. | |||
| D.7. Since draft-ietf-httpbis-header-structure-05 | D.8. Since draft-ietf-httpbis-header-structure-05 | |||
| o Reorganise specification to separate parsing out. | o Reorganise specification to separate parsing out. | |||
| o Allow referencing specs to use ABNF. | o Allow referencing specs to use ABNF. | |||
| o Define serialisation algorithms. | o Define serialisation algorithms. | |||
| o Refine relationship between ABNF, parsing and serialisation | o Refine relationship between ABNF, parsing and serialisation | |||
| algorithms. | algorithms. | |||
| D.8. Since draft-ietf-httpbis-header-structure-04 | D.9. Since draft-ietf-httpbis-header-structure-04 | |||
| o Remove identifiers from item. | o Remove identifiers from item. | |||
| o Remove most limits on sizes. | o Remove most limits on sizes. | |||
| o Refine number parsing. | o Refine number parsing. | |||
| D.9. Since draft-ietf-httpbis-header-structure-03 | D.10. Since draft-ietf-httpbis-header-structure-03 | |||
| o Strengthen language around failure handling. | o Strengthen language around failure handling. | |||
| D.10. Since draft-ietf-httpbis-header-structure-02 | D.11. Since draft-ietf-httpbis-header-structure-02 | |||
| o Split Numbers into Integers and Floats. | o Split Numbers into Integers and Floats. | |||
| o Define number parsing. | o Define number parsing. | |||
| o Tighten up binary parsing and give it an explicit end delimiter. | o Tighten up binary parsing and give it an explicit end delimiter. | |||
| o Clarify that mappings are unordered. | o Clarify that mappings are unordered. | |||
| o Allow zero-length strings. | o Allow zero-length strings. | |||
| o Improve string parsing algorithm. | o Improve string parsing algorithm. | |||
| o Improve limits in algorithms. | o Improve limits in algorithms. | |||
| o Require parsers to combine header fields before processing. | o Require parsers to combine header fields before processing. | |||
| o Throw an error on trailing garbage. | o Throw an error on trailing garbage. | |||
| D.11. Since draft-ietf-httpbis-header-structure-01 | D.12. Since draft-ietf-httpbis-header-structure-01 | |||
| o Replaced with draft-nottingham-structured-headers. | o Replaced with draft-nottingham-structured-headers. | |||
| D.12. Since draft-ietf-httpbis-header-structure-00 | D.13. Since draft-ietf-httpbis-header-structure-00 | |||
| o Added signed 64bit integer type. | o Added signed 64bit integer type. | |||
| o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- | o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- | |||
| unicode-string. | unicode-string. | |||
| o Change h1_blob delimiter to ":" since "'" is valid t_char | o Change h1_blob delimiter to ":" since "'" is valid t_char | |||
| Authors' Addresses | Authors' Addresses | |||
| End of changes. 117 change blocks. | ||||
| 201 lines changed or deleted | 227 lines changed or added | |||
This html diff was produced by rfcdiff 1.45. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||