| draft-ietf-httpbis-header-structure-02.txt | draft-ietf-httpbis-header-structure-03.txt | |||
|---|---|---|---|---|
| HTTP Working Group 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 31, 2018 The Varnish Cache Project | Expires: August 5, 2018 The Varnish Cache Project | |||
| November 27, 2017 | February 1, 2018 | |||
| Structured Headers for HTTP | Structured Headers for HTTP | |||
| draft-ietf-httpbis-header-structure-02 | draft-ietf-httpbis-header-structure-03 | |||
| Abstract | Abstract | |||
| This document describes Structured Headers, a way of simplifying HTTP | This document describes a set of data types and parsing algorithms | |||
| header field definition and parsing. It is intended for use by new | associated with them that are intended to make it easier and safer to | |||
| specifications of HTTP header fields. This includes revisions of | define and handle HTTP header fields. It is intended for use by new | |||
| existing specifications when doing so does not cause interoperability | specifications of HTTP header fields as well as revisions of existing | |||
| issues. | header field specifications when doing so does not cause | |||
| interoperability issues. | ||||
| Note to Readers | Note to Readers | |||
| _RFC EDITOR: please remove this section before publication_ | ||||
| Discussion of this draft takes place on the HTTP working group | Discussion of this draft takes place on the HTTP working group | |||
| mailing list (ietf-http-wg@w3.org), which is archived at | mailing list (ietf-http-wg@w3.org), which is archived at | |||
| https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. | https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. | |||
| _RFC EDITOR: please remove this section before publication_ | ||||
| Working Group information can be found at https://httpwg.github.io/ | Working Group information can be found at https://httpwg.github.io/ | |||
| [2]; source code and issues list for this draft can be found at | [2]; source code and issues list for this draft can be found at | |||
| https://github.com/httpwg/http-extensions/labels/header-structure | https://github.com/httpwg/http-extensions/labels/header-structure | |||
| [3]. | [3]. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| 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 31, 2018. | This Internet-Draft will expire on August 5, 2018. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2017 IETF Trust and the persons identified as the | Copyright (c) 2018 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 | ||||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | ||||
| 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 3 | ||||
| 2. Specifying Structured Headers . . . . . . . . . . . . . . . . 4 | ||||
| 3. Parsing Text into Structured Headers . . . . . . . . . . . . 5 | ||||
| 4. Structured Header Data Types . . . . . . . . . . . . . . . . 6 | ||||
| 4.1. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 6 | ||||
| 4.2. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | ||||
| 4.3. Parameterised Labels . . . . . . . . . . . . . . . . . . 9 | ||||
| 4.4. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 10 | ||||
| 4.5. Integers . . . . . . . . . . . . . . . . . . . . . . . . 11 | ||||
| 4.6. Floats . . . . . . . . . . . . . . . . . . . . . . . . . 11 | ||||
| 4.7. Strings . . . . . . . . . . . . . . . . . . . . . . . . . 12 | ||||
| 4.8. Labels . . . . . . . . . . . . . . . . . . . . . . . . . 14 | ||||
| 4.9. Binary Content . . . . . . . . . . . . . . . . . . . . . 15 | ||||
| 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 | ||||
| 6. Security Considerations . . . . . . . . . . . . . . . . . . . 16 | ||||
| 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 | ||||
| 7.1. Normative References . . . . . . . . . . . . . . . . . . 16 | ||||
| 7.2. Informative References . . . . . . . . . . . . . . . . . 17 | ||||
| 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 17 | ||||
| Appendix A. Changes . . . . . . . . . . . . . . . . . . . . . . 17 | ||||
| A.1. Since draft-ietf-httpbis-header-structure-02 . . . . . . 17 | ||||
| A.2. Since draft-ietf-httpbis-header-structure-01 . . . . . . 18 | ||||
| A.3. Since draft-ietf-httpbis-header-structure-00 . . . . . . 18 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 | ||||
| 1. Introduction | 1. Introduction | |||
| Specifying the syntax of new HTTP header fields is an onerous task; | Specifying the syntax of new HTTP header fields is an onerous task; | |||
| even with the guidance in [RFC7231], Section 8.3.1, there are many | even with the guidance in [RFC7231], Section 8.3.1, there are many | |||
| decisions - and pitfalls - for a prospective HTTP header field | decisions - and pitfalls - for a prospective HTTP header field | |||
| author. | author. | |||
| Likewise, bespoke parsers often need to be written for specific HTTP | Once a header field is defined, bespoke parsers for it often need to | |||
| headers, because each has slightly different handling of what looks | be written, because each header has slightly different handling of | |||
| like common syntax. | what looks like common syntax. | |||
| This document introduces structured HTTP header field values | This document introduces structured HTTP header field values | |||
| (hereafter, Structured Headers) to address these problems. | (hereafter, Structured Headers) to address these problems. | |||
| Structured Headers define a generic, abstract model for data, along | Structured Headers define a generic, abstract model for header field | |||
| with a concrete serialisation for expressing that model in textual | values, along with a concrete serialisation for expressing that model | |||
| HTTP headers, as used by HTTP/1 [RFC7230] and HTTP/2 [RFC7540]. | in textual HTTP headers, as used by HTTP/1 [RFC7230] and HTTP/2 | |||
| [RFC7540]. | ||||
| HTTP headers that are defined as Structured Headers use the types | HTTP headers that are defined as Structured Headers use the types | |||
| defined in this specification to define their syntax and basic | defined in this specification to define their syntax and basic | |||
| handling rules, thereby simplifying both their definition and | handling rules, thereby simplifying both their definition and | |||
| parsing. | parsing. | |||
| Additionally, future versions of HTTP can define alternative | Additionally, future versions of HTTP can define alternative | |||
| serialisations of the abstract model of Structured Headers, allowing | serialisations of the abstract model of Structured Headers, allowing | |||
| headers that use it to be transmitted more efficiently without being | headers that use it to be transmitted more efficiently without being | |||
| redefined. | redefined. | |||
| Note that it is not a goal of this document to redefine the syntax of | Note that it is not a goal of this document to redefine the syntax of | |||
| existing HTTP headers; the mechanisms described herein are only | existing HTTP headers; the mechanisms described herein are only | |||
| intended to be used with headers that explicitly opt into them. | intended to be used with headers that explicitly opt into them. | |||
| To specify a header field that uses Structured Headers, see | To specify a header field that uses Structured Headers, see | |||
| Section 2. | Section 2. | |||
| Section 4 defines a number of abstract data types that can be used in | Section 4 defines a number of abstract data types that can be used in | |||
| Structured Headers, of which only three are allowed at the "top" | Structured Headers. Dictionaries and lists are only usable at the | |||
| level: lists, dictionaries, or items. | "top" level, while the remaining types can be specified appear at the | |||
| top level or inside those structures. | ||||
| Those abstract types can be serialised into textual headers - such as | Those abstract types can be serialised into textual headers - such as | |||
| those used in HTTP/1 and HTTP/2 - using the algorithms described in | those used in HTTP/1 and HTTP/2 - using the algorithms described in | |||
| Section 3. | Section 3. | |||
| 1.1. Notational Conventions | 1.1. Notational Conventions | |||
| 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 the Augmented Backus-Naur Form (ABNF) notation of | This document uses the Augmented Backus-Naur Form (ABNF) notation of | |||
| [RFC5234], including the DIGIT, ALPHA and DQUOTE rules from that | [RFC5234], including the DIGIT, ALPHA and DQUOTE rules from that | |||
| document. It also includes the OWS rule from [RFC7230]. | document. It also includes the OWS rule from [RFC7230]. | |||
| 2. Specifying Structured Headers | 2. Specifying Structured Headers | |||
| HTTP headers that use Structured Headers need to be defined to do so | A HTTP header that uses Structured Headers need to be defined to do | |||
| explicitly; recipients and generators need to know that the | so explicitly; recipients and generators need to know that the | |||
| requirements of this document are in effect. The simplest way to do | requirements of this document are in effect. The simplest way to do | |||
| that is by referencing this document in its definition. | that is by referencing this document in its definition. | |||
| The field's definition will also need to specify the field-value's | The field's definition will also need to specify the field-value's | |||
| allowed syntax, in terms of the types described in Section 4, along | allowed syntax, in terms of the types described in Section 4, along | |||
| with their associated semantics. | with their associated semantics. | |||
| Field definitions MUST NOT relax or otherwise modify the requirements | A header field definition cannot relax or otherwise modify the | |||
| of this specification; doing so would preclude handling by generic | requirements of this specification; doing so would preclude handling | |||
| software. | by generic software. | |||
| However, field definitions are encouraged to clearly state additional | However, header field authors are encouraged to clearly state | |||
| constraints upon the syntax, as well as the consequences when those | additional constraints upon the syntax, as well as the consequences | |||
| constraints are violated. | when those constraints are violated. Such additional constraints | |||
| could include additional structure (e.g., a list of URLs [RFC3986] | ||||
| inside a string) that cannot be expressed using the primitives | ||||
| defined here. | ||||
| For example: | For example: | |||
| # FooExample Header | # FooExample Header | |||
| The FooExample HTTP header field conveys a list of numbers about how | The FooExample HTTP header field conveys a list of integers about how | |||
| much Foo the sender has. | much Foo the sender has. | |||
| FooExample is a Structured header [RFCxxxx]. Its value MUST be a | FooExample is a Structured header [RFCxxxx]. Its value MUST be a | |||
| dictionary ([RFCxxxx], Section Y.Y). | dictionary ([RFCxxxx], Section Y.Y). | |||
| The dictionary MUST contain: | The dictionary MUST contain: | |||
| * A member whose key is "foo", and whose value is an integer | * A member whose key is "foo", and whose value is an integer | |||
| ([RFCxxxx], Section Y.Y), indicating the number of foos in | ([RFCxxxx], Section Y.Y), indicating the number of foos in | |||
| the message. | the message. | |||
| * A member whose key is "bar", and whose value is a string | * A member whose key is "barUrls", and whose value is a string | |||
| ([RFCxxxx], Section Y.Y), conveying the characteristic bar-ness | ([RFCxxxx], Section Y.Y), conveying the Bar URLs for the message. | |||
| of the message. | See below for processing requirements. | |||
| If the parsed header field does not contain both, it MUST be ignored. | If the parsed header field does not contain both, it MUST be ignored. | |||
| "barUrls" contains a space-separated list of URI-references ([RFC3986], | ||||
| Section 4.1): | ||||
| barURLs = URI-reference *( 1*SP URI-reference ) | ||||
| If a member of barURLs is not a valid URI-reference, it MUST be ignored. | ||||
| If a member of barURLs is a relative reference ([RFC3986], Section 4.2), | ||||
| it MUST be resolved ([RFC3986], Section 5) before being used. | ||||
| Note that empty header field values are not allowed by the syntax, | Note that empty header field values are not allowed by the syntax, | |||
| and therefore will be considered errors. | and therefore will be considered errors. | |||
| 3. Parsing Requirements for Textual Headers | 3. Parsing Text into Structured Headers | |||
| When a receiving implementation parses textual HTTP header fields | When a receiving implementation parses textual HTTP header fields | |||
| (e.g., in HTTP/1 or HTTP/2) that are known to be Structured Headers, | (e.g., in HTTP/1 or HTTP/2) that are known to be Structured Headers, | |||
| it is important that care be taken, as there are a number of edge | it is important that care be taken, as there are a number of edge | |||
| cases that can cause interoperability or even security problems. | cases that can cause interoperability or even security problems. | |||
| This section specifies the algorithm for doing so. | This section specifies the algorithm for doing so. | |||
| Given an ASCII string input_string that represents the chosen | Given an ASCII string input_string that represents the chosen | |||
| header's field-value, return the parsed header value. Note that | header's field-value, return the parsed header value. | |||
| input_string may incorporate multiple header lines combined into one | ||||
| comma-separated field-value, as per [RFC7230], Section 3.2.2. | ||||
| 1. Discard any OWS from the beginning of input_string. | 1. Discard any leading OWS from input_string. | |||
| 2. If the field-value is defined to be a dictionary, return the | 2. If the field-value is defined to be a dictionary, let output be | |||
| result of Parsing a Dictionary from Textual headers | the result of Parsing a Dictionary from Textual headers | |||
| (Section 4.7). | (Section 4.1.1). | |||
| 3. If the field-value is defined to be a list, return the result of | 3. If the field-value is defined to be a list, let output be the | |||
| Parsing a List from Textual Headers (Section 4.8). | result of Parsing a List from Text (Section 4.2.1). | |||
| 4. If the field-value is defined to be a parameterised label, return | 4. If the field-value is defined to be a parameterised label, let | |||
| the result of Parsing a Parameterised Label from Textual headers | output be the result of Parsing a Parameterised Label from | |||
| (Section 4.4). | Textual headers (Section 4.3.1). | |||
| 5. Otherwise, return the result of Parsing an Item from Textual | 5. Otherwise, let output be the result of Parsing an Item from Text | |||
| Headers (Section 4.6). | (Section 4.4.1). | |||
| 6. Discard any leading OWS from input_string. | ||||
| 7. If input_string is not empty, throw an error. | ||||
| 8. Otherwise, return output. | ||||
| When generating input_string for a given header field, parsers MUST | ||||
| combine all instances of it into one comma-separated field-value, as | ||||
| per [RFC7230], Section 3.2.2; this assures that the header is | ||||
| processed correctly. | ||||
| Note that in the case of lists and dictionaries, this has the effect | Note that in the case of lists and dictionaries, this has the effect | |||
| of combining multiple instances of the header field into one. | of coalescing all of the values for that field. However, for | |||
| However, for singular items and parameterised labels, it has the | singular items and parameterised labels, it will result in an error | |||
| effect of selecting the first value and ignoring any subsequent | being thrown. | |||
| instances of the field, as well as extraneous text afterwards. | ||||
| Additionally, note that the effect of the parsing algorithms as | Additionally, note that the effect of the parsing algorithms as | |||
| specified is generally intolerant of syntax errors; if one is | specified is generally intolerant of syntax errors; if one is | |||
| encountered, the typical response is to throw an error, thereby | encountered, the typical response is to throw an error, thereby | |||
| discarding the entire header field value. This includes any non- | discarding the entire header field value. This includes any non- | |||
| ASCII characters in input_string. | ASCII characters in input_string. | |||
| 4. Structured Header Data Types | 4. Structured Header Data Types | |||
| This section defines the abstract value types that can be composed | This section defines the abstract value types that can be composed | |||
| into Structured Headers, along with the textual HTTP serialisations | into Structured Headers, along with the textual HTTP serialisations | |||
| of them. | of them. | |||
| 4.1. Numbers | 4.1. Dictionaries | |||
| Abstractly, numbers are integers with an optional fractional part. | ||||
| They have a maximum of fifteen digits available to be used in one or | ||||
| both of the parts, as reflected in the ABNF below; this allows them | ||||
| to be stored as IEEE 754 double precision numbers (binary64) | ||||
| ([IEEE754]). | ||||
| The textual HTTP serialisation of numbers allows a maximum of fifteen | ||||
| digits between the integer and fractional part, along with an | ||||
| optional "-" indicating negative numbers. | ||||
| number = ["-"] ( "." 1*15DIGIT / | ||||
| DIGIT "." 1*14DIGIT / | ||||
| 2DIGIT "." 1*13DIGIT / | ||||
| 3DIGIT "." 1*12DIGIT / | ||||
| 4DIGIT "." 1*11DIGIT / | ||||
| 5DIGIT "." 1*10DIGIT / | ||||
| 6DIGIT "." 1*9DIGIT / | ||||
| 7DIGIT "." 1*8DIGIT / | ||||
| 8DIGIT "." 1*7DIGIT / | ||||
| 9DIGIT "." 1*6DIGIT / | ||||
| 10DIGIT "." 1*5DIGIT / | ||||
| 11DIGIT "." 1*4DIGIT / | ||||
| 12DIGIT "." 1*3DIGIT / | ||||
| 13DIGIT "." 1*2DIGIT / | ||||
| 14DIGIT "." 1DIGIT / | ||||
| 15DIGIT ) | ||||
| integer = ["-"] 1*15DIGIT | ||||
| unsigned = 1*15DIGIT | ||||
| integer and unsigned are defined as conveniences to specification | ||||
| authors; if their use is specified and their ABNF is not matched, a | ||||
| parser MUST consider it to be invalid. | ||||
| For example, a header whose value is defined as a number could look | ||||
| like: | ||||
| ExampleNumberHeader: 4.5 | ||||
| 4.1.1. Parsing Numbers from Textual Headers | ||||
| TBD | ||||
| 4.2. Strings | ||||
| Abstractly, strings are ASCII strings [RFC0020], excluding control | ||||
| characters (i.e., the range 0x20 to 0x7E). Note that this excludes | ||||
| tabs, newlines and carriage returns. They may be at most 1024 | ||||
| characters long. | ||||
| The textual HTTP serialisation of strings uses a backslash ("") to | Dictionaries are unordered maps of key-value pairs, where the keys | |||
| escape double quotes and backslashes in strings. | are labels (Section 4.8) and the values are items (Section 4.4). | |||
| There can be between 1 and 1024 members, and keys are required to be | ||||
| unique. | ||||
| string = DQUOTE 1*1024(char) DQUOTE | In the textual HTTP serialisation, keys and values are separated by | |||
| char = unescaped / escape ( DQUOTE / "\" ) | "=" (without whitespace), and key/value pairs are separated by a | |||
| unescaped = %x20-21 / %x23-5B / %x5D-7E | comma with optional whitespace. Duplicate keys MUST be considered an | |||
| escape = "\" | error. | |||
| For example, a header whose value is defined as a string could look | ||||
| like: | ||||
| ExampleStringHeader: "hello world" | dictionary = label "=" item *1023( OWS "," OWS label "=" item ) | |||
| Note that strings only use DQUOTE as a delimiter; single quotes do | For example, a header field whose value is defined as a dictionary | |||
| not delimit strings. Furthermore, only DQUOTE and "" can be escaped; | could look like: | |||
| other sequences MUST generate an error. | ||||
| Unicode is not directly supported in Structured Headers, because it | ExampleDictHeader: foo=1.23, en="Applepie", da=*w4ZibGV0w6ZydGUK | |||
| causes a number of interoperability issues, and - with few exceptions | ||||
| - header values do not require it. | ||||
| When it is necessary for a field value to convey non-ASCII string | Typically, a header field specification will define the semantics of | |||
| content, binary content (Section 4.5) SHOULD be specified, along with | individual keys, as well as whether their presence is required or | |||
| a character encoding (most likely, UTF-8). | optional. Recipients MUST ignore keys that are undefined or unknown, | |||
| unless the header field's specification specifically disallows them. | ||||
| 4.2.1. Parsing a String from Textual Headers | 4.1.1. Parsing a Dictionary from Text | |||
| Given an ASCII string input_string, return an unquoted string. | Given an ASCII string input_string, return a mapping of (label, | |||
| input_string is modified to remove the parsed value. | item). input_string is modified to remove the parsed value. | |||
| 1. Let output_string be an empty string. | 1. Let dictionary be an empty, unordered mapping. | |||
| 2. If the first character of input_string is not DQUOTE, throw an | 2. While input_string is not empty: | |||
| error. | ||||
| 3. Discard the first character of input_string. | 1. Let this_key be the result of running Parse Label from Text | |||
| (Section 4.8.1) with input_string. If an error is | ||||
| encountered, throw it. | ||||
| 4. If input_string contains more than 1025 characters, throw an | 2. If dictionary already contains this_key, throw an error. | |||
| error. | ||||
| 5. While input_string is not empty: | 3. Consume a "=" from input_string; if none is present, throw | |||
| an error. | ||||
| 1. Let char be the result of removing the first character of | 4. Let this_value be the result of running Parse Item from Text | |||
| input_string. | (Section 4.4.1) with input_string. If an error is | |||
| encountered, throw it. | ||||
| 2. If char is a backslash ("\"): | 5. Add key this_key with value this_value to dictionary. | |||
| 1. If input_string is now empty, throw an error. | 6. If dictionary has more than 1024 members, throw an error. | |||
| 2. Else: | 7. Discard any leading OWS from input_string. | |||
| 1. Let next_char be the result of removing the first | 8. If input_string is empty, return dictionary. | |||
| character of input_string. | ||||
| 2. If next_char is not DQUOTE or "\", throw an error. | 9. Consume a COMMA from input_string; if no comma is present, | |||
| throw an error. | ||||
| 3. Append next_char to output_string. | 10. Discard any leading OWS from input_string. | |||
| 3. Else, if char is DQUOTE, remove the first character of | 3. Return dictionary. | |||
| input_string and return output_string. | ||||
| 4. Else, append char to output_string. | 4.2. Lists | |||
| 6. Otherwise, throw an error. | Lists are arrays of items (Section 4.4) or parameterised labels | |||
| (Section 4.3), with one to 1024 members. | ||||
| 4.3. Labels | In the textual HTTP serialisation, each member is separated by a | |||
| comma and optional whitespace. | ||||
| Labels are short (up to 256 characters) textual identifiers; their | list = list_member 0*1023( OWS "," OWS list_member ) | |||
| abstract model is identical to their expression in the textual HTTP | list_member = item / parameterised | |||
| serialisation. | ||||
| label = lcalpha *255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) | For example, a header field whose value is defined as a list of | |||
| lcalpha = %x61-7A ; a-z | labels could look like: | |||
| Note that labels can only contain lowercase letters. | ExampleLabelListHeader: foo, bar, baz_45 | |||
| For example, a header whose value is defined as a label could look | and a header field whose value is defined as a list of parameterised | |||
| like: | labels could look like: | |||
| ExampleLabelHeader: foo/bar | ExampleParamListHeader: abc/def; g="hi";j, klm/nop | |||
| 4.3.1. Parsing a Label from Textual Headers | 4.2.1. Parsing a List from Text | |||
| Given an ASCII string input_string, return a label. input_string is | Given an ASCII string input_string, return a list of items. | |||
| modified to remove the parsed value. | input_string is modified to remove the parsed value. | |||
| 1. If input_string contains more than 256 characters, throw an | 1. Let items be an empty array. | |||
| error. | ||||
| 2. If the first character of input_string is not lcalpha, throw an | 2. While input_string is not empty: | |||
| error. | ||||
| 3. Let output_string be an empty string. | 1. Let item be the result of running Parse Item from Text | |||
| (Section 4.4.1) with input_string. If an error is | ||||
| encountered, throw it. | ||||
| 4. While input_string is not empty: | 2. Append item to items. | |||
| 1. Let char be the result of removing the first character of | 3. If items has more than 1024 members, throw an error. | |||
| input_string. | ||||
| 2. If char is not one of lcalpha, DIGIT, "_", "-", "*" or "/": | 4. Discard any leading OWS from input_string. | |||
| 1. Prepend char to input_string. | 5. If input_string is empty, return items. | |||
| 2. Return output_string. | 6. Consume a COMMA from input_string; if no comma is present, | |||
| throw an error. | ||||
| 3. Append char to output_string. | 7. Discard any leading OWS from input_string. | |||
| 5. Return output_string. | 3. Return items. | |||
| 4.4. Parameterised Labels | 4.3. Parameterised Labels | |||
| Parameterised Labels are labels (Section 4.3) with up to 256 | Parameterised Labels are labels (Section 4.8) with up to 256 | |||
| parameters; each parameter has a label and an optional value that is | parameters; each parameter has a label and an optional value that is | |||
| an item (Section 4.6). Ordering between parameters is not | an item (Section 4.4). Ordering between parameters is not | |||
| significant, and duplicate parameters MUST be considered an error. | significant, and duplicate parameters MUST be considered an error. | |||
| The textual HTTP serialisation uses semicolons (";") to delimit the | The textual HTTP serialisation uses semicolons (";") to delimit the | |||
| parameters from each other, and equals ("=") to delimit the parameter | parameters from each other, and equals ("=") to delimit the parameter | |||
| name from its value. | name from its value. | |||
| parameterised = label *256( OWS ";" OWS label [ "=" item ] ) | parameterised = label *256( OWS ";" OWS label [ "=" item ] ) | |||
| For example, | For example, | |||
| ExampleParamHeader: abc; a=1; b=2; c | ExampleParamHeader: abc_123;a=1;b=2; c | |||
| 4.4.1. Parsing a Parameterised Label from Textual Headers | 4.3.1. Parsing a Parameterised Label from Text | |||
| Given an ASCII string input_string, return a label with an mapping of | Given an ASCII string input_string, return a label with an mapping of | |||
| parameters. input_string is modified to remove the parsed value. | parameters. input_string is modified to remove the parsed value. | |||
| 1. Let primary_label be the result of Parsing a Label from Textual | 1. Let primary_label be the result of Parsing a Label from Text | |||
| Headers (Section 4.3) from input_string. | (Section 4.8.1) from input_string. | |||
| 2. Let parameters be an empty mapping. | 2. Let parameters be an empty, unordered mapping. | |||
| 3. In a loop: | 3. In a loop: | |||
| 1. Consume any OWS from the beginning of input_string. | 1. Discard any leading OWS from input_string. | |||
| 2. If the first character of input_string is not ";", exit the | 2. If the first character of input_string is not ";", exit the | |||
| loop. | loop. | |||
| 3. Consume a ";" character from the beginning of input_string. | 3. Consume a ";" character from the beginning of input_string. | |||
| 4. Consume any OWS from the beginning of input_string. | 4. Discard any leading OWS from input_string. | |||
| 5. let param_name be the result of Parsing a Label from Textual | 5. let param_name be the result of Parsing a Label from Text | |||
| Headers (Section 4.3) from input_string. | (Section 4.8.1) from input_string. | |||
| 6. If param_name is already present in parameters, throw an | 6. If param_name is already present in parameters, throw an | |||
| error. | error. | |||
| 7. Let param_value be a null value. | 7. Let param_value be a null value. | |||
| 8. If the first character of input_string is "=": | 8. If the first character of input_string is "=": | |||
| 1. Consume the "=" character at the beginning of | 1. Consume the "=" character at the beginning of | |||
| input_string. | input_string. | |||
| 2. Let param_value be the result of Parsing an Item from | 2. Let param_value be the result of Parsing an Item from | |||
| Textual Headers (Section 4.6) from input_string. | Text (Section 4.4.1) from input_string. | |||
| 9. If parameters has more than 255 members, throw an error. | 9. If parameters has more than 255 members, throw an error. | |||
| 10. Add param_name to parameters with the value param_value. | 10. Add param_name to parameters with the value param_value. | |||
| 4. Return the tuple (primary_label, parameters). | 4. Return the tuple (primary_label, parameters). | |||
| 4.5. Binary Content | 4.4. Items | |||
| Arbitrary binary content up to 16K in size can be conveyed in | An item is can be a integer (Section 4.5), float (Section 4.6), | |||
| Structured Headers. | string (Section 4.7), label (Section 4.8) or binary content | |||
| (Section 4.9). | ||||
| The textual HTTP serialisation indicates their presence by a leading | item = integer / float / string / label / binary | |||
| "*", with the data encoded using Base 64 Encoding [RFC4648], without | ||||
| padding (as "=" might be confused with the use of dictionaries). | ||||
| binary = "*" 1*21846(base64) | 4.4.1. Parsing an Item from Text | |||
| base64 = ALPHA / DIGIT / "+" / "/" | ||||
| For example, a header whose value is defined as binary content could | Given an ASCII string input_string, return an item. input_string is | |||
| look like: | modified to remove the parsed value. | |||
| ExampleBinaryHeader: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg | 1. Discard any leading OWS from input_string. | |||
| 4.5.1. Parsing Binary Content from Textual Headers | 2. If the first character of input_string is a "-" or a DIGIT, | |||
| process input_string as a number (Section 4.5.1) and return the | ||||
| result, throwing any errors encountered. | ||||
| Given an ASCII string input_string, return binary content. | 3. If the first character of input_string is a DQUOTE, process | |||
| input_string is modified to remove the parsed value. | input_string as a string (Section 4.7.1) and return the result, | |||
| throwing any errors encountered. | ||||
| 1. If the first character of input_string is not "*", throw an | 4. If the first character of input_string is "*", process | |||
| error. | input_string as binary content (Section 4.9.1) and return the | |||
| result, throwing any errors encountered. | ||||
| 2. Discard the first character of input_string. | 5. If the first character of input_string is an lcalpha, process | |||
| input_string as a label (Section 4.8.1) and return the result, | ||||
| throwing any errors encountered. | ||||
| 3. Let b64_content be the result of removing content of input_string | 6. Otherwise, throw an error. | |||
| up to but not including the first character that is not in ALPHA, | ||||
| DIGIT, "+" or "/". | ||||
| 4. Let binary_content be the result of Base 64 Decoding [RFC4648] | 4.5. Integers | |||
| b64_content, synthesising padding if necessary. If an error is | ||||
| encountered, throw it. | ||||
| 5. Return binary_content. | Abstractly, integers have a range of -9,223,372,036,854,775,808 to | |||
| 9,223,372,036,854,775,807 inclusive (i.e., a 64-bit signed integer). | ||||
| 4.6. Items | integer = ["-"] 1*19DIGIT | |||
| An item is can be a number (Section 4.1), string (Section 4.2), label | Parsers that encounter an integer outside the range defined above | |||
| (Section 4.3) or binary content (Section 4.5). | MUST throw an error. Therefore, the value "9223372036854775809" | |||
| would be invalid. Likewise, values that do not conform to the ABNF | ||||
| above are invalid, and MUST throw an error. | ||||
| item = number / string / label / binary | For example, a header whose value is defined as a integer could look | |||
| like: | ||||
| 4.6.1. Parsing an Item from Textual Headers | ExampleIntegerHeader: 42 | |||
| Given an ASCII string input_string, return an item. input_string is | 4.5.1. Parsing a Number from Text | |||
| modified to remove the parsed value. | ||||
| 1. Discard any OWS from the beginning of input_string. | NOTE: This algorithm parses both Integers and Floats Section 4.6, and | |||
| returns the corresponding structure. | ||||
| 2. If the first character of input_string is a "-" or a DIGIT, | 1. If the first character of input_string is not "-" or a DIGIT, | |||
| process input_string as a number (Section 4.1) and return the | throw an error. | |||
| result, throwing any errors encountered. | ||||
| 3. If the first character of input_string is a DQUOTE, process | 2. Let input_number be the result of consuming input_string up to | |||
| input_string as a string (Section 4.2) and return the result, | (but not including) the first character that is not in DIGIT, | |||
| throwing any errors encountered. | "-", and ".". | |||
| 4. If the first character of input_string is "*", process | 3. If input_number contains ".", parse it as a floating point number | |||
| input_string as binary content (Section 4.5) and return the | and let output_number be the result. | |||
| result, throwing any errors encountered. | ||||
| 5. If the first character of input_string is an lcalpha, process | 4. Otherwise, parse input_number as an integer and let output_number | |||
| input_string as a label (Section 4.3) and return the result, | be the result. | |||
| throwing any errors encountered. | ||||
| 6. Otherwise, throw an error. | 5. Return output_number. | |||
| 4.7. Dictionaries | 4.6. Floats | |||
| Dictionaries are unordered maps of key-value pairs, where the keys | Abstractly, floats are integers with a fractional part. They have a | |||
| are labels (Section 4.3) and the values are items (Section 4.6). | maximum of fifteen digits available to be used in both of the parts, | |||
| There can be between 1 and 1024 members, and keys are required to be | as reflected in the ABNF below; this allows them to be stored as IEEE | |||
| unique. | 754 double precision numbers (binary64) ([IEEE754]). | |||
| In the textual HTTP serialisation, keys and values are separated by | The textual HTTP serialisation of floats allows a maximum of fifteen | |||
| "=" (without whitespace), and key/value pairs are separated by a | digits between the integer and fractional part, with at least one | |||
| comma with optional whitespace. | required on each side, along with an optional "-" indicating negative | |||
| numbers. | ||||
| dictionary = label "=" item *1023( OWS "," OWS label "=" item ) | float = ["-"] ( | |||
| DIGIT "." 1*14DIGIT / | ||||
| 2DIGIT "." 1*13DIGIT / | ||||
| 3DIGIT "." 1*12DIGIT / | ||||
| 4DIGIT "." 1*11DIGIT / | ||||
| 5DIGIT "." 1*10DIGIT / | ||||
| 6DIGIT "." 1*9DIGIT / | ||||
| 7DIGIT "." 1*8DIGIT / | ||||
| 8DIGIT "." 1*7DIGIT / | ||||
| 9DIGIT "." 1*6DIGIT / | ||||
| 10DIGIT "." 1*5DIGIT / | ||||
| 11DIGIT "." 1*4DIGIT / | ||||
| 12DIGIT "." 1*3DIGIT / | ||||
| 13DIGIT "." 1*2DIGIT / | ||||
| 14DIGIT "." 1DIGIT ) | ||||
| For example, a header field whose value is defined as a dictionary | Values that do not conform to the ABNF above are invalid, and MUST | |||
| could look like: | throw an error. | |||
| ExampleDictHeader: foo=1.23, en="Applepie", da=*w4ZibGV0w6ZydGUK | For example, a header whose value is defined as a float could look | |||
| like: | ||||
| Typically, a header field specification will define the semantics of | ExampleFloatHeader: 4.5 | |||
| individual keys, as well as whether their presence is required or | ||||
| optional. Recipients MUST ignore keys that are undefined or unknown, | ||||
| unless the header field's specification specifically disallows them. | ||||
| 4.7.1. Parsing a Dictionary from Textual Headers | See Section 4.5.1 for the parsing algorithm for floats. | |||
| Given an ASCII string input_string, return a mapping of (label, | 4.7. Strings | |||
| item). input_string is modified to remove the parsed value. | ||||
| 1. Let dictionary be an empty mapping. | Abstractly, strings are ASCII strings [RFC0020], excluding control | |||
| characters (i.e., the range 0x20 to 0x7E). Note that this excludes | ||||
| tabs, newlines and carriage returns. They may be at most 1024 | ||||
| characters long. | ||||
| 2. While input_string is not empty: | The textual HTTP serialisation of strings uses a backslash ("") to | |||
| escape double quotes and backslashes in strings. | ||||
| 1. Let this_key be the result of running Parse Label from | string = DQUOTE 0*1024(char) DQUOTE | |||
| Textual Headers (Section 4.3) with input_string. If an error | char = unescaped / escape ( DQUOTE / "\" ) | |||
| is encountered, throw it. | unescaped = %x20-21 / %x23-5B / %x5D-7E | |||
| escape = "\" | ||||
| 2. If dictionary already contains this_key, raise an error. | For example, a header whose value is defined as a string could look | |||
| like: | ||||
| 3. Consume a "=" from input_string; if none is present, raise an | ExampleStringHeader: "hello world" | |||
| Note that strings only use DQUOTE as a delimiter; single quotes do | ||||
| not delimit strings. Furthermore, only DQUOTE and "" can be escaped; | ||||
| other sequences MUST generate an error. | ||||
| Unicode is not directly supported in Structured Headers, because it | ||||
| causes a number of interoperability issues, and - with few exceptions | ||||
| - header values do not require it. | ||||
| When it is necessary for a field value to convey non-ASCII string | ||||
| content, binary content (Section 4.9) SHOULD be specified, along with | ||||
| a character encoding (most likely, UTF-8). | ||||
| 4.7.1. Parsing a String from Text | ||||
| Given an ASCII string input_string, return an unquoted string. | ||||
| input_string is modified to remove the parsed value. | ||||
| 1. Let output_string be an empty string. | ||||
| 2. If the first character of input_string is not DQUOTE, throw an | ||||
| error. | ||||
| 3. Discard the first character of input_string. | ||||
| 4. While input_string is not empty: | ||||
| 1. Let char be the result of removing the first character of | ||||
| input_string. | ||||
| 2. If char is a backslash ("\"): | ||||
| 1. If input_string is now empty, throw an error. | ||||
| 2. Else: | ||||
| 1. Let next_char be the result of removing the first | ||||
| character of input_string. | ||||
| 2. If next_char is not DQUOTE or "\", throw an error. | ||||
| 3. Append next_char to output_string. | ||||
| 3. Else, if char is DQUOTE, return output_string. | ||||
| 4. Else, append char to output_string. | ||||
| 5. If output_string contains more than 1024 characters, throw an | ||||
| error. | error. | |||
| 4. Let this_value be the result of running Parse Item from | 5. Otherwise, throw an error. | |||
| Textual Headers (Section 4.6) with input_string. If an error | ||||
| is encountered, throw it. | ||||
| 5. Add key this_key with value this_value to dictionary. | 4.8. Labels | |||
| 6. Discard any leading OWS from input_string. | Labels are short (up to 256 characters) textual identifiers; their | |||
| abstract model is identical to their expression in the textual HTTP | ||||
| serialisation. | ||||
| 7. If input_string is empty, return dictionary. | label = lcalpha *255( lcalpha / DIGIT / "_" / "-"/ "*" / "/" ) | |||
| lcalpha = %x61-7A ; a-z | ||||
| 8. Consume a COMMA from input_string; if no comma is present, | Note that labels can only contain lowercase letters. | |||
| raise an error. | ||||
| 9. Discard any leading OWS from input_string. | For example, a header whose value is defined as a label could look | |||
| like: | ||||
| 3. Return dictionary. | ExampleLabelHeader: foo/bar | |||
| 4.8. Lists | 4.8.1. Parsing a Label from Text | |||
| Lists are arrays of items (Section 4.6) or parameterised labels | Given an ASCII string input_string, return a label. input_string is | |||
| (Section 4.4, with one to 1024 members. | modified to remove the parsed value. | |||
| In the textual HTTP serialisation, each member is separated by a | 1. If the first character of input_string is not lcalpha, throw an | |||
| comma and optional whitespace. | error. | |||
| list = list_member 1*1024( OWS "," OWS list_member ) | 2. Let output_string be an empty string. | |||
| list_member = item / parameterised | ||||
| For example, a header field whose value is defined as a list of | 3. While input_string is not empty: | |||
| labels could look like: | ||||
| ExampleLabelListHeader: foo, bar, baz_45 | 1. Let char be the result of removing the first character of | |||
| input_string. | ||||
| and a header field whose value is defined as a list of parameterised | 2. If char is not one of lcalpha, DIGIT, "_", "-", "*" or "/": | |||
| labels could look like: | ||||
| ExampleParamListHeader: abc/def; g="hi";j, klm/nop | 1. Prepend char to input_string. | |||
| 4.8.1. Parsing a List from Textual Headers | 2. Return output_string. | |||
| Given an ASCII string input_string, return a list of items. | 3. Append char to output_string. | |||
| input_string is modified to remove the parsed value. | ||||
| 1. Let items be an empty array. | 4. If output_string contains more than 256 characters, throw an | |||
| error. | ||||
| 2. While input_string is not empty: | 4. Return output_string. | |||
| 1. Let item be the result of running Parse Item from Textual | 4.9. Binary Content | |||
| Headers (Section 4.6) with input_string. If an error is | ||||
| encountered, throw it. | ||||
| 2. Append item to items. | Arbitrary binary content up to 16K in size can be conveyed in | |||
| Structured Headers. | ||||
| 3. Discard any leading OWS from input_string. | The textual HTTP serialisation indicates their presence by a leading | |||
| "*", with the data encoded using Base 64 Encoding [RFC4648], | ||||
| Section 4. | ||||
| 4. If input_string is empty, return items. | Parsers MUST consider encoded data that is padded an error, as "=" | |||
| might be confused with the use of dictionaries). See [RFC4648], | ||||
| Section 3.2. | ||||
| 5. Consume a COMMA from input_string; if no comma is present, | Likewise, parsers MUST consider encoded data that has non-zero pad | |||
| raise an error. | bits an error. See [RFC4648], Section 3.5. | |||
| 6. Discard any leading OWS from input_string. | This specification does not relax the requirements in [RFC4648], | |||
| Section 3.1 and 3.3; therefore, parsers MUST consider characters | ||||
| outside the base64 alphabet and line feeds in encoded data as errors. | ||||
| 3. Return items. | binary = "*" 0*21846(base64) "*" | |||
| base64 = ALPHA / DIGIT / "+" / "/" | ||||
| For example, a header whose value is defined as binary content could | ||||
| look like: | ||||
| ExampleBinaryHeader: *cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg* | ||||
| 4.9.1. Parsing Binary Content from Text | ||||
| Given an ASCII string input_string, return binary content. | ||||
| input_string is modified to remove the parsed value. | ||||
| 1. If the first character of input_string is not "*", throw an | ||||
| error. | ||||
| 2. Discard the first character of input_string. | ||||
| 3. Let b64_content be the result of removing content of input_string | ||||
| up to but not including the first instance of the character "_". | ||||
| If there is not a "_" character before the end of input_string, | ||||
| throw an error. | ||||
| 4. Consume the "*" character at the beginning of input_string. | ||||
| 5. If b64_content is has more than 21846 characters, throw an error. | ||||
| 6. Let binary_content be the result of Base 64 Decoding [RFC4648] | ||||
| b64_content, synthesising padding if necessary. If an error is | ||||
| encountered, throw it (note the requirements about recipient | ||||
| behaviour in Section 4.9). | ||||
| 7. Return binary_content. | ||||
| 5. IANA Considerations | 5. IANA Considerations | |||
| This draft has no actions for IANA. | This draft has no actions for IANA. | |||
| 6. Security Considerations | 6. Security Considerations | |||
| TBD | TBD | |||
| 7. References | 7. References | |||
| skipping to change at page 14, line 49 ¶ | skipping to change at page 17, line 10 ¶ | |||
| [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
| 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
| May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| 7.2. Informative References | 7.2. Informative References | |||
| [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 2008, | [IEEE754] IEEE, "IEEE Standard for Floating-Point Arithmetic", 2008, | |||
| <http://grouper.ieee.org/groups/754/>. | <http://grouper.ieee.org/groups/754/>. | |||
| [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | ||||
| Resource Identifier (URI): Generic Syntax", STD 66, | ||||
| RFC 3986, DOI 10.17487/RFC3986, January 2005, | ||||
| <https://www.rfc-editor.org/info/rfc3986>. | ||||
| [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | |||
| Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | Protocol (HTTP/1.1): Semantics and Content", RFC 7231, | |||
| DOI 10.17487/RFC7231, June 2014, | DOI 10.17487/RFC7231, June 2014, | |||
| <https://www.rfc-editor.org/info/rfc7231>. | <https://www.rfc-editor.org/info/rfc7231>. | |||
| [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext | |||
| Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | Transfer Protocol Version 2 (HTTP/2)", RFC 7540, | |||
| DOI 10.17487/RFC7540, May 2015, | DOI 10.17487/RFC7540, May 2015, | |||
| <https://www.rfc-editor.org/info/rfc7540>. | <https://www.rfc-editor.org/info/rfc7540>. | |||
| 7.3. URIs | 7.3. URIs | |||
| [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
| [2] https://httpwg.github.io/ | [2] https://httpwg.github.io/ | |||
| [3] https://github.com/httpwg/http-extensions/labels/header-structure | [3] https://github.com/httpwg/http-extensions/labels/header-structure | |||
| Appendix A. Changes | Appendix A. Changes | |||
| A.1. Since draft-ietf-httpbis-header-structure-01 | A.1. Since draft-ietf-httpbis-header-structure-02 | |||
| Replaced with draft-nottingham-structured-headers. | o Split Numbers into Integers and Floats. | |||
| A.2. Since draft-ietf-httpbis-header-structure-00 | o Define number parsing. | |||
| Added signed 64bit integer type. | o Tighten up binary parsing and give it an explicit end delimiter. | |||
| Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1-unicode- | o Clarify that mappings are unordered. | |||
| string. | ||||
| Change h1_blob delimiter to ":" since "'" is valid t_char | o Allow zero-length strings. | |||
| o Improve string parsing algorithm. | ||||
| o Improve limits in algorithms. | ||||
| o Require parsers to combine header fields before processing. | ||||
| o Throw an error on trailing garbage. | ||||
| A.2. Since draft-ietf-httpbis-header-structure-01 | ||||
| o Replaced with draft-nottingham-structured-headers. | ||||
| A.3. Since draft-ietf-httpbis-header-structure-00 | ||||
| o Added signed 64bit integer type. | ||||
| o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- | ||||
| unicode-string. | ||||
| o Change h1_blob delimiter to ":" since "'" is valid t_char | ||||
| Authors' Addresses | Authors' Addresses | |||
| Mark Nottingham | Mark Nottingham | |||
| Fastly | Fastly | |||
| Email: mnot@mnot.net | Email: mnot@mnot.net | |||
| URI: https://www.mnot.net/ | URI: https://www.mnot.net/ | |||
| Poul-Henning Kamp | Poul-Henning Kamp | |||
| End of changes. 153 change blocks. | ||||
| 308 lines changed or deleted | 437 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/ | ||||