| draft-ietf-httpbis-header-structure-14.txt | draft-ietf-httpbis-header-structure-15.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: May 2, 2020 The Varnish Cache Project | Expires: July 31, 2020 The Varnish Cache Project | |||
| October 30, 2019 | January 28, 2020 | |||
| Structured Headers for HTTP | Structured Headers for HTTP | |||
| draft-ietf-httpbis-header-structure-14 | draft-ietf-httpbis-header-structure-15 | |||
| 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 May 2, 2020. | This Internet-Draft will expire on July 31, 2020. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2019 IETF Trust and the persons identified as the | Copyright (c) 2020 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 | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| 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 . . . . . . . . . . . . . . . . . 5 | |||
| 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 | 2. Defining New Structured Headers . . . . . . . . . . . . . . . 5 | |||
| 3. Structured Data Types . . . . . . . . . . . . . . . . . . . . 7 | 3. Structured Data Types . . . . . . . . . . . . . . . . . . . . 7 | |||
| 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 9 | 3.1.1. Inner Lists . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 10 | 3.1.2. Parameters . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 4. Working With Structured Headers in HTTP Headers . . . . . . . 13 | 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.1. Serializing Structured Headers . . . . . . . . . . . . . 13 | 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 4.2. Parsing Header Fields into Structured Headers . . . . . . 20 | 3.3.1. Integers . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 | 3.3.2. Decimals . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 6. Security Considerations . . . . . . . . . . . . . . . . . . . 30 | 3.3.3. Strings . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 30 | 3.3.4. Tokens . . . . . . . . . . . . . . . . . . . . . . . 13 | |||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 30 | 3.3.5. Byte Sequences . . . . . . . . . . . . . . . . . . . 13 | |||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 31 | 3.3.6. Booleans . . . . . . . . . . . . . . . . . . . . . . 14 | |||
| 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 31 | 4. Working With Structured Headers in HTTP Headers . . . . . . . 14 | |||
| Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 32 | 4.1. Serializing Structured Headers . . . . . . . . . . . . . 14 | |||
| Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 32 | 4.1.1. Serializing a List . . . . . . . . . . . . . . . . . 15 | |||
| B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 32 | 4.1.2. Serializing a Dictionary . . . . . . . . . . . . . . 17 | |||
| B.2. Structured Headers don't "fit" my data. . . . . . . . . . 33 | 4.1.3. Serializing an Item . . . . . . . . . . . . . . . . . 17 | |||
| Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 33 | 4.1.4. Serializing an Integer . . . . . . . . . . . . . . . 18 | |||
| Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 34 | 4.1.5. Serializing a Decimal . . . . . . . . . . . . . . . . 19 | |||
| D.1. Since draft-ietf-httpbis-header-structure-13 . . . . . . 34 | 4.1.6. Serializing a String . . . . . . . . . . . . . . . . 19 | |||
| D.2. Since draft-ietf-httpbis-header-structure-12 . . . . . . 34 | 4.1.7. Serializing a Token . . . . . . . . . . . . . . . . . 20 | |||
| D.3. Since draft-ietf-httpbis-header-structure-11 . . . . . . 34 | 4.1.8. Serializing a Byte Sequence . . . . . . . . . . . . . 20 | |||
| D.4. Since draft-ietf-httpbis-header-structure-10 . . . . . . 34 | 4.1.9. Serializing a Boolean . . . . . . . . . . . . . . . . 21 | |||
| D.5. Since draft-ietf-httpbis-header-structure-09 . . . . . . 35 | 4.2. Parsing Header Fields into Structured Headers . . . . . . 21 | |||
| D.6. Since draft-ietf-httpbis-header-structure-08 . . . . . . 35 | 4.2.1. Parsing a List . . . . . . . . . . . . . . . . . . . 22 | |||
| D.7. Since draft-ietf-httpbis-header-structure-07 . . . . . . 35 | 4.2.2. Parsing a Dictionary . . . . . . . . . . . . . . . . 24 | |||
| D.8. Since draft-ietf-httpbis-header-structure-06 . . . . . . 36 | 4.2.3. Parsing an Item . . . . . . . . . . . . . . . . . . . 25 | |||
| D.9. Since draft-ietf-httpbis-header-structure-05 . . . . . . 36 | 4.2.4. Parsing a Number . . . . . . . . . . . . . . . . . . 27 | |||
| D.10. Since draft-ietf-httpbis-header-structure-04 . . . . . . 36 | 4.2.5. Parsing a String . . . . . . . . . . . . . . . . . . 28 | |||
| D.11. Since draft-ietf-httpbis-header-structure-03 . . . . . . 36 | 4.2.6. Parsing a Token . . . . . . . . . . . . . . . . . . . 29 | |||
| D.12. Since draft-ietf-httpbis-header-structure-02 . . . . . . 36 | 4.2.7. Parsing a Byte Sequence . . . . . . . . . . . . . . . 29 | |||
| D.13. Since draft-ietf-httpbis-header-structure-01 . . . . . . 37 | 4.2.8. Parsing a Boolean . . . . . . . . . . . . . . . . . . 30 | |||
| D.14. Since draft-ietf-httpbis-header-structure-00 . . . . . . 37 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 31 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 37 | 6. Security Considerations . . . . . . . . . . . . . . . . . . . 31 | |||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 31 | ||||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 31 | ||||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 32 | ||||
| 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 32 | ||||
| Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 33 | ||||
| Appendix B. Frequently Asked Questions . . . . . . . . . . . . . 33 | ||||
| B.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 33 | ||||
| B.2. Structured Headers don't "fit" my data. . . . . . . . . . 34 | ||||
| Appendix C. Implementation Notes . . . . . . . . . . . . . . . . 34 | ||||
| Appendix D. Changes . . . . . . . . . . . . . . . . . . . . . . 35 | ||||
| D.1. Since draft-ietf-httpbis-header-structure-14 . . . . . . 35 | ||||
| D.2. Since draft-ietf-httpbis-header-structure-13 . . . . . . 35 | ||||
| D.3. Since draft-ietf-httpbis-header-structure-12 . . . . . . 36 | ||||
| D.4. Since draft-ietf-httpbis-header-structure-11 . . . . . . 36 | ||||
| D.5. Since draft-ietf-httpbis-header-structure-10 . . . . . . 36 | ||||
| D.6. Since draft-ietf-httpbis-header-structure-09 . . . . . . 36 | ||||
| D.7. Since draft-ietf-httpbis-header-structure-08 . . . . . . 37 | ||||
| D.8. Since draft-ietf-httpbis-header-structure-07 . . . . . . 37 | ||||
| D.9. Since draft-ietf-httpbis-header-structure-06 . . . . . . 38 | ||||
| D.10. Since draft-ietf-httpbis-header-structure-05 . . . . . . 38 | ||||
| D.11. Since draft-ietf-httpbis-header-structure-04 . . . . . . 38 | ||||
| D.12. Since draft-ietf-httpbis-header-structure-03 . . . . . . 38 | ||||
| D.13. Since draft-ietf-httpbis-header-structure-02 . . . . . . 38 | ||||
| D.14. Since draft-ietf-httpbis-header-structure-01 . . . . . . 39 | ||||
| D.15. Since draft-ietf-httpbis-header-structure-00 . . . . . . 39 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 39 | ||||
| 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 Section 8.3.1 of [RFC7231], 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 | |||
| skipping to change at page 4, line 43 ¶ | skipping to change at page 5, line 22 ¶ | |||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
| "OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in BCP | |||
| 14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
| capitals, as shown here. | capitals, as shown here. | |||
| This document uses algorithms to specify parsing and serialisation | This document uses algorithms to specify parsing and serialisation | |||
| behaviours, and the Augmented Backus-Naur Form (ABNF) notation of | behaviours, and the Augmented Backus-Naur Form (ABNF) notation of | |||
| [RFC5234] to illustrate expected syntax in HTTP header fields. In | [RFC5234] to illustrate expected syntax in HTTP header fields. In | |||
| doing so, uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE rules from | doing so, uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE rules from | |||
| [RFC5234]. It also includes the OWS and tchar rules from [RFC7230]. | [RFC5234]. It also includes the tchar rule from [RFC7230]. | |||
| When parsing from HTTP header fields, implementations MUST follow the | When parsing from HTTP header fields, implementations MUST follow the | |||
| algorithms, but MAY vary in implementation so as the behaviours are | algorithms, but MAY vary in implementation so as the behaviours are | |||
| indistinguishable from specified behaviour. If there is disagreement | indistinguishable from specified behaviour. If there is disagreement | |||
| between the parsing algorithms and ABNF, the specified algorithms | between the parsing algorithms and ABNF, the specified algorithms | |||
| take precedence. In some places, the algorithms are "greedy" with | take precedence. In some places, the algorithms are "greedy" with | |||
| whitespace, but this should not affect conformance. | whitespace, but this should not affect conformance. | |||
| For serialisation to header fields, the ABNF illustrates the range of | For serialisation to header fields, the ABNF illustrates the range of | |||
| acceptable wire representations with as much fidelity as possible, | acceptable wire representations with as much fidelity as possible, | |||
| skipping to change at page 5, line 33 ¶ | skipping to change at page 6, line 10 ¶ | |||
| o Define the semantics of those structures. | o Define the semantics of those structures. | |||
| o Specify any additional constraints upon the structures used, as | o Specify any additional constraints upon the structures used, as | |||
| well as the consequences when those constraints are violated. | well as the consequences when those constraints are violated. | |||
| Typically, this means that a header definition will specify the top- | Typically, this means that a header definition will specify the top- | |||
| level type - Dictionary, List or Item - and then define its allowable | level type - Dictionary, List or Item - and then define its allowable | |||
| types, and constraints upon them. For example, a header defined as a | types, and constraints upon them. For example, a header defined as a | |||
| List might have all Integer members, or a mix of types; a header | List might have all Integer members, or a mix of types; a header | |||
| defined as an Item might allow only Strings, and additionally only | defined as an Item might allow only Strings, and additionally only | |||
| strings beginning with the letter "Q". | strings beginning with the letter "Q". Likewise, inner lists are | |||
| only valid when a header definition explicitly allows them. | ||||
| When Structured Headers parsing fails, the header is ignored (see | When Structured Headers parsing fails, the header is ignored (see | |||
| Section 4.2); in most situations, violating header-specific | Section 4.2); in most situations, violating header-specific | |||
| constraints should have the same effect. Thus, if a header is | constraints should have the same effect. Thus, if a header is | |||
| defined as an Item and required to be an Integer, but a String is | defined as an Item and required to be an Integer, but a String is | |||
| received, it will by default be ignored. If the header requires | received, it will by default be ignored. If the header requires | |||
| different error handling, this should be explicitly specified. | different error handling, this should be explicitly specified. | |||
| However, both Items and Inner Lists allow parameters as an | However, both items and inner lists allow parameters as an | |||
| extensibility mechanism; this means that values can later be extended | extensibility mechanism; this means that values can later be extended | |||
| to accommodate more information, if need be. As a result, header | to accommodate more information, if need be. As a result, header | |||
| specifications are discouraged from defining the presence of an | specifications are discouraged from defining the presence of an | |||
| unrecognised parameter as an error condition. | unrecognised parameter as an error condition. | |||
| Conversely, inner lists are only valid when a header definition | To help assure that this extensibility is available in the future, | |||
| explicitly allows them. | and to encourage consumers to use a fully capable Structured Headers | |||
| parser, a header definition can specify that "grease" parameters be | ||||
| added by senders. For example, a specification could stipulate that | ||||
| all parameters beginning with the letter 'q' are reserved for this | ||||
| use. | ||||
| 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 decimals, the format of | |||
| strings and tokens, the types allowed in a dictionary's values, or | strings and tokens, the types allowed in a dictionary's values, or | |||
| the number of items in a list). Likewise, header field definitions | the number of items in a list). Likewise, header field definitions | |||
| can only use Structured Headers for the entire header field value, | can only use Structured Headers for the entire header field value, | |||
| not a portion thereof. | 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, | |||
| skipping to change at page 7, line 32 ¶ | skipping to change at page 7, line 37 ¶ | |||
| for the message. See below for processing requirements. | for the message. See below for processing requirements. | |||
| "fooUrl" contains a URI-reference (Section 4.1 of | "fooUrl" contains a URI-reference (Section 4.1 of | |||
| [RFC3986], Section 4.1). If its value is not a valid URI-reference, | [RFC3986], Section 4.1). If its value is not a valid URI-reference, | |||
| that URL MUST be ignored. If its value is a relative reference | that URL MUST be ignored. If its value is a relative reference | |||
| (Section 4.2 of [RFC3986]), it MUST be resolved (Section 5 of | (Section 4.2 of [RFC3986]), it MUST be resolved (Section 5 of | |||
| [RFC3986]) before being used. | [RFC3986]) before being used. | |||
| For example: | For example: | |||
| Foo-Example: 2; fooUrl="https://foo.example.com/" | Foo-Example: 2; foourl="https://foo.example.com/" | |||
| 3. Structured Data Types | 3. Structured 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 headers. | format in HTTP headers. | |||
| In summary: | In summary: | |||
| o There are three top-level types that a HTTP header can be defined | o There are three top-level types that a HTTP header can be defined | |||
| skipping to change at page 8, line 13 ¶ | skipping to change at page 8, line 16 ¶ | |||
| pairs. | pairs. | |||
| 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 (Section 3.1.1), both of which | item (Section 3.3) or an inner list (Section 3.1.1), both of which | |||
| can be parameterised (Section 3.1.2). | can be parameterised (Section 3.1.2). | |||
| The ABNF for lists in HTTP headers is: | The ABNF for lists in HTTP headers is: | |||
| sh-list = list-member *( OWS "," OWS list-member ) | sh-list = list-member *( *SP "," *SP list-member ) | |||
| list-member = sh-item / inner-list | list-member = sh-item / inner-list | |||
| In HTTP headers, each member is separated by a comma and optional | In HTTP headers, each member is separated by a comma and optional | |||
| whitespace. For example, a header field whose value is defined as a | whitespace. For example, a header field whose value is defined as a | |||
| list of strings could look like: | list of strings could look like: | |||
| Example-StrListHeader: "foo", "bar", "It was the best of times." | Example-StrListHeader: "foo", "bar", "It was the best of times." | |||
| In HTTP headers, an empty list is denoted by not serialising the | In HTTP headers, an empty list is denoted by not serialising the | |||
| header at all. | header at all. | |||
| Note that lists can have their members split across multiple | ||||
| instances inside a block of fields; for example, the following are | ||||
| equivalent: | ||||
| Example-Hdr: foo, bar | ||||
| and | ||||
| Example-Hdr: foo | ||||
| Example-Hdr: bar | ||||
| However, members of a list cannot be safely split between instances; | ||||
| see Section 4.2 for details. | ||||
| Parsers MUST support lists containing at least 1024 members. Header | Parsers MUST support lists containing at least 1024 members. Header | |||
| specifications can constrain the types and cardinality of individual | specifications can constrain the types and cardinality of individual | |||
| list values as they require. | list values as they require. | |||
| 3.1.1. Inner Lists | 3.1.1. Inner Lists | |||
| An inner list is an array of zero or more items (Section 3.3). Both | An inner list is an array of zero or more items (Section 3.3). Both | |||
| the individual items and the inner-list itself can be parameterised | the individual items and the inner-list itself can be parameterised | |||
| (Section 3.1.2). | (Section 3.1.2). | |||
| The ABNF for inner-lists in HTTP headers is: | The ABNF for inner-lists in HTTP headers is: | |||
| inner-list = "(" OWS [ sh-item *( SP OWS sh-item ) OWS ] ")" | inner-list = "(" *SP [ sh-item *( 1*SP sh-item ) *SP ] ")" | |||
| *parameter | *parameter | |||
| In HTTP headers, inner lists are denoted by surrounding parenthesis, | In HTTP headers, inner lists are denoted by surrounding parenthesis, | |||
| and have their values delimited by a single space. A header field | and have their values delimited by a single space. A header field | |||
| whose value is defined as a list of inner-lists of strings could look | whose value is defined as a list of inner-lists of strings could look | |||
| like: | 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. | |||
| A header field whose value is defined as a list of inner-lists with | A header field whose value is defined as a list of inner-lists with | |||
| parameters at both levels could look like: | parameters at both levels could look like: | |||
| Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar", "baz");lvl=1 | Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | |||
| Parsers MUST support inner-lists containing at least 256 members. | Parsers MUST support inner-lists containing at least 256 members. | |||
| Header specifications can constrain the types and cardinality of | Header specifications can constrain the types and cardinality of | |||
| individual inner-list members as they require. | individual inner-list members as they require. | |||
| 3.1.2. Parameters | 3.1.2. Parameters | |||
| Parameters are an ordered map of key-values pairs that are associated | Parameters are an ordered map of key-values pairs that are associated | |||
| with an item (Section 3.3) or inner-list (Section 3.1.1). The keys | with an item (Section 3.3) or inner-list (Section 3.1.1). The keys | |||
| are required to be unique within the scope of a map of parameters, | are unique within the scope of a map of parameters, and the values | |||
| and the values are bare items (i.e., they themselves cannot be | are bare items (i.e., they themselves cannot be parameterised; see | |||
| parameterised; see Section 3.3). | Section 3.3). | |||
| The ABNF for parameters in HTTP headers is: | The ABNF for parameters in HTTP headers is: | |||
| parameter = ";" OWS param-name [ "=" param-value ] | parameter = ";" *SP param-name [ "=" param-value ] | |||
| param-name = key | param-name = key | |||
| key = lcalpha *( lcalpha / DIGIT / "_" / "-" / "*" ) | key = lcalpha *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) | |||
| lcalpha = %x61-7A ; a-z | lcalpha = %x61-7A ; a-z | |||
| param-value = bare-item | param-value = bare-item | |||
| In HTTP headers, parameters are separated from their item or inner- | In HTTP headers, parameters are separated from their item or inner- | |||
| list and each other by semicolons. For example: | list and each other by semicolons. For example: | |||
| Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | |||
| Parameters whose value is Boolean true MUST omit that value when | ||||
| serialised. For example: | ||||
| Example-IntHeader: 1; a; b=?0 | ||||
| Note that this requirement is only on serialisation; parsers are | ||||
| still required to correctly handle the true value when it appears in | ||||
| parameters. | ||||
| Parsers MUST support at least 256 parameters on an item or inner- | Parsers MUST support at least 256 parameters on an item or inner- | |||
| list, and support parameter keys with at least 64 characters. Header | list, and support parameter keys with at least 64 characters. Header | |||
| specifications can constrain the types and cardinality of individual | specifications can constrain the types and cardinality of individual | |||
| parameter names and values as they require. | parameter names and values as they require. | |||
| 3.2. Dictionaries | 3.2. Dictionaries | |||
| Dictionaries are ordered maps of name-value pairs, where the names | Dictionaries are ordered maps of name-value pairs, where the names | |||
| are short, textual strings and the values are items (Section 3.3) or | are short, textual strings and the values are items (Section 3.3) or | |||
| arrays of items, both of which can be parameterised (Section 3.1.2). | arrays of items, both of which can be parameterised (Section 3.1.2). | |||
| There can be zero or more members, and their names are required to be | There can be zero or more members, and their names are unique in the | |||
| unique within the scope of the dictionary they occur within. | scope of the dictionary they occur within. | |||
| Implementations MUST provide access to dictionaries both by index and | Implementations MUST provide access to dictionaries both by index and | |||
| by name. Specifications MAY use either means of accessing the | by name. Specifications MAY use either means of accessing the | |||
| members. | members. | |||
| The ABNF for dictionaries in HTTP headers is: | The ABNF for dictionaries in HTTP headers is: | |||
| sh-dictionary = dict-member *( OWS "," OWS dict-member ) | sh-dictionary = dict-member *( *SP "," *SP dict-member ) | |||
| dict-member = member-name "=" member-value | dict-member = member-name [ "=" member-value ] | |||
| member-name = key | member-name = key | |||
| member-value = sh-item / inner-list | member-value = sh-item / inner-list | |||
| In HTTP headers, members are separated by a comma with optional | In HTTP headers, members are separated by a comma with optional | |||
| whitespace, while names and values are separated by "=" (without | whitespace, while names and values are separated by "=" (without | |||
| whitespace). For example: | whitespace). For example: | |||
| Example-DictHeader: en="Applepie", da=*w4ZibGV0w6ZydGU=* | Example-DictHeader: en="Applepie", da=:w4ZibGV0w6ZydGU=: | |||
| Members whose value is Boolean true MUST omit that value when | ||||
| serialised, unless it has parameters. For example, here both "b" and | ||||
| "c" are true, but "c"'s value is serialised because it has | ||||
| parameters: | ||||
| Example-DictHeader: a=?0, b, c=?1; foo=bar | ||||
| Note that this requirement is only on serialisation; parsers are | ||||
| still required to correctly handle the true value when it appears in | ||||
| dictionary values. | ||||
| A dictionary with a member whose value is an inner-list of tokens: | A dictionary with a member whose value is an inner-list of tokens: | |||
| Example-DictListHeader: rating=1.5, feelings=(joy sadness) | Example-DictListHeader: rating=1.5, feelings=(joy sadness) | |||
| A dictionary with a mix of singular and list values, some with | A dictionary with a mix of singular and list values, some with | |||
| parameters: | parameters: | |||
| Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?1 | Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid=?1 | |||
| As with lists, an empty dictionary is represented in HTTP headers by | As with lists, an empty dictionary is represented in HTTP headers by | |||
| omitting the entire header field. | omitting the entire header field. | |||
| Typically, a header field specification will define the semantics of | Typically, a header field specification will define the semantics of | |||
| dictionaries by specifying the allowed type(s) for individual member | dictionaries by specifying the allowed type(s) for individual member | |||
| names, as well as whether their presence is required or optional. | names, as well as whether their presence is required or optional. | |||
| Recipients MUST ignore names that are undefined or unknown, unless | Recipients MUST ignore names that are undefined or unknown, unless | |||
| the header field's specification specifically disallows them. | the header field's specification specifically disallows them. | |||
| Note that dictionaries can have their members split across multiple | ||||
| instances inside a block of fields; for example, the following are | ||||
| equivalent: | ||||
| Example-Hdr: foo=1, bar=2 | ||||
| and | ||||
| Example-Hdr: foo=1 | ||||
| Example-Hdr: bar=2 | ||||
| However, members of a dictionary cannot be safely split between | ||||
| instances; see Section 4.2 for details. | ||||
| Parsers MUST support dictionaries containing at least 1024 name/value | Parsers MUST support dictionaries containing at least 1024 name/value | |||
| pairs, and names with at least 64 characters. | pairs, and names with at least 64 characters. | |||
| 3.3. Items | 3.3. Items | |||
| An item is can be a integer (Section 3.3.1), float (Section 3.3.2), | An item is can be a integer (Section 3.3.1), decimal (Section 3.3.2), | |||
| string (Section 3.3.3), token (Section 3.3.4), byte sequence | string (Section 3.3.3), token (Section 3.3.4), byte sequence | |||
| (Section 3.3.5), or Boolean (Section 3.3.6). It can have associated | (Section 3.3.5), or Boolean (Section 3.3.6). It can have associated | |||
| parameters (Section 3.1.2). | parameters (Section 3.1.2). | |||
| The ABNF for items in HTTP headers is: | The ABNF for items in HTTP headers is: | |||
| sh-item = bare-item *parameter | sh-item = bare-item *parameter | |||
| bare-item = sh-integer / sh-float / sh-string / sh-token / sh-binary | bare-item = sh-integer / sh-decimal / sh-string / sh-token / sh-binary | |||
| / sh-boolean | / sh-boolean | |||
| For example, a header field that is defined to be an Item that is an | For example, a header field that is defined to be an Item that is an | |||
| integer might look like: | integer might look like: | |||
| Example-IntItemHeader: 5 | Example-IntItemHeader: 5 | |||
| or with parameters: | or with parameters: | |||
| Example-IntItemHeader: 5; foo=bar | Example-IntItemHeader: 5; foo=bar | |||
| 3.3.1. Integers | 3.3.1. Integers | |||
| Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 | Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 | |||
| inclusive (i.e., up to fifteen digits, signed), for IEEE 754 | inclusive (i.e., up to fifteen digits, signed), for IEEE 754 | |||
| compatibility ([IEEE754]). | compatibility ([IEEE754]). | |||
| skipping to change at page 11, line 22 ¶ | skipping to change at page 12, line 25 ¶ | |||
| sh-integer = ["-"] 1*15DIGIT | sh-integer = ["-"] 1*15DIGIT | |||
| For example: | For example: | |||
| Example-IntegerHeader: 42 | Example-IntegerHeader: 42 | |||
| Note that commas in integers are used in this section's prose only | Note that commas in integers are used in this section's prose only | |||
| for readability; they are not valid in the wire format. | for readability; they are not valid in the wire format. | |||
| 3.3.2. Floats | 3.3.2. Decimals | |||
| Floats are decimal numbers with an integer and a fractional | Decimals are numbers with an integer and a fractional component. The | |||
| component. The fractional component has at most six digits of | Integer component has at most 12 digits; the fractional component has | |||
| precision. Additionally, like integers, it can have no more than | at most three digits. | |||
| fifteen digits in total, which in some cases further constrains its | ||||
| precision. | ||||
| The ABNF for floats in HTTP headers is: | The ABNF for decimals in HTTP headers is: | |||
| sh-float = ["-"] (1*9DIGIT "." 1*6DIGIT / | sh-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | |||
| 10DIGIT "." 1*5DIGIT / | ||||
| 11DIGIT "." 1*4DIGIT / | ||||
| 12DIGIT "." 1*3DIGIT / | ||||
| 13DIGIT "." 1*2DIGIT / | ||||
| 14DIGIT "." 1DIGIT ) | ||||
| For example, a header whose value is defined as a float could look | For example, a header whose value is defined as a decimal could look | |||
| like: | like: | |||
| Example-FloatHeader: 4.5 | Example-DecimalHeader: 4.5 | |||
| 3.3.3. Strings | 3.3.3. Strings | |||
| Strings are zero or more printable ASCII [RFC0020] characters (i.e., | Strings are zero or more printable ASCII [RFC0020] characters (i.e., | |||
| the range %x20 to %x7E). Note that this excludes tabs, newlines, | the range %x20 to %x7E). Note that this excludes tabs, newlines, | |||
| carriage returns, etc. | carriage returns, etc. | |||
| The ABNF for strings in HTTP headers is: | The ABNF for strings in HTTP headers is: | |||
| sh-string = DQUOTE *(chr) DQUOTE | sh-string = DQUOTE *(chr) DQUOTE | |||
| skipping to change at page 12, line 37 ¶ | skipping to change at page 13, line 31 ¶ | |||
| Parsers MUST support strings with at least 1024 characters. | Parsers MUST support strings with at least 1024 characters. | |||
| 3.3.4. Tokens | 3.3.4. Tokens | |||
| Tokens are short textual words; their abstract model is identical to | Tokens are short textual words; their abstract model is identical to | |||
| their expression in the HTTP header serialisation. | their expression in the HTTP header serialisation. | |||
| The ABNF for tokens in HTTP headers is: | The ABNF for tokens in HTTP headers is: | |||
| sh-token = ALPHA *( tchar / ":" / "/" ) | sh-token = ( ALPHA / "\*" ) *( tchar / ":" / "/" ) | |||
| Parsers MUST support tokens with at least 512 characters. | Parsers MUST support tokens with at least 512 characters. | |||
| Note that a Structured Header token allows the characters as the | Note that a Structured Header token allows the characters as the | |||
| "token" ABNF rule defined in [RFC7230], with the exceptions that the | "token" ABNF rule defined in [RFC7230], with the exceptions that the | |||
| first character is required to be ALPHA, and ":" and "/" are also | first character is required to be either ALPHA or "*", and ":" and | |||
| allowed. | "/" are also allowed in subsequent characters. | |||
| 3.3.5. Byte Sequences | 3.3.5. Byte Sequences | |||
| Byte sequences can be conveyed in Structured Headers. | Byte sequences can be conveyed in Structured Headers. | |||
| The ABNF for a byte sequence in HTTP headers is: | The ABNF for a byte sequence in HTTP headers is: | |||
| sh-binary = "*" *(base64) "*" | sh-binary = ":" *(base64) ":" | |||
| base64 = ALPHA / DIGIT / "+" / "/" / "=" | base64 = ALPHA / DIGIT / "+" / "/" / "=" | |||
| In HTTP headers, a byte sequence is delimited with asterisks and | In HTTP headers, a byte sequence is delimited with colons and encoded | |||
| encoded using base64 ([RFC4648], Section 4). For example: | using base64 ([RFC4648], Section 4). For example: | |||
| Example-BinaryHdr: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==* | Example-BinaryHdr: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | |||
| Parsers MUST support byte sequences with at least 16384 octets after | Parsers MUST support byte sequences with at least 16384 octets after | |||
| decoding. | decoding. | |||
| 3.3.6. Booleans | 3.3.6. Booleans | |||
| Boolean values can be conveyed in Structured Headers. | Boolean values can be conveyed in Structured Headers. | |||
| The ABNF for a Boolean in HTTP headers is: | The ABNF for a Boolean in HTTP headers is: | |||
| skipping to change at page 13, line 41 ¶ | skipping to change at page 14, line 35 ¶ | |||
| This section defines how to serialize and parse Structured Headers in | This section defines how to serialize and parse Structured Headers in | |||
| header fields, and protocols compatible with them (e.g., in HTTP/2 | header fields, and protocols compatible with them (e.g., in HTTP/2 | |||
| [RFC7540] before HPACK [RFC7541] is applied). | [RFC7540] before HPACK [RFC7541] is applied). | |||
| 4.1. Serializing Structured Headers | 4.1. Serializing Structured Headers | |||
| Given a structure defined in this specification, return an ASCII | Given a structure defined in this specification, return an ASCII | |||
| string suitable for use in a HTTP header value. | string suitable for use in a 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 serialize the field at all | (i.e., it has no members), do not serialize the 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 running Serializing a Dictionary (Section 4.1.2) with the | of running Serializing a Dictionary (Section 4.1.2) with the | |||
| structure. | structure. | |||
| 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 running Serializing a List (Section 4.1.1) with the structure. | of running Serializing a List (Section 4.1.1) with the structure. | |||
| 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 running Serializing an Item (Section 4.1.3) with the | of running Serializing an Item (Section 4.1.3) with the | |||
| structure. | structure. | |||
| 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 an array of (member-value, parameters) tuples as input_list, | Given an array of (member_value, parameters) tuples as input_list, | |||
| return an ASCII string suitable for use in a HTTP header value. | return an ASCII string suitable for use in a HTTP header value. | |||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each (member-value, parameters) of input_list: | 2. For each (member_value, parameters) of input_list: | |||
| 1. If member-value is an array, append the result of running | 1. If member_value is an array, append the result of running | |||
| Serialising an Inner List (Section 4.1.1.1) with (member- | Serialising an Inner List (Section 4.1.1.1) with | |||
| value, parameters) to output. | (member_value, parameters) to output. | |||
| 2. Otherwise, append the result of running Serializing an Item | 2. Otherwise, append the result of running Serializing an Item | |||
| (Section 4.1.3) with (member-value, parameters) to output. | (Section 4.1.3) with (member_value, parameters) to output. | |||
| 3. If more member-values remain in input_list: | 3. If more member_values remain in input_list: | |||
| 1. Append a COMMA to output. | 1. Append a COMMA to output. | |||
| 2. Append a single WS to output. | 2. Append a single SP 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 of (member-value, parameters) tuples as inner_list, | Given an array of (member_value, parameters) tuples as inner_list, | |||
| and parameters as list_parameters, return an ASCII string suitable | and parameters as list_parameters, return an ASCII string suitable | |||
| for use in a HTTP header value. | for use in a HTTP header value. | |||
| 1. Let output be the string "(". | 1. Let output be the string "(". | |||
| 2. For each (member-value, parameters) of inner_list: | 2. For each (member_value, parameters) of inner_list: | |||
| 1. Append the result of running Serializing an Item | 1. Append the result of running Serializing an Item | |||
| (Section 4.1.3) with (member-value, parameters) to output. | (Section 4.1.3) with (member_value, parameters) to output. | |||
| 2. If more values remain in inner_list, append a single WS to | 2. If more values remain in inner_list, append a single SP to | |||
| output. | output. | |||
| 3. Append ")" to output. | 3. Append ")" to output. | |||
| 4. Append the result of running Serializing Parameters | 4. Append the result of running Serializing Parameters | |||
| Section 4.1.1.2 with list_parameters to output. | Section 4.1.1.2 with list_parameters to output. | |||
| 5. Return output. | 5. Return output. | |||
| 4.1.1.2. Serializing Parameters | 4.1.1.2. Serializing Parameters | |||
| Given an ordered dictionary as input_parameters (each member having a | Given an ordered dictionary as input_parameters (each member having a | |||
| param-name and a param-value), return an ASCII string suitable for | param_name and a param_value), return an ASCII string suitable for | |||
| use in a HTTP header value. | use in a HTTP header value. | |||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each parameter-name with a value of param-value in | 2. For each parameter-name with a value of param_value in | |||
| input_parameters: | input_parameters: | |||
| 1. Append ";" to output. | 1. Append ";" to output. | |||
| 2. Append the result of running Serializing a Key | 2. Append the result of running Serializing a Key | |||
| (Section 4.1.1.3) with param-name to output. | (Section 4.1.1.3) with param_name to output. | |||
| 3. If param-value is not null: | 3. If param_value is not Boolean true: | |||
| 1. Append "=" to output. | 1. Append "=" to output. | |||
| 2. Append the result of running Serializing a bare Item | 2. Append the result of running Serializing a bare Item | |||
| (Section 4.1.3.1) with param-value to output. | (Section 4.1.3.1) with param_value to output. | |||
| 3. 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, return an ASCII string suitable for use in | Given a key as input_key, return an ASCII string suitable for use in | |||
| a HTTP header value. | a 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 in lcalpha, DIGIT, "*", "_", or "-", fail | characters not in lcalpha, DIGIT, "_", "-", ".", or "*" fail | |||
| serialisation. | serialisation. | |||
| 2. Let output be an empty string. | 2. If the first character of input_key is not lcalpha, fail parsing. | |||
| 3. Append input_key to output. | 3. Let output be an empty string. | |||
| 4. Return output. | 4. Append input_key to output. | |||
| 5. Return output. | ||||
| 4.1.2. Serializing a Dictionary | 4.1.2. Serializing a Dictionary | |||
| Given an ordered dictionary as input_dictionary (each member having a | Given an ordered dictionary as input_dictionary (each member having a | |||
| member-name and a tuple value of (member-value, parameters)), return | member_name and a tuple value of (member_value, parameters)), return | |||
| an ASCII string suitable for use in a HTTP header value. | an ASCII string suitable for use in a HTTP header value. | |||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. For each member-name with a value of (member-value, parameters) | 2. For each member_name with a value of (member_value, parameters) | |||
| in input_dictionary: | in input_dictionary: | |||
| 1. Append the result of running Serializing a Key | 1. Append the result of running Serializing a Key | |||
| (Section 4.1.1.3) with member's member-name to output. | (Section 4.1.1.3) with member's member_name to output. | |||
| 2. Append "=" to output. | 3. If member_value is not Boolean true or parameters is not empty: | |||
| 3. If member-value is an array, append the result of running | 1. Append "=" to output. | |||
| Serialising an Inner List (Section 4.1.1.1) with (member- | ||||
| value, parameters) to output. | ||||
| 4. Otherwise, append the result of running Serializing an Item | 1. If member_value is an array, append the result of running | |||
| (Section 4.1.3) with (member-value, parameters) to output. | Serialising an Inner List (Section 4.1.1.1) with | |||
| (member_value, parameters) to output. | ||||
| 5. If more members remain in input_dictionary: | 2. Otherwise, append the result of running Serializing an | |||
| Item (Section 4.1.3) with (member_value, parameters) to | ||||
| output. | ||||
| 1. Append a COMMA to output. | 4. If more members remain in input_dictionary: | |||
| 2. Append a single WS to output. | 1. Append a COMMA to output. | |||
| 3. Return output. | 2. Append a single SP to output. | |||
| 5. Return output. | ||||
| 4.1.3. Serializing an Item | 4.1.3. Serializing an Item | |||
| Given an item bare_item and parameters item_parameters as input, | Given an item bare_item and parameters item_parameters as input, | |||
| return an ASCII string suitable for use in a HTTP header value. | return an ASCII string suitable for use in a HTTP header value. | |||
| 1. Let output be an empty string. | 1. Let output be an empty string. | |||
| 2. Append the result of running Serializing a Bare Item | 2. Append the result of running Serializing a Bare Item | |||
| Section 4.1.3.1 with bare_item to output. | Section 4.1.3.1 with bare_item to output. | |||
| skipping to change at page 17, line 13 ¶ | skipping to change at page 18, line 13 ¶ | |||
| 4. Return output. | 4. Return output. | |||
| 4.1.3.1. Serialising a Bare Item | 4.1.3.1. Serialising a Bare Item | |||
| Given an item as input_item, return an ASCII string suitable for use | Given an item as input_item, return an ASCII string suitable for use | |||
| in a HTTP header value. | in a HTTP header value. | |||
| 1. If input_item is an integer, return the result of running | 1. If input_item is an integer, return the result of running | |||
| Serializing an Integer (Section 4.1.4) with input_item. | Serializing an Integer (Section 4.1.4) with input_item. | |||
| 2. If input_item is a float, return the result of running | 2. If input_item is a decimal, return the result of running | |||
| Serializing a Float (Section 4.1.5) with input_item. | Serializing a Decimal (Section 4.1.5) with input_item. | |||
| 3. If input_item is a string, return the result of running | 3. If input_item is a string, return the result of running | |||
| Serializing a String (Section 4.1.6) with input_item. | Serializing a String (Section 4.1.6) with input_item. | |||
| 4. If input_item is a token, return the result of running | 4. If input_item is a token, return the result of running | |||
| Serializing a Token (Section 4.1.7) with input_item. | Serializing a Token (Section 4.1.7) with input_item. | |||
| 5. If input_item is a Boolean, return the result of running | 5. If input_item is a Boolean, return the result of running | |||
| Serializing a Boolean (Section 4.1.9) with input_item. | Serializing a Boolean (Section 4.1.9) with input_item. | |||
| skipping to change at page 18, line 5 ¶ | skipping to change at page 19, line 5 ¶ | |||
| 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 Decimal | |||
| Given a float as input_float, return an ASCII string suitable for use | ||||
| in a HTTP header value. | ||||
| 1. Let output be an empty string. | Given a decimal_number as input_decimal, return an ASCII string | |||
| suitable for use in a HTTP header value. | ||||
| 2. If input_float is less than (but not equal to) 0, append "-" to | 1. Let output be an empty string. | |||
| output. | ||||
| 3. Append input_float's integer component represented in base 10 | 2. If input_decimal is less than (but not equal to) 0, append "-" to | |||
| (using only decimal digits) to output; if it is zero, append | output. | |||
| "0". | ||||
| 4. Let integer_digits be the number of characters appended in the | 3. Append input_decimal's integer component represented in base 10 | |||
| previous step. | (using only decimal digits) to output; if it is zero, append "0". | |||
| 5. If integer_digits is greater than 14, fail serialisation. | 4. If the number of characters appended in the previous step is | |||
| greater than 12, fail serialisation. | ||||
| 6. Let digits_avail be 15 minus integer_digits. | 5. Append "." to output. | |||
| 7. Let fractional_digits_avail be the minimum of digits_avail and | 6. If input_decimal's fractional component is zero, append "0" to | |||
| 6. | output. | |||
| 8. Append "." to output. | 7. Else if input_decimal's fractional component has up to three | |||
| digits, append them represented in base 10 (using only decimal | ||||
| digits) to output. | ||||
| 9. Append at most fractional_digits_avail digits of input_float's | 8. Otherwise, append the first three digits of input_decimal's | |||
| fractional component represented in base 10 to output (using | fractional component (represented in base 10, using only decimal | |||
| only decimal digits, and truncating any remaining digits); if it | digits) to output, rounding the final digit to the nearest value, | |||
| is zero, append "0". | or to the even value if it is equidistant. | |||
| 10. Return output. | 9. Return output. | |||
| 4.1.6. Serializing a String | 4.1.6. Serializing a String | |||
| Given a string as input_string, return an ASCII string suitable for | Given a string as input_string, return an ASCII string suitable for | |||
| use in a HTTP header value. | use in a 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 in the range %x00-1f or %x7f (i.e., is not in VCHAR or | characters in the range %x00-1f or %x7f (i.e., is not in VCHAR or | |||
| SP), fail serialisation. | SP), fail serialisation. | |||
| skipping to change at page 19, line 20 ¶ | skipping to change at page 20, line 18 ¶ | |||
| 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, return an ASCII string suitable for use | Given a token as input_token, return an ASCII string suitable for use | |||
| in a HTTP header value. | in a 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, the first | |||
| characters not allowed by the tchar ABNF rule, fail | character is not ALPHA or "*", or the remaining contain a | |||
| serialisation. | character not in tchar, ":" 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, return an ASCII string suitable | Given a byte sequence as input_bytes, return an ASCII string suitable | |||
| for use in a HTTP header value. | for use in a 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. | |||
| 5. Append "*" to output. | 5. Append ":" to output. | |||
| 6. Return output. | 6. Return output. | |||
| 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. | |||
| skipping to change at page 20, line 42 ¶ | skipping to change at page 21, line 38 ¶ | |||
| doing so. | doing so. | |||
| Given an array of bytes input_bytes that represents the chosen | Given an array of bytes input_bytes that represents the chosen | |||
| header's field-value (which is empty if that header is not present), | header's field-value (which is empty if that header is not present), | |||
| and header_type (one of "dictionary", "list", or "item"), return the | and header_type (one of "dictionary", "list", or "item"), return the | |||
| parsed header value. | parsed header value. | |||
| 1. Convert input_bytes into an ASCII string input_string; if | 1. Convert input_bytes into an ASCII string input_string; if | |||
| conversion fails, fail parsing. | conversion fails, fail parsing. | |||
| 2. Discard any leading OWS from input_string. | 2. Discard any leading SP characters from input_string. | |||
| 3. If header_type is "list", let output be the result of running | 3. If header_type is "list", let output be the result of running | |||
| Parsing a List (Section 4.2.1) with input_string. | Parsing a List (Section 4.2.1) with input_string. | |||
| 4. If header_type is "dictionary", let output be the result of | 4. If header_type is "dictionary", let output be the result of | |||
| running Parsing a Dictionary (Section 4.2.2) with input_string. | running Parsing a Dictionary (Section 4.2.2) with input_string. | |||
| 5. If header_type is "item", let output be the result of running | 5. If header_type is "item", let output be the result of running | |||
| Parsing an Item (Section 4.2.3) with input_string. | Parsing an Item (Section 4.2.3) with input_string. | |||
| 6. Discard any leading OWS from input_string. | 6. Discard any leading SP characters 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 | |||
| correctly. | correctly. | |||
| skipping to change at page 21, line 27 ¶ | skipping to change at page 22, line 23 ¶ | |||
| concatenating all instances of the header field, as long as | concatenating all instances of the header field, as long as | |||
| individual individual members of the top-level data structure are not | individual individual members of the top-level data structure are not | |||
| split across multiple header instances. | split across multiple header instances. | |||
| Strings split across multiple header instances will have | Strings split across multiple header instances will have | |||
| 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, Decimals 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 ignored (i.e., treated as if the | 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 | 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 | Note that this requirement does not apply to an implementation that | |||
| skipping to change at page 22, line 8 ¶ | skipping to change at page 22, line 51 ¶ | |||
| (item_or_inner_list, parameters) tuples. input_string is modified to | (item_or_inner_list, parameters) tuples. input_string is modified to | |||
| remove the parsed value. | 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. Append the result of running Parsing an Item or Inner List | 1. Append the result of running Parsing an Item or Inner List | |||
| (Section 4.2.1.1) with input_string to members. | (Section 4.2.1.1) with input_string to members. | |||
| 2. Discard any leading OWS from input_string. | 2. Discard any leading SP characters from input_string. | |||
| 3. If input_string is empty, return members. | 3. If input_string is empty, return members. | |||
| 4. Consume the first character of input_string; if it is not | 4. Consume the first character of input_string; if it is not | |||
| COMMA, fail parsing. | COMMA, fail parsing. | |||
| 5. Discard any leading OWS from input_string. | 5. Discard any leading SP characters from input_string. | |||
| 6. If input_string is empty, there is a trailing comma; fail | 6. 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 an Item or Inner List | 4.2.1.1. Parsing an Item or Inner List | |||
| Given an ASCII string as input_string, return the tuple | Given an ASCII string as input_string, return the tuple | |||
| skipping to change at page 22, line 50 ¶ | skipping to change at page 23, line 45 ¶ | |||
| parameters), where inner_list is an array of (bare_item, parameters) | parameters), where inner_list is an array of (bare_item, parameters) | |||
| tuples. input_string is modified to remove the parsed value. | tuples. 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 SP characters 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. Let parameters be the result of running Parsing | 2. Let parameters be the result of running Parsing | |||
| Parameters (Section 4.2.3.2) with input_string. | Parameters (Section 4.2.3.2) with input_string. | |||
| 3. Return the tuple (inner_list, parameters). | 3. Return the tuple (inner_list, parameters). | |||
| skipping to change at page 23, line 32 ¶ | skipping to change at page 24, line 27 ¶ | |||
| 4.2.2. Parsing a Dictionary | 4.2.2. Parsing a Dictionary | |||
| Given an ASCII string as input_string, return an ordered map whose | Given an ASCII string as input_string, return an ordered map whose | |||
| values are (item_or_inner_list, parameters) tuples. input_string is | values are (item_or_inner_list, parameters) tuples. input_string is | |||
| modified to remove the parsed value. | 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 | 1. Let this_key be the result of running Parsing a Key | |||
| (Section 4.2.3.3) with input_string. | (Section 4.2.3.3) with input_string. | |||
| 2. If dictionary already contains the name this_key, there is a | 2. If the first character of input_string is "=": | |||
| duplicate; fail parsing. | ||||
| 3. Consume the first character of input_string; if it is not | 1. Consume the first character of input_string. | |||
| "=", fail parsing. | ||||
| 4. Let member be the result of running Parsing an Item or Inner | 2. Let member be the result of running Parsing an Item or | |||
| List (Section 4.2.1.1) with input_string. | Inner List (Section 4.2.1.1) with input_string. | |||
| 5. Add name this_key with value member to dictionary. | 3. Otherwise: | |||
| 6. Discard any leading OWS from input_string. | 1. Let value be Boolean true. | |||
| 7. If input_string is empty, return dictionary. | 2. Let parameters be an empty, ordered map. | |||
| 8. Consume the first character of input_string; if it is not | 3. Let member be the tuple (value, parameters). | |||
| COMMA, fail parsing. | ||||
| 9. Discard any leading OWS from input_string. | 4. Add name this_key with value member to dictionary. If | |||
| dictionary already contains a name this_key (comparing | ||||
| character-for-character), overwrite its value. | ||||
| 10. If input_string is empty, there is a trailing comma; fail | 5. Discard any leading SP characters from input_string. | |||
| parsing. | ||||
| 6. If input_string is empty, return dictionary. | ||||
| 7. Consume the first character of input_string; if it is not | ||||
| COMMA, fail parsing. | ||||
| 8. Discard any leading SP characters from input_string. | ||||
| 9. If input_string is empty, there is a trailing comma; fail | ||||
| 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 an Item | 4.2.3. Parsing an Item | |||
| Given an ASCII string as input_string, return a (bare_item, | Given an ASCII string as input_string, return a (bare_item, | |||
| parameters) tuple. input_string is modified to remove the parsed | parameters) tuple. input_string is modified to remove the parsed | |||
| value. | value. | |||
| skipping to change at page 24, line 40 ¶ | skipping to change at page 25, line 43 ¶ | |||
| 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 a "-" or a DIGIT, | 1. If the first character of input_string is a "-" or a DIGIT, | |||
| return the result of running Parsing a Number (Section 4.2.4) | return the result of running Parsing a Number (Section 4.2.4) | |||
| with input_string. | with input_string. | |||
| 2. If the first character of input_string is a DQUOTE, return the | 2. If the first character of input_string is a DQUOTE, return the | |||
| result of running Parsing a String (Section 4.2.5) with | result of running Parsing a String (Section 4.2.5) with | |||
| input_string. | input_string. | |||
| 3. If the first character of input_string is "*", return the result | 3. If the first character of input_string is ":", return the result | |||
| of running Parsing a Byte Sequence (Section 4.2.7) with | of running Parsing a Byte Sequence (Section 4.2.7) with | |||
| input_string. | input_string. | |||
| 4. If the first character of input_string is "?", return the result | 4. If the first character of input_string is "?", return the result | |||
| of running Parsing a Boolean (Section 4.2.8) with input_string. | of running Parsing a Boolean (Section 4.2.8) with input_string. | |||
| 5. If the first character of input_string is an ALPHA, return the | 5. If the first character of input_string is an ALPHA or "*", return | |||
| result of running Parsing a Token (Section 4.2.6) with | the result of running Parsing a Token (Section 4.2.6) with | |||
| input_string. | input_string. | |||
| 6. Otherwise, the item type is unrecognized; fail parsing. | 6. Otherwise, the item type is unrecognized; fail parsing. | |||
| 4.2.3.2. Parsing Parameters | 4.2.3.2. Parsing Parameters | |||
| Given an ASCII string as input_string, return an ordered map whose | Given an ASCII string as input_string, return an ordered map whose | |||
| values are bare items. input_string is modified to remove the parsed | values are bare items. input_string is modified to remove the parsed | |||
| value. | value. | |||
| 1. Let parameters be an empty, ordered map. | 1. Let parameters be an empty, ordered map. | |||
| 2. While input_string is not empty: | 2. While input_string is not empty: | |||
| 1. If the first character of input_string is not ";", exit the | 1. If the first character of input_string is not ";", exit the | |||
| loop. | loop. | |||
| 2. Consume a ";" character from the beginning of input_string. | 2. Consume a ";" character from the beginning of input_string. | |||
| 3. Discard any leading OWS from input_string. | 3. Discard any leading SP characters from input_string. | |||
| 4. let param_name be the result of running Parsing a Key | 4. let param_name be the result of running Parsing a Key | |||
| (Section 4.2.3.3) with input_string. | (Section 4.2.3.3) with input_string. | |||
| 5. If param_name is already present in parameters, there is a | 5. Let param_value be Boolean true. | |||
| duplicate; fail parsing. | ||||
| 6. Let param_value be a null value. | ||||
| 7. If the first character of input_string is "=": | 6. 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 running Parsing a Bare | 2. Let param_value be the result of running Parsing a Bare | |||
| Item (Section 4.2.3.1) with input_string. | Item (Section 4.2.3.1) with input_string. | |||
| 8. Append key param_name with value param_value to parameters. | 7. Append key param_name with value param_value to parameters. | |||
| If parameters already contains a name param_name (comparing | ||||
| character-for-character), overwrite its value. | ||||
| 3. Return parameters. | 3. Return parameters. | |||
| 4.2.3.3. Parsing a Key from Text | 4.2.3.3. Parsing a Key | |||
| Given an ASCII string as input_string, return a key. input_string is | Given an ASCII string as input_string, return a key. input_string is | |||
| modified to remove the parsed value. | modified to remove the parsed value. | |||
| 1. If the first character of input_string is not lcalpha, fail | 1. If the first character of input_string is not lcalpha, 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. If the first character of input_string is not one of lcalpha, | 1. If the first character of input_string is not one of lcalpha, | |||
| DIGIT, "*", "_", or "-", return output_string. | DIGIT, "_", "-", ".", or "*", return output_string. | |||
| 2. Let char be the result of removing the first character of | 2. Let char be the result of removing the first character of | |||
| input_string. | input_string. | |||
| 3. Append char to output_string. | 3. Append char to output_string. | |||
| 4. Return output_string. | 4. Return output_string. | |||
| 4.2.4. Parsing a Number from Text | 4.2.4. Parsing a Number | |||
| Given an ASCII string as input_string, return a number. input_string | Given an ASCII string as input_string, return a number. input_string | |||
| is modified to remove the parsed value. | is modified to remove the parsed value. | |||
| NOTE: This algorithm parses both Integers (Section 3.3.1) and Floats | NOTE: This algorithm parses both Integers (Section 3.3.1) and | |||
| (Section 3.3.2), and returns the corresponding structure. | Decimals (Section 3.3.2), 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. | |||
| 4. If the first character of input_string is "-", consume it and | 4. If the first character of input_string is "-", consume it and | |||
| set sign to -1. | set sign to -1. | |||
| skipping to change at page 26, line 45 ¶ | skipping to change at page 27, line 47 ¶ | |||
| 6. If the first character of input_string is not a DIGIT, fail | 6. If the first character of input_string is not a DIGIT, fail | |||
| parsing. | parsing. | |||
| 7. While input_string is not empty: | 7. 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 DIGIT, append it to input_number. | 2. If char is a DIGIT, append it to input_number. | |||
| 3. Else, if type is "integer" and char is ".", append char to | 3. Else, if type is "integer" and char is ".": | |||
| input_number and set type to "float". | ||||
| 1. If input_number contains more than 12 characters, fail | ||||
| parsing. | ||||
| 2. Otherwise, append char to input_number and set type to | ||||
| "decimal". | ||||
| 4. Otherwise, prepend char to input_string, and exit the loop. | 4. Otherwise, prepend char to input_string, and exit the loop. | |||
| 5. If type is "integer" and input_number contains more than 15 | 5. If type is "integer" and input_number contains more than 15 | |||
| characters, fail parsing. | characters, fail parsing. | |||
| 6. If type is "float" and input_number contains more than 16 | 6. If type is "decimal" and input_number contains more than 16 | |||
| characters, fail parsing. | characters, fail parsing. | |||
| 8. If type is "integer": | 8. If type is "integer": | |||
| 1. Parse input_number as an integer and let output_number be | 1. Parse input_number as an integer and let output_number be | |||
| the product of the result and sign. | the product of the result and sign. | |||
| 2. If output_number is outside the range defined in | 2. If output_number is outside the range -999,999,999,999,999 | |||
| Section 3.3.1, fail parsing. | to 999,999,999,999,999 inclusive, fail parsing. | |||
| 9. Otherwise: | 9. Otherwise: | |||
| 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 three, fail parsing. | |||
| 3. Parse input_number as a float and let output_number be the | 3. Parse input_number as a decimal number and let output_number | |||
| product of the result and sign. | be the product of the result and sign. | |||
| 10. Return output_number. | 10. Return output_number. | |||
| 4.2.5. Parsing a String from Text | 4.2.5. Parsing a String | |||
| Given an ASCII string as 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. | |||
| skipping to change at page 28, line 17 ¶ | skipping to change at page 29, line 26 ¶ | |||
| 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.6. Parsing a Token from Text | 4.2.6. Parsing a Token | |||
| Given an ASCII string as input_string, return a token. input_string | Given an ASCII string as input_string, return a token. input_string | |||
| is 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 or "*", 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. If the first character of input_string is not allowed by the | 1. If the first character of input_string is not in tchar, ":" | |||
| tchar ABNF rule, return output_string. | or "/", return output_string. | |||
| 2. Let char be the result of consuming the first character of | 2. Let char be the result of consuming the first character of | |||
| input_string. | input_string. | |||
| 3. Append char to output_string. | 3. Append char to output_string. | |||
| 4. Return output_string. | 4. Return output_string. | |||
| 4.2.7. Parsing a Byte Sequence from Text | 4.2.7. Parsing a Byte Sequence | |||
| Given an ASCII string as 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 | |||
| input_string up to but not including the first instance of the | input_string up to but not including the first instance of the | |||
| character "*". | character ":". | |||
| 5. Consume the "*" character at the beginning of input_string. | 5. Consume the ":" character at the beginning of input_string. | |||
| 6. If b64_content contains a character not included in ALPHA, DIGIT, | 6. If b64_content contains a character not included in ALPHA, DIGIT, | |||
| "+", "/" and "=", fail parsing. | "+", "/" and "=", fail parsing. | |||
| 7. Let binary_content be the result of Base 64 Decoding [RFC4648] | 7. Let binary_content be the result of Base 64 Decoding [RFC4648] | |||
| b64_content, synthesizing padding if necessary (note the | b64_content, synthesizing padding if necessary (note the | |||
| requirements about recipient behaviour below). | requirements about recipient behaviour below). | |||
| 8. Return binary_content. | 8. Return binary_content. | |||
| skipping to change at page 29, line 34 ¶ | skipping to change at page 30, line 41 ¶ | |||
| 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.8. Parsing a Boolean from Text | 4.2.8. Parsing a Boolean | |||
| Given an ASCII string as input_string, return a Boolean. input_string | Given an ASCII string as input_string, return a Boolean. input_string | |||
| is 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. | |||
| skipping to change at page 33, line 22 ¶ | skipping to change at page 34, line 22 ¶ | |||
| Sometimes, this can be achieved by creating limited substructures in | Sometimes, this can be achieved by creating limited substructures in | |||
| values, and/or using more than one header. For example, consider: | values, and/or using more than one header. For example, consider: | |||
| Example-Thing: name="Widget", cost=89.2, descriptions=(foo bar) | Example-Thing: name="Widget", cost=89.2, descriptions=(foo bar) | |||
| Example-Description: foo; url="https://example.net"; context=123, | Example-Description: foo; url="https://example.net"; context=123, | |||
| bar; url="https://example.org"; context=456 | bar; url="https://example.org"; context=456 | |||
| Since the description contains an array of key/value pairs, we use a | Since the description contains an array of key/value pairs, we use a | |||
| List to represent them, with the token for each item in the array | List to represent them, with the token for each item in the array | |||
| used to identify it in the "descriptions" member of the Example-Thing | used to identify it in the "descriptions" member of the Example-Thing | |||
| header. | dictionary header. | |||
| When specifying more than one header, it's important to remember to | When specifying more than one header, it's important to remember to | |||
| describe what a processor's behaviour should be when one of the | describe what a processor's behaviour should be when one of the | |||
| headers is missing. | headers is missing. | |||
| If you need to fit arbitrarily complex data into a header, Structured | If you need to fit arbitrarily complex data into a header, Structured | |||
| Headers is probably a poor fit for your use case. | Headers is probably a poor fit for your use case. | |||
| Appendix C. Implementation Notes | Appendix C. Implementation Notes | |||
| skipping to change at page 34, line 9 ¶ | skipping to change at page 35, line 9 ¶ | |||
| 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-13 | D.1. Since draft-ietf-httpbis-header-structure-14 | |||
| o Editorial improvements. | ||||
| o Allow empty dictionary values (#992). | ||||
| o Change value of omitted parameter value to True (#995). | ||||
| o Explain more about splitting dictionaries and lists across header | ||||
| instances (#997). | ||||
| o Disallow HTAB, replace OWS with spaces (#998). | ||||
| o Change byte sequence delimiters from "*" to ":" (#991). | ||||
| o Allow tokens to start with "*" (#991). | ||||
| o Change Floats to fixed-precision Decimals (#982). | ||||
| o Round the fractional component of decimal, rather than truncating | ||||
| it (#982). | ||||
| o Handle duplicate dictionary and parameter keys by overwriting | ||||
| their values, rather than failing (#997). | ||||
| o Allow "." in key (#1027). | ||||
| o Check first character of key in serialisation (#1037). | ||||
| o Talk about greasing headers (#1015). | ||||
| D.2. Since draft-ietf-httpbis-header-structure-13 | ||||
| o Editorial improvements. | o Editorial improvements. | |||
| o Define "structured header name" and "structured header value" | o Define "structured header name" and "structured header value" | |||
| terms (#908). | terms (#908). | |||
| o Corrected text about valid characters in strings (#931). | o Corrected text about valid characters in strings (#931). | |||
| o Removed most instances of the word "textual", as it was redundant | o Removed most instances of the word "textual", as it was redundant | |||
| (#915). | (#915). | |||
| o Allowed parameters on Items and Inner Lists (#907). | o Allowed parameters on Items and Inner Lists (#907). | |||
| o Expand the range of characters in token (#961). | o Expand the range of characters in token (#961). | |||
| D.2. Since draft-ietf-httpbis-header-structure-12 | o Disallow OWS before ";" delimiter in parameters (#961). | |||
| D.3. Since draft-ietf-httpbis-header-structure-12 | ||||
| o Editorial improvements. | o Editorial improvements. | |||
| o Reworked float serialisation (#896). | o Reworked float serialisation (#896). | |||
| o Don't add a trailing space in inner-list (#904). | o Don't add a trailing space in inner-list (#904). | |||
| D.3. Since draft-ietf-httpbis-header-structure-11 | D.4. 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.4. Since draft-ietf-httpbis-header-structure-10 | D.5. 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.5. Since draft-ietf-httpbis-header-structure-09 | D.6. 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.6. Since draft-ietf-httpbis-header-structure-08 | D.7. 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 35, line 42 ¶ | skipping to change at page 37, line 29 ¶ | |||
| 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.7. Since draft-ietf-httpbis-header-structure-07 | D.8. 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.8. Since draft-ietf-httpbis-header-structure-06 | D.9. 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.9. Since draft-ietf-httpbis-header-structure-05 | D.10. 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.10. Since draft-ietf-httpbis-header-structure-04 | D.11. 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.11. Since draft-ietf-httpbis-header-structure-03 | D.12. Since draft-ietf-httpbis-header-structure-03 | |||
| o Strengthen language around failure handling. | o Strengthen language around failure handling. | |||
| D.12. Since draft-ietf-httpbis-header-structure-02 | D.13. 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.13. Since draft-ietf-httpbis-header-structure-01 | D.14. Since draft-ietf-httpbis-header-structure-01 | |||
| o Replaced with draft-nottingham-structured-headers. | o Replaced with draft-nottingham-structured-headers. | |||
| D.14. Since draft-ietf-httpbis-header-structure-00 | D.15. 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. 144 change blocks. | ||||
| 224 lines changed or deleted | 344 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/ | ||||