| rfc8941xml2.original.xml | rfc8941.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version='1.0' encoding='utf-8'?> | |||
| <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?> | ||||
| <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.3.8 --> | ||||
| <!DOCTYPE rfc SYSTEM "rfc2629.dtd" [ | ||||
| ]> | ||||
| <?rfc toc="yes"?> | ||||
| <?rfc tocindent="yes"?> | ||||
| <?rfc sortrefs="yes"?> | ||||
| <?rfc symrefs="yes"?> | ||||
| <?rfc strict="yes"?> | ||||
| <?rfc compact="yes"?> | ||||
| <?rfc comments="yes"?> | ||||
| <?rfc inline="yes"?> | ||||
| <?rfc tocdepth="3"?> | ||||
| <rfc ipr="trust200902" docName="draft-ietf-httpbis-header-structure-19" category | ||||
| ="std"> | ||||
| <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | ||||
| <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft | ||||
| -ietf-httpbis-header-structure-19" number="8941" submissionType="IETF" category= | ||||
| "std" consensus="true" obsoletes="" updates="" xml:lang="en" tocInclude="true" s | ||||
| ortRefs="true" symRefs="true" tocDepth="3" version="3"> | ||||
| <!-- xml2rfc v2v3 conversion 2.46.0 --> | ||||
| <front> | <front> | |||
| <title>Structured Field Values for HTTP</title> | <title>Structured Field Values for HTTP</title> | |||
| <seriesInfo name="RFC" value="8941"/> | ||||
| <author initials="M." surname="Nottingham" fullname="Mark Nottingham"> | <author initials="M." surname="Nottingham" fullname="Mark Nottingham"> | |||
| <organization>Fastly</organization> | <organization>Fastly</organization> | |||
| <address> | <address> | |||
| <postal> | ||||
| <city>Prahran</city> | ||||
| <region>VIC</region> | ||||
| <country>Australia</country> | ||||
| </postal> | ||||
| <email>mnot@mnot.net</email> | <email>mnot@mnot.net</email> | |||
| <uri>https://www.mnot.net/</uri> | <uri>https://www.mnot.net/</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author initials="P-H." surname="Kamp" fullname="Poul-Henning Kamp"> | <author initials="P-H." surname="Kamp" fullname="Poul-Henning Kamp"> | |||
| <organization>The Varnish Cache Project</organization> | <organization>The Varnish Cache Project</organization> | |||
| <address> | <address> | |||
| <email>phk@varnish-cache.org</email> | <email>phk@varnish-cache.org</email> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <date month="February" year="2021"/> | ||||
| <date /> | ||||
| <area>Applications and Real-Time</area> | <area>Applications and Real-Time</area> | |||
| <workgroup>HTTP</workgroup> | <workgroup>HTTP</workgroup> | |||
| <keyword>Internet-Draft</keyword> | ||||
| <abstract> | <abstract> | |||
| <t>This document describes a set of data types and associated algorithms | ||||
| <t>This document describes a set of data types and associated algorithms that ar | that are intended to make it easier and safer to define and handle HTTP | |||
| e intended to make it easier and safer to define and handle HTTP header and trai | header and trailer fields, known as "Structured Fields", "Structured | |||
| ler fields, known as “Structured Fields”, “Structured Headers”, or “Structured T | Headers", or "Structured Trailers". It is intended for use by | |||
| railers”. It is intended for use by specifications of new HTTP fields that wish | specifications of new HTTP fields that wish to use a common syntax that | |||
| to use a common syntax that is more restrictive than traditional HTTP field valu | is more restrictive than traditional HTTP field values.</t> | |||
| es.</t> | ||||
| </abstract> | </abstract> | |||
| <note title="Note to Readers"> | ||||
| <t><spanx style="emph">RFC EDITOR: please remove this section before publication | ||||
| </spanx></t> | ||||
| <t>Discussion of this draft takes place on the HTTP working group mailing list ( | ||||
| ietf-http-wg@w3.org), which is archived at <eref target="https://lists.w3.org/Ar | ||||
| chives/Public/ietf-http-wg/">https://lists.w3.org/Archives/Public/ietf-http-wg/< | ||||
| /eref>.</t> | ||||
| <t>Working Group information can be found at <eref target="https://httpwg.github | ||||
| .io/">https://httpwg.github.io/</eref>; source code and issues list for this dra | ||||
| ft can be found at <eref target="https://github.com/httpwg/http-extensions/label | ||||
| s/header-structure">https://github.com/httpwg/http-extensions/labels/header-stru | ||||
| cture</eref>.</t> | ||||
| <t>Tests for implementations are collected at <eref target="https://github.com/h | ||||
| ttpwg/structured-field-tests">https://github.com/httpwg/structured-field-tests</ | ||||
| eref>.</t> | ||||
| <t>Implementations are tracked at <eref target="https://github.com/httpwg/wiki/w | ||||
| iki/Structured-Headers">https://github.com/httpwg/wiki/wiki/Structured-Headers</ | ||||
| eref>.</t> | ||||
| </note> | ||||
| </front> | </front> | |||
| <middle> | <middle> | |||
| <section anchor="introduction"> | ||||
| <name>Introduction</name> | ||||
| <t>Specifying the syntax of new HTTP header (and trailer) fields is an | ||||
| onerous task; even with the guidance in <xref target="RFC7231" section="8. | ||||
| 3.1"/>, there are many decisions -- and | ||||
| pitfalls -- for a prospective HTTP field author.</t> | ||||
| <t>Once a field is defined, bespoke parsers and serializers often need | ||||
| to be written, because each field value has a slightly different handling | ||||
| of what looks like common syntax.</t> | ||||
| <t>This document introduces a set of common data structures for use in | ||||
| definitions of new HTTP field values to address these problems. In | ||||
| particular, it defines a generic, abstract model for them, along with a | ||||
| concrete serialization for expressing that model in HTTP <xref target="RFC | ||||
| 7230"/> header and trailer fields.</t> | ||||
| <t>An HTTP field that is defined as a "Structured Header" or "Structured | ||||
| Trailer" (if the field can be either, it is a "Structured Field") uses | ||||
| the types defined in this specification to define its syntax and basic | ||||
| handling rules, thereby simplifying both its definition by specification | ||||
| writers and handling by implementations.</t> | ||||
| <t>Additionally, future versions of HTTP can define alternative | ||||
| serializations of the abstract model of these structures, allowing | ||||
| fields that use that model to be transmitted more efficiently without | ||||
| being redefined.</t> | ||||
| <t>Note that it is not a goal of this document to redefine the syntax of | ||||
| existing HTTP fields; the mechanisms described herein are only intended | ||||
| to be used with fields that explicitly opt into them.</t> | ||||
| <t><xref target="specify"/> describes how to specify a | ||||
| Structured Field.</t> | ||||
| <t><xref target="types"/> defines a number of abstract | ||||
| data types that can be used in Structured Fields.</t> | ||||
| <t>Those abstract types can be serialized into and parsed from HTTP | ||||
| field values using the algorithms described in <xref target="text"/>.</t> | ||||
| <section anchor="strict"> | ||||
| <name>Intentionally Strict Processing</name> | ||||
| <t>This specification intentionally defines strict parsing and | ||||
| serialization behaviors using step-by-step algorithms; the only error | ||||
| handling defined is to fail the operation altogether.</t> | ||||
| <t>It is designed to encourage faithful implementation and | ||||
| good interoperability. Therefore, an implementation that tried to be | ||||
| helpful by being more tolerant of input would make interoperability | ||||
| worse, since that would create pressure on other implementations to | ||||
| implement similar (but likely subtly different) workarounds.</t> | ||||
| <t>In other words, strict processing is an intentional feature of this | ||||
| specification; it allows non-conformant input to be discovered and | ||||
| corrected by the producer early and avoids both interoperability and | ||||
| security issues that might otherwise result.</t> | ||||
| <t>Note that as a result of this strictness, if a field is appended to | ||||
| by multiple parties (e.g., intermediaries or different components in | ||||
| the sender), an error in one party's value is likely to cause the | ||||
| entire field value to fail parsing.</t> | ||||
| </section> | ||||
| <section anchor="notational-conventions"> | ||||
| <name>Notational Conventions</name> | ||||
| <t> | ||||
| The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | ||||
| "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | ||||
| NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | ||||
| "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | ||||
| "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are | ||||
| to be interpreted as | ||||
| described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | ||||
| when, and only when, they appear in all capitals, as shown here. | ||||
| </t> | ||||
| <t>This document uses algorithms to specify parsing and serialization | ||||
| behaviors and the Augmented Backus-Naur Form (ABNF) notation of <xref tar | ||||
| get="RFC5234"/> to illustrate expected syntax in | ||||
| HTTP header fields. In doing so, it uses the VCHAR, SP, DIGIT, ALPHA, | ||||
| and DQUOTE rules from <xref target="RFC5234"/>. It | ||||
| also includes the tchar and OWS rules from <xref target="RFC7230"/>.</t> | ||||
| <t>When parsing from HTTP fields, implementations <bcp14>MUST</bcp14> ha | ||||
| ve behavior | ||||
| that is indistinguishable from following the algorithms. If there is | ||||
| disagreement between the parsing algorithms and ABNF, the specified | ||||
| algorithms take precedence.</t> | ||||
| <t>For serialization to HTTP fields, the ABNF illustrates their | ||||
| expected wire representations, and the algorithms define the | ||||
| recommended way to produce them. Implementations <bcp14>MAY</bcp14> vary | ||||
| from the | ||||
| specified behavior so long as the output is still correctly handled by | ||||
| the parsing algorithm described in <xref target="text-parse"/>.</t> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="specify"> | ||||
| <name>Defining New Structured Fields</name> | ||||
| <t>To specify an HTTP field as a Structured Field, its authors need to:</t | ||||
| > | ||||
| <ul> | ||||
| <li>Normatively reference this specification. Recipients and | ||||
| generators of the field need to know that the requirements of this | ||||
| document are in effect.</li> | ||||
| <li>Identify whether the field is a Structured Header (i.e., it can | ||||
| only be used in the header section -- the common case), a Structured | ||||
| Trailer (only in the trailer section), or a Structured Field | ||||
| (both).</li> | ||||
| <li>Specify the type of the field value; either List (<xref target="list | ||||
| "/>), Dictionary (<xref target="dictionary"/>), or Item (<xref target="item"/>). | ||||
| </li> | ||||
| <li>Define the semantics of the field value.</li> | ||||
| <li>Specify any additional constraints upon the field value, as well | ||||
| as the consequences when those constraints are violated.</li> | ||||
| </ul> | ||||
| <t>Typically, this means that a field definition will specify the | ||||
| top-level type -- List, Dictionary, or Item -- and then define its | ||||
| allowable 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 defined as an Item might allow only Strings, and additionally | ||||
| only strings beginning with the letter "Q", or strings in | ||||
| lowercase. Likewise, Inner Lists (<xref target="inner-list"/>) are only va | ||||
| lid when a field definition explicitly | ||||
| allows them.</t> | ||||
| <t>When parsing fails, the entire field is ignored (see <xref target="text | ||||
| -parse"/>); in most situations, violating | ||||
| field-specific 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 received, the field will by default be ignored. If the field requires | ||||
| different error handling, this should be explicitly specified.</t> | ||||
| <t>Both Items and Inner Lists allow parameters as an extensibility | ||||
| mechanism; this means that values can later be extended to accommodate | ||||
| more information, if need be. To preserve forward compatibility, field | ||||
| specifications are discouraged from defining the presence of an | ||||
| unrecognized parameter as an error condition.</t> | ||||
| <t>To further assure that this extensibility is available in the future, | ||||
| and to encourage consumers to use a complete parser implementation, a | ||||
| field definition can specify that "grease" parameters be added by | ||||
| senders. A specification could stipulate that all parameters that fit a | ||||
| defined pattern are reserved for this use and then encourage them to be | ||||
| sent on some portion of requests. This helps to discourage recipients | ||||
| from writing a parser that does not account for Parameters.</t> | ||||
| <t>Specifications that use Dictionaries can also allow for forward | ||||
| compatibility by requiring that the presence of -- as well as value and | ||||
| type associated with -- unknown members be ignored. Subsequent specificati | ||||
| ons | ||||
| can then add additional members, specifying constraints on them as | ||||
| appropriate.</t> | ||||
| <t>An extension to a Structured Field can then require that an entire | ||||
| field value be ignored by a recipient that understands the extension if | ||||
| constraints on the value it defines are not met.</t> | ||||
| <t>A field definition cannot relax the requirements of this | ||||
| specification because doing so would preclude handling by generic | ||||
| software; they can only add additional constraints (for example, on the | ||||
| numeric range of Integers and Decimals, the format of Strings and | ||||
| Tokens, the types allowed in a Dictionary's values, or the number of | ||||
| Items in a List). Likewise, field definitions can only use this | ||||
| specification for the entire field value, not a portion thereof.</t> | ||||
| <t>This specification defines minimums for the length or number of | ||||
| various structures supported by implementations. It does not specify | ||||
| maximum sizes in most cases, but authors should be aware that HTTP | ||||
| implementations do impose various limits on the size of individual | ||||
| fields, the total number of fields, and/or the size of the entire header | ||||
| or trailer section.</t> | ||||
| <t>Specifications can refer to a field name as a "structured header | ||||
| name", "structured trailer name", or "structured field name" as | ||||
| appropriate. Likewise, they can refer its field value as a "structured | ||||
| header value", "structured trailer value", or "structured field value" as | ||||
| necessary. | ||||
| Field definitions are encouraged to use the ABNF rules | ||||
| beginning with "sf-" defined in this specification; other rules in this | ||||
| specification are not intended to be used in field definitions.</t> | ||||
| <t>For example, a fictitious Foo-Example header field might be specified | ||||
| as:</t> | ||||
| <section anchor="introduction" title="Introduction"> | <blockquote> | |||
| <t>42. Foo-Example Header</t> | ||||
| <t>Specifying the syntax of new HTTP header (and trailer) fields is an onerous t | ||||
| ask; even with the guidance in Section 8.3.1 of <xref target="RFC7231"/>, there | ||||
| are many decisions – and pitfalls – for a prospective HTTP field author.</t> | ||||
| <t>Once a field is defined, bespoke parsers and serializers often need to be wri | ||||
| tten, because each field value has slightly different handling of what looks lik | ||||
| e common syntax.</t> | ||||
| <t>This document introduces a set of common data structures for use in definitio | ||||
| ns of new HTTP field values to address these problems. In particular, it defines | ||||
| a generic, abstract model for them, along with a concrete serialization for exp | ||||
| ressing that model in HTTP <xref target="RFC7230"/> header and trailer fields.</ | ||||
| t> | ||||
| <t>A HTTP field that is defined as a “Structured Header” or “Structured Trailer” | ||||
| (if the field can be either, it is a “Structured Field”) uses the types defined | ||||
| in this specification to define its syntax and basic handling rules, thereby si | ||||
| mplifying both its definition by specification writers and handling by implement | ||||
| ations.</t> | ||||
| <t>Additionally, future versions of HTTP can define alternative serializations o | ||||
| f the abstract model of these structures, allowing fields that use that model to | ||||
| be transmitted more efficiently without being redefined.</t> | ||||
| <t>Note that it is not a goal of this document to redefine the syntax of existin | ||||
| g HTTP fields; the mechanisms described herein are only intended to be used with | ||||
| fields that explicitly opt into them.</t> | ||||
| <t><xref target="specify"/> describes how to specify a Structured Field.</t> | ||||
| <t><xref target="types"/> defines a number of abstract data types that can be us | ||||
| ed in Structured Fields.</t> | ||||
| <t>Those abstract types can be serialized into and parsed from HTTP field values | ||||
| using the algorithms described in <xref target="text"/>.</t> | ||||
| <section anchor="strict" title="Intentionally Strict Processing"> | ||||
| <t>This specification intentionally defines strict parsing and serialization beh | ||||
| aviors using step-by-step algorithms; the only error handling defined is to fail | ||||
| the operation altogether.</t> | ||||
| <t>It is designed to encourage faithful implementation and therefore good intero | ||||
| perability. Therefore, an implementation that tried to be helpful by being more | ||||
| tolerant of input would make interoperability worse, since that would create pre | ||||
| ssure on other implementations to implement similar (but likely subtly different | ||||
| ) workarounds.</t> | ||||
| <t>In other words, strict processing is an intentional feature of this specifica | ||||
| tion; it allows non-conformant input to be discovered and corrected by the produ | ||||
| cer early, and avoids both interoperability and security issues that might other | ||||
| wise result.</t> | ||||
| <t>Note that as a result of this strictness, if a field is appended to by multip | ||||
| le parties (e.g., intermediaries, or different components in the sender), an err | ||||
| or in one party’s value is likely to cause the entire field value to fail parsin | ||||
| g.</t> | ||||
| </section> | ||||
| <section anchor="notational-conventions" title="Notational Conventions"> | ||||
| <t>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, | ||||
| “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and “OPTIONAL” in this d | ||||
| ocument are to be interpreted as described in BCP 14 <xref target="RFC2119"/> <x | ||||
| ref target="RFC8174"/> when, and only when, they appear in all capitals, as show | ||||
| n here.</t> | ||||
| <t>This document uses algorithms to specify parsing and serialization behaviors, | ||||
| and the Augmented Backus-Naur Form (ABNF) notation of <xref target="RFC5234"/> | ||||
| to illustrate expected syntax in HTTP header fields. In doing so, it uses the VC | ||||
| HAR, SP, DIGIT, ALPHA and DQUOTE rules from <xref target="RFC5234"/>. It also in | ||||
| cludes the tchar and OWS rules from <xref target="RFC7230"/>.</t> | ||||
| <t>When parsing from HTTP fields, implementations MUST have behavior that is ind | ||||
| istinguishable from following the algorithms. If there is disagreement between t | ||||
| he parsing algorithms and ABNF, the specified algorithms take precedence.</t> | ||||
| <t>For serialization to HTTP fields, the ABNF illustrates their expected wire re | ||||
| presentations, and the algorithms define the recommended way to produce them. Im | ||||
| plementations MAY vary from the specified behavior so long as the output is stil | ||||
| l correctly handled by the parsing algorithm.</t> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="specify" title="Defining New Structured Fields"> | ||||
| <t>To specify a HTTP field as a Structured Field, its authors needs to:</t> | ||||
| <t><list style="symbols"> | ||||
| <t>Normatively reference this specification. Recipients and generators of the | ||||
| field need to know that the requirements of this document are in effect.</t> | ||||
| <t>Identify whether the field is a Structured Header (i.e., it can only be use | ||||
| d in the header section - the common case), a Structured Trailer (only in the tr | ||||
| ailer section), or a Structured Field (both).</t> | ||||
| <t>Specify the type of the field value; either List (<xref target="list"/>), D | ||||
| ictionary (<xref target="dictionary"/>), or Item (<xref target="item"/>).</t> | ||||
| <t>Define the semantics of the field value.</t> | ||||
| <t>Specify any additional constraints upon the field value, as well as the con | ||||
| sequences when those constraints are violated.</t> | ||||
| </list></t> | ||||
| <t>Typically, this means that a field definition will specify the top-level type | ||||
| – List, Dictionary or Item – and then define its allowable types, and constrain | ||||
| ts upon them. For example, a header defined as a List might have all Integer mem | ||||
| bers, or a mix of types; a header defined as an Item might allow only Strings, a | ||||
| nd additionally only strings beginning with the letter “Q”, or strings in lowerc | ||||
| ase. Likewise, Inner Lists (<xref target="inner-list"/>) are only valid when a f | ||||
| ield definition explicitly allows them.</t> | ||||
| <t>When parsing fails, the entire field is ignored (see <xref target="text-parse | ||||
| "/>); in most situations, violating field-specific constraints should have the s | ||||
| ame effect. Thus, if a header is defined as an Item and required to be an Intege | ||||
| r, but a String is received, the field will by default be ignored. If the field | ||||
| requires different error handling, this should be explicitly specified.</t> | ||||
| <t>Both Items and Inner Lists allow parameters as an extensibility mechanism; th | ||||
| is means that values can later be extended to accommodate more information, if n | ||||
| eed be. To preserve forward compatibility, field specifications are discouraged | ||||
| from defining the presence of an unrecognized Parameter as an error condition.</ | ||||
| t> | ||||
| <t>To further assure that this extensibility is available in the future, and to | ||||
| encourage consumers to use a complete parser implementation, a field definition | ||||
| can specify that “grease” Parameters be added by senders. A specification could | ||||
| stipulate that all Parameters that fit a defined pattern are reserved for this u | ||||
| se and then encourage them to be sent on some portion of requests. This helps to | ||||
| discourage recipients from writing a parser that does not account for Parameter | ||||
| s.</t> | ||||
| <t>Specifications that use Dictionaries can also allow for forward compatibility | ||||
| by requiring that the presence of – as well as value and type associated with – | ||||
| unknown members be ignored. Later specifications can then add additional member | ||||
| s, specifying constraints on them as appropriate.</t> | ||||
| <t>An extension to a structured field can then require that an entire field valu | ||||
| e be ignored by a recipient that understands the extension if constraints on the | ||||
| value it defines are not met.</t> | ||||
| <t>A field definition cannot relax the requirements of this specification becaus | ||||
| e doing so would preclude handling by generic software; they can only add additi | ||||
| onal constraints (for example, on the numeric range of Integers and Decimals, th | ||||
| e format of Strings and Tokens, the types allowed in a Dictionary’s values, or t | ||||
| he number of Items in a List). Likewise, field definitions can only use this spe | ||||
| cification for the entire field value, not a portion thereof.</t> | ||||
| <t>This specification defines minimums for the length or number of various struc | ||||
| tures supported by implementations. It does not specify maximum sizes in most ca | ||||
| ses, but authors should be aware that HTTP implementations do impose various lim | ||||
| its on the size of individual fields, the total number of fields, and/or the siz | ||||
| e of the entire header or trailer section.</t> | ||||
| <t>Specifications can refer to a field name as a “structured header name”, “stru | ||||
| ctured trailer name” or “structured field name” as appropriate. Likewise, they c | ||||
| an refer its field value as a “structured header value”, “structured trailer val | ||||
| ue” or “structured field value” as necessary. Field definitions are encouraged t | ||||
| o use the ABNF rules beginning with “sf-“ defined in this specification; other r | ||||
| ules in this specification are not intended for their use.</t> | ||||
| <t>For example, a fictitious Foo-Example header field might be specified as:</t> | ||||
| <figure><artwork type="example"><![CDATA[ | ||||
| 42. Foo-Example Header | ||||
| The Foo-Example HTTP header field conveys information about how | <t>The Foo-Example HTTP header field conveys information about how | |||
| much Foo the message has. | much Foo the message has.</t> | |||
| Foo-Example is a Item Structured Header [RFCxxxx]. Its value MUST be | <t>Foo-Example is an Item Structured Header [RFC8941]. Its value MUST be | |||
| an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is: | an Integer (Section 3.3.1 of [RFC8941]). Its ABNF is:</t> | |||
| Foo-Example = sf-integer | <artwork> | |||
| Foo-Example = sf-integer | ||||
| </artwork> | ||||
| Its value indicates the amount of Foo in the message, and MUST | <t>Its value indicates the amount of Foo in the message, and it MUST | |||
| be between 0 and 10, inclusive; other values MUST cause | be between 0 and 10, inclusive; other values MUST cause | |||
| the entire header field to be ignored. | the entire header field to be ignored.</t> | |||
| The following parameters are defined: | <t>The following parameter is defined:</t> | |||
| * A Parameter whose name is "foourl", and whose value is a String | ||||
| (Section Y.Y of [RFCxxxx]), conveying the Foo URL | ||||
| for the message. See below for processing requirements. | ||||
| "foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | <ul> | |||
| <li>A parameter whose key is "foourl", and whose value is a String | ||||
| (Section 3.3.3 of [RFC8941]), conveying the Foo URL | ||||
| for the message. See below for processing requirements.</li> | ||||
| </ul> | ||||
| <t>"foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | ||||
| its value is not a valid URI-reference, the entire header field | its value is not a valid URI-reference, the entire header field | |||
| MUST be ignored. If its value is a relative reference (Section 4.2 | MUST be ignored. If its value is a relative reference (Section 4.2 | |||
| of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | |||
| being used. | being used.</t> | |||
| For example: | ||||
| Foo-Example: 2; foourl="https://foo.example.com/" | ||||
| ]]></artwork></figure> | ||||
| </section> | ||||
| <section anchor="types" title="Structured Data Types"> | ||||
| <t>This section defines the abstract types for Structured Fields. The ABNF provi | ||||
| ded represents the on-wire format in HTTP field values.</t> | ||||
| <t>In summary:</t> | ||||
| <t><list style="symbols"> | ||||
| <t>There are three top-level types that a HTTP field can be defined as: Lists, | ||||
| Dictionaries, and Items.</t> | ||||
| <t>Lists and Dictionaries are containers; their members can be Items or Inner | ||||
| Lists (which are themselves arrays of Items).</t> | ||||
| <t>Both Items and Inner Lists can be parameterized with key/value pairs.</t> | ||||
| </list></t> | ||||
| <section anchor="list" title="Lists"> | ||||
| <t>Lists are arrays of zero or more members, each of which can be an Item (<xref target="item"/>) or an Inner List (<xref target="inner-list"/>), both of which can be Parameterized (<xref target="param"/>).</t> | <t>For example:</t> | |||
| <t>The ABNF for Lists in HTTP fields is:</t> | <artwork> | |||
| Foo-Example: 2; foourl="https://foo.example.com/" | ||||
| </artwork> | ||||
| </blockquote> | ||||
| <figure><artwork type="abnf"><![CDATA[ | </section> | |||
| <section anchor="types"> | ||||
| <name>Structured Data Types</name> | ||||
| <t>This section defines the abstract types for Structured Fields. The | ||||
| ABNF provided represents the on-wire format in HTTP field values.</t> | ||||
| <t>In summary:</t> | ||||
| <ul> | ||||
| <li>There are three top-level types that an HTTP field can be defined | ||||
| as: Lists, Dictionaries, and Items.</li> | ||||
| <li>Lists and Dictionaries are containers; their members can be Items | ||||
| or Inner Lists (which are themselves arrays of Items).</li> | ||||
| <li>Both Items and Inner Lists can be Parameterized with key/value pairs | ||||
| .</li> | ||||
| </ul> | ||||
| <section anchor="list"> | ||||
| <name>Lists</name> | ||||
| <t>Lists are arrays of zero or more members, each of which can be an | ||||
| Item (<xref target="item"/>) or an Inner List (<xref target="inner-list"/ | ||||
| >), both of which can be | ||||
| Parameterized (<xref target="param"/>).</t> | ||||
| <t>The ABNF for Lists in HTTP fields is:</t> | ||||
| <sourcecode type="abnf"> | ||||
| sf-list = list-member *( OWS "," OWS list-member ) | sf-list = list-member *( OWS "," OWS list-member ) | |||
| list-member = sf-item / inner-list | list-member = sf-item / inner-list | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Each member is separated by a comma and optional whitespace. For | ||||
| <t>Each member is separated by a comma and optional whitespace. For example, a f | example, a field whose value is defined as a List of Tokens could | |||
| ield whose value is defined as a List of Strings could look like:</t> | look like:</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | Example-List: sugar, tea, rum | |||
| Example-StrList: "foo", "bar", "It was the best of times." | </sourcecode> | |||
| ]]></artwork></figure> | <t>An empty List is denoted by not serializing the field at all. This | |||
| implies that fields defined as Lists have a default empty value.</t> | ||||
| <t>An empty List is denoted by not serializing the field at all. This implies th | <t>Note that Lists can have their members split across multiple lines | |||
| at fields defined as Lists have a default empty value.</t> | of the same header or trailer section, as per <xref target="RFC7230" sect | |||
| ion="3.2.2"/>; for example, the following are | ||||
| <t>Note that Lists can have their members split across multiple lines inside a h | equivalent:</t> | |||
| eader or trailer section, as per Section 3.2.2 of <xref target="RFC7230"/>; for | <sourcecode type="http-message"> | |||
| example, the following are equivalent:</t> | Example-List: sugar, tea, rum | |||
| </sourcecode> | ||||
| <figure><artwork type="example"><![CDATA[ | <t>and</t> | |||
| Example-Hdr: foo, bar | <sourcecode type="http-message"> | |||
| ]]></artwork></figure> | Example-List: sugar, tea | |||
| Example-List: rum | ||||
| <t>and</t> | </sourcecode> | |||
| <t>However, individual members of a List cannot be safely split | ||||
| <figure><artwork type="example"><![CDATA[ | between lines; see <xref target="text-parse"/> | |||
| Example-Hdr: foo | for details.</t> | |||
| Example-Hdr: bar | <t>Parsers <bcp14>MUST</bcp14> support Lists containing at least 1024 me | |||
| ]]></artwork></figure> | mbers. Field | |||
| specifications can constrain the types and cardinality of individual | ||||
| <t>However, individual members of a List cannot be safely split between across l | List values as they require.</t> | |||
| ines; see <xref target="text-parse"/> for details.</t> | <section anchor="inner-list"> | |||
| <name>Inner Lists</name> | ||||
| <t>Parsers MUST support Lists containing at least 1024 members. Field specificat | <t>An Inner List is an array of zero or more Items (<xref target="item | |||
| ions can constrain the types and cardinality of individual List values as they r | "/>). Both the individual Items and the | |||
| equire.</t> | Inner List itself can be Parameterized (<xref target="param"/>).</t> | |||
| <t>The ABNF for Inner Lists is:</t> | ||||
| <section anchor="inner-list" title="Inner Lists"> | <sourcecode type="abnf"> | |||
| <t>An Inner List is an array of zero or more Items (<xref target="item"/>). Both | ||||
| the individual Items and the Inner List itself can be Parameterized (<xref targ | ||||
| et="param"/>).</t> | ||||
| <t>The ABNF for Inner Lists is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | |||
| parameters | parameters | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Inner Lists are denoted by surrounding parenthesis, and | ||||
| <t>Inner Lists are denoted by surrounding parenthesis, and have their values del | their values are delimited by one or more spaces. A field whose value i | |||
| imited by one or more spaces. A field whose value is defined as a List of Inner | s | |||
| Lists of Strings could look like:</t> | defined as a List of Inner Lists of Strings could look like:</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | Example-List: ("foo" "bar"), ("baz"), ("bat" "one"), () | |||
| Example-StrListList: ("foo" "bar"), ("baz"), ("bat" "one"), () | </sourcecode> | |||
| ]]></artwork></figure> | <t>Note that the last member in this example is an empty Inner List.</ | |||
| t> | ||||
| <t>Note that the last member in this example is an empty Inner List.</t> | <t>A header field whose value is defined as a List of Inner Lists | |||
| with Parameters at both levels could look like:</t> | ||||
| <t>A header field whose value is defined as a List of Inner Lists with Parameter | <sourcecode type="http-message"> | |||
| s at both levels could look like:</t> | Example-List: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | |||
| </sourcecode> | ||||
| <figure><artwork type="example"><![CDATA[ | <t>Parsers <bcp14>MUST</bcp14> support Inner Lists containing at least | |||
| Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | 256 | |||
| ]]></artwork></figure> | members. Field specifications can constrain the types and | |||
| cardinality of individual Inner List members as they require.</t> | ||||
| <t>Parsers MUST support Inner Lists containing at least 256 members. Field speci | </section> | |||
| fications can constrain the types and cardinality of individual Inner List membe | <section anchor="param"> | |||
| rs as they require.</t> | <name>Parameters</name> | |||
| <t>Parameters are an ordered map of key-value pairs that are | ||||
| </section> | associated with an Item (<xref target="item"/>) or | |||
| <section anchor="param" title="Parameters"> | Inner List (<xref target="inner-list"/>). | |||
| The keys | ||||
| <t>Parameters are an ordered map of key-value pairs that are associated with an | are unique within the scope of the Parameters they occur within, and | |||
| Item (<xref target="item"/>) or Inner List (<xref target="inner-list"/>). The ke | the values are bare items (i.e., they themselves cannot be | |||
| ys are unique within the scope the Parameters they occur within, and the values | parameterized; see <xref target="item"/>).</t> | |||
| are bare items (i.e., they themselves cannot be parameterized; see <xref target= | <t>Implementations <bcp14>MUST</bcp14> provide access to Parameters both by inde | |||
| "item"/>).</t> | x and | |||
| by key. Specifications <bcp14>MAY</bcp14> use either means of accessing them | ||||
| <t>The ABNF for Parameters is:</t> | .</t> | |||
| <t>The ABNF for Parameters is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| parameters = *( ";" *SP parameter ) | parameters = *( ";" *SP parameter ) | |||
| parameter = param-name [ "=" param-value ] | parameter = param-key [ "=" param-value ] | |||
| param-name = key | param-key = key | |||
| key = ( lcalpha / "*" ) | key = ( lcalpha / "*" ) | |||
| *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) | *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) | |||
| lcalpha = %x61-7A ; a-z | lcalpha = %x61-7A ; a-z | |||
| param-value = bare-item | param-value = bare-item | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Note that parameters are ordered as serialized, and parameter | ||||
| <t>Note that Parameters are ordered as serialized, and Parameter keys cannot con | keys cannot contain uppercase letters. A parameter is separated from | |||
| tain uppercase letters. A parameter is separated from its Item or Inner List and | its Item or Inner List and other parameters by a semicolon. For | |||
| other parameters by a semicolon. For example:</t> | example:</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | Example-List: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | |||
| Example-ParamList: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | </sourcecode> | |||
| ]]></artwork></figure> | <t>Parameters whose value is Boolean (see <xref target="boolean"/>) tr | |||
| ue <bcp14>MUST</bcp14> omit that value when serialized. For | ||||
| <t>Parameters whose value is Boolean (see <xref target="boolean"/>) true MUST om | example, the "a" parameter here is true, while the "b" parameter is | |||
| it that value when serialized. For example, the “a” parameter here is true, whil | false:</t> | |||
| e the “b” parameter is false:</t> | <sourcecode type="http-message"> | |||
| Example-Integer: 1; a; b=?0 | ||||
| <figure><artwork type="example"><![CDATA[ | </sourcecode> | |||
| Example-Int: 1; a; b=?0 | <t>Note that this requirement is only on serialization; parsers are | |||
| ]]></artwork></figure> | still required to correctly handle the true value when it appears in | |||
| a parameter.</t> | ||||
| <t>Note that this requirement is only on serialization; parsers are still requir | <t>Parsers <bcp14>MUST</bcp14> support at least 256 parameters on an I | |||
| ed to correctly handle the true value when it appears in a parameter.</t> | tem or Inner | |||
| List, and support parameter keys with at least 64 characters. Field | ||||
| <t>Parsers MUST support at least 256 parameters on an Item or Inner List, and su | specifications can constrain the order of individual parameters, as | |||
| pport parameter keys with at least 64 characters. Field specifications can const | well as their values' types as required.</t> | |||
| rain the order of individual Parameters, as well as their values’ types as requi | </section> | |||
| red.</t> | </section> | |||
| <section anchor="dictionary"> | ||||
| </section> | <name>Dictionaries</name> | |||
| </section> | <t>Dictionaries are ordered maps of key-value pairs, where the keys | |||
| <section anchor="dictionary" title="Dictionaries"> | are short textual strings and the values are Items (<xref target="item"/> | |||
| ) or arrays of Items, both of which | ||||
| <t>Dictionaries are ordered maps of name-value pairs, where the names are short | can be Parameterized (<xref target="param"/>). There | |||
| textual strings and the values are Items (<xref target="item"/>) or arrays of It | can be zero or more members, and their keys are unique in the scope | |||
| ems, both of which can be Parameterized (<xref target="param"/>). There can be z | of the Dictionary they occur within.</t> | |||
| ero or more members, and their names are unique in the scope of the Dictionary t | <t>Implementations <bcp14>MUST</bcp14> provide access to Dictionaries bo | |||
| hey occur within.</t> | th by index | |||
| and by key. Specifications <bcp14>MAY</bcp14> use either means of accessi | ||||
| <t>Implementations MUST provide access to Dictionaries both by index and by name | ng the | |||
| . Specifications MAY use either means of accessing the members.</t> | members.</t> | |||
| <t>The ABNF for Dictionaries is:</t> | ||||
| <t>The ABNF for Dictionaries is:</t> | <sourcecode type="abnf"> | |||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-dictionary = dict-member *( OWS "," OWS dict-member ) | sf-dictionary = dict-member *( OWS "," OWS dict-member ) | |||
| dict-member = member-name [ "=" member-value ] | dict-member = member-key ( parameters / ( "=" member-value )) | |||
| member-name = key | member-key = key | |||
| member-value = sf-item / inner-list | member-value = sf-item / inner-list | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Members are ordered as serialized and separated by a comma with | ||||
| <t>Members are ordered as serialized, and separated by a comma with optional whi | optional whitespace. Member keys cannot contain uppercase | |||
| tespace. Member names cannot contain uppercase characters. Names and values are | characters. Keys and values are separated by "=" (without | |||
| separated by “=” (without whitespace). For example:</t> | whitespace). For example:</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Note that in this example, the final "=" is due to the inclusion of | ||||
| <t>Note that in this example, the final “=” is due to the inclusion of a Byte Se | a Byte Sequence; see <xref target="binary"/>.</t> | |||
| quence; see <xref target="binary"/>.</t> | <t>Members whose value is Boolean (see <xref target="boolean"/>) true <b | |||
| cp14>MUST</bcp14> omit that value when serialized. For | ||||
| <t>Members whose value is Boolean (see <xref target="boolean"/>) true MUST omit | example, here both "b" and "c" are true:</t> | |||
| that value when serialized. For example, here both “b” and “c” are true:</t> | <sourcecode type="http-message"> | |||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-Dict: a=?0, b, c; foo=bar | Example-Dict: a=?0, b, c; foo=bar | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Note that this requirement is only on serialization; parsers are | ||||
| <t>Note that this requirement is only on serialization; parsers are still requir | still required to correctly handle the true Boolean value when it | |||
| ed to correctly handle the true Boolean value when it appears in Dictionary valu | appears in Dictionary values.</t> | |||
| es.</t> | <t>A Dictionary with a member whose value is an Inner List of Tokens:</t | |||
| > | ||||
| <t>A Dictionary with a member whose value is an Inner List of Tokens:</t> | <sourcecode type="http-message"> | |||
| Example-Dict: rating=1.5, feelings=(joy sadness) | ||||
| <figure><artwork type="example"><![CDATA[ | </sourcecode> | |||
| Example-DictList: rating=1.5, feelings=(joy sadness) | <t>A Dictionary with a mix of Items and Inner Lists, some with parameter | |||
| ]]></artwork></figure> | s:</t> | |||
| <sourcecode type="http-message"> | ||||
| <t>A Dictionary with a mix of Items and Inner Lists, some with Parameters:</t> | Example-Dict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid | |||
| </sourcecode> | ||||
| <figure><artwork type="example"><![CDATA[ | <t>As with Lists, an empty Dictionary is represented by omitting the | |||
| Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid | entire field. This implies that fields defined as Dictionaries have a | |||
| ]]></artwork></figure> | default empty value.</t> | |||
| <t>Typically, a field specification will define the semantics of | ||||
| <t>As with lists, an empty Dictionary is represented by omitting the entire fiel | Dictionaries by specifying the allowed type(s) for individual members | |||
| d. This implies that fields defined as Dictionaries have a default empty value.< | by their keys, as well as whether their presence is required or | |||
| /t> | optional. Recipients <bcp14>MUST</bcp14> ignore members whose keys that a | |||
| re undefined or unknown, | ||||
| <t>Typically, a field specification will define the semantics of Dictionaries by | unless the field's specification specifically disallows them.</t> | |||
| specifying the allowed type(s) for individual members by their names, as well a | <t>Note that Dictionaries can have their members split across multiple | |||
| s whether their presence is required or optional. Recipients MUST ignore names t | lines of the same header or trailer section; for example, the following | |||
| hat are undefined or unknown, unless the field’s specification specifically disa | are equivalent:</t> | |||
| llows them.</t> | <sourcecode type="http-message"> | |||
| Example-Dict: foo=1, bar=2 | ||||
| <t>Note that Dictionaries can have their members split across multiple lines ins | </sourcecode> | |||
| ide a header or trailer section; for example, the following are equivalent:</t> | <t>and</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | Example-Dict: foo=1 | |||
| Example-Hdr: foo=1, bar=2 | Example-Dict: bar=2 | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>However, individual members of a Dictionary cannot be safely split | ||||
| <t>and</t> | between lines; see <xref target="text-parse"/> for | |||
| details.</t> | ||||
| <figure><artwork type="example"><![CDATA[ | <t>Parsers <bcp14>MUST</bcp14> support Dictionaries containing at least | |||
| Example-Hdr: foo=1 | 1024 | |||
| Example-Hdr: bar=2 | key/value pairs and keys with at least 64 characters. Field | |||
| ]]></artwork></figure> | specifications can constrain the order of individual Dictionary | |||
| members, as well as their values' types as required.</t> | ||||
| <t>However, individual members of a Dictionary cannot be safely split between li | </section> | |||
| nes; see <xref target="text-parse"/> for details.</t> | <section anchor="item"> | |||
| <name>Items</name> | ||||
| <t>Parsers MUST support Dictionaries containing at least 1024 name/value pairs, | <t>An Item can be an Integer (<xref target="integer"/>), a Decimal (<xre | |||
| and names with at least 64 characters. Field specifications can constrain the or | f target="decimal"/>), a String (<xref target="string"/>), a Token (<xref target | |||
| der of individual Dictionary members, as well as their values’ types as required | ="token"/>), | |||
| .</t> | a Byte Sequence (<xref target="binary"/>), or a Boolean | |||
| (<xref target="boolean"/>). It can have associated | ||||
| </section> | parameters (<xref target="param"/>).</t> | |||
| <section anchor="item" title="Items"> | <t>The ABNF for Items is:</t> | |||
| <sourcecode type="abnf"> | ||||
| <t>An Item can be a Integer (<xref target="integer"/>), Decimal (<xref target="d | ||||
| ecimal"/>), String (<xref target="string"/>), Token (<xref target="token"/>), By | ||||
| te Sequence (<xref target="binary"/>), or Boolean (<xref target="boolean"/>). It | ||||
| can have associated Parameters (<xref target="param"/>).</t> | ||||
| <t>The ABNF for Items is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-item = bare-item parameters | sf-item = bare-item parameters | |||
| bare-item = sf-integer / sf-decimal / sf-string / sf-token | bare-item = sf-integer / sf-decimal / sf-string / sf-token | |||
| / sf-binary / sf-boolean | / sf-binary / sf-boolean | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>For example, a header field that is defined to be an Item that is | ||||
| <t>For example, a header field that is defined to be an Item that is an Integer | an Integer might look like:</t> | |||
| might look like:</t> | <sourcecode type="http-message"> | |||
| Example-Integer: 5 | ||||
| <figure><artwork type="example"><![CDATA[ | </sourcecode> | |||
| Example-IntItemHeader: 5 | <t>or with parameters:</t> | |||
| ]]></artwork></figure> | <sourcecode type="http-message"> | |||
| Example-Integer: 5; foo=bar | ||||
| <t>or with Parameters:</t> | </sourcecode> | |||
| <section anchor="integer"> | ||||
| <figure><artwork type="example"><![CDATA[ | <name>Integers</name> | |||
| Example-IntItem: 5; foo=bar | <t>Integers have a range of -999,999,999,999,999 to | |||
| ]]></artwork></figure> | 999,999,999,999,999 inclusive (i.e., up to fifteen digits, signed), | |||
| for IEEE 754 compatibility <xref target="IEEE754"/>.</t> | ||||
| <section anchor="integer" title="Integers"> | <t>The ABNF for Integers is:</t> | |||
| <sourcecode type="abnf"> | ||||
| <t>Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 inclusiv | ||||
| e (i.e., up to fifteen digits, signed), for IEEE 754 compatibility (<xref target | ||||
| ="IEEE754"/>).</t> | ||||
| <t>The ABNF for Integers is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-integer = ["-"] 1*15DIGIT | sf-integer = ["-"] 1*15DIGIT | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>For example:</t> | ||||
| <t>For example:</t> | <sourcecode type="http-message"> | |||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-Integer: 42 | Example-Integer: 42 | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Integers larger than 15 digits can be supported in a variety of | ||||
| <t>Integers larger than 15 digits can be supported in a variety of ways; for exa | ways; for example, by using a String (<xref target="string"/>), a Byte | |||
| mple, by using a String (<xref target="string"/>), Byte Sequence (<xref target=" | Sequence (<xref target="binary"/>), or a parameter on an Integer that acts as a | |||
| binary"/>), or a parameter on an Integer that acts as a scaling factor.</t> | scaling factor.</t> | |||
| <t>While it is possible to serialize Integers with leading zeros | ||||
| <t>While it is possible to serialise Integers with leading zeros (e.g., “0002”, | (e.g., "0002", "-01") and signed zero ("-0"), these distinctions may | |||
| “-01”) and signed zero (“-0”), these distinctions may not be preserved by implem | not be preserved by implementations.</t> | |||
| entations.</t> | <t>Note that commas in Integers are used in this section's prose | |||
| only for readability; they are not valid in the wire format.</t> | ||||
| <t>Note that commas in Integers are used in this section’s prose only for readab | </section> | |||
| ility; they are not valid in the wire format.</t> | <section anchor="decimal"> | |||
| <name>Decimals</name> | ||||
| </section> | <t>Decimals are numbers with an integer and a fractional | |||
| <section anchor="decimal" title="Decimals"> | component. The integer component has at most 12 digits; the | |||
| fractional component has at most three digits.</t> | ||||
| <t>Decimals are numbers with an integer and a fractional component. The integer | <t>The ABNF for decimals is:</t> | |||
| component has at most 12 digits; the fractional component has at most three digi | <sourcecode type="abnf"> | |||
| ts.</t> | ||||
| <t>The ABNF for decimals is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>For example, a header whose value is defined as a Decimal could | ||||
| <t>For example, a header whose value is defined as a Decimal could look like:</t | look like:</t> | |||
| > | <sourcecode type="http-message"> | |||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-Decimal: 4.5 | Example-Decimal: 4.5 | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>While it is possible to serialize Decimals with leading zeros | ||||
| <t>While it is possible to serialise Decimals with leading zeros (e.g., “0002.5” | (e.g., "0002.5", "-01.334"), trailing zeros (e.g., "5.230", | |||
| , “-01.334”), trailing zeros (e.g., “5.230”, “-0.40”), and signed zero (e.g., “- | "-0.40"), and signed zero (e.g., "-0.0"), these distinctions may not | |||
| 0.0”), these distinctions may not be preserved by implementations.</t> | be preserved by implementations.</t> | |||
| <t>Note that the serialization algorithm (<xref target="ser-decimal"/> | ||||
| <t>Note that the serialisation algorithm (<xref target="ser-decimal"/>) rounds i | ) rounds input with more than three digits of | |||
| nput with more than three digits of precision in the fractional component. If an | precision in the fractional component. If an alternative rounding | |||
| alternative rounding strategy is desired, this should be specified by the heade | strategy is desired, this should be specified by the header | |||
| r definition to occur before serialisation.</t> | definition to occur before serialization.</t> | |||
| </section> | ||||
| </section> | <section anchor="string"> | |||
| <section anchor="string" title="Strings"> | <name>Strings</name> | |||
| <t>Strings are zero or more printable ASCII <xref target="RFC0020"/> c | ||||
| <t>Strings are zero or more printable ASCII <xref target="RFC0020"/> characters | haracters (i.e., the range %x20 to %x7E). Note | |||
| (i.e., the range %x20 to %x7E). Note that this excludes tabs, newlines, carriage | that this excludes tabs, newlines, carriage returns, etc.</t> | |||
| returns, etc.</t> | <t>The ABNF for Strings is:</t> | |||
| <sourcecode type="abnf"> | ||||
| <t>The ABNF for Strings is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-string = DQUOTE *chr DQUOTE | sf-string = DQUOTE *chr DQUOTE | |||
| chr = unescaped / escaped | chr = unescaped / escaped | |||
| unescaped = %x20-21 / %x23-5B / %x5D-7E | unescaped = %x20-21 / %x23-5B / %x5D-7E | |||
| escaped = "\" ( DQUOTE / "\" ) | escaped = "\" ( DQUOTE / "\" ) | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Strings are delimited with double quotes, using a backslash ("\") | ||||
| <t>Strings are delimited with double quotes, using a backslash (“\”) to escape d | to escape double quotes and backslashes. For example:</t> | |||
| ouble quotes and backslashes. For example:</t> | <sourcecode type="http-message"> | |||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-String: "hello world" | Example-String: "hello world" | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Note that Strings only use DQUOTE as a delimiter; single quotes | ||||
| <t>Note that Strings only use DQUOTE as a delimiter; single quotes do not delimi | do not delimit Strings. Furthermore, only DQUOTE and "\" can be | |||
| t Strings. Furthermore, only DQUOTE and “\” can be escaped; other characters aft | escaped; other characters after "\" <bcp14>MUST</bcp14> cause parsing t | |||
| er “\” MUST cause parsing to fail.</t> | o fail.</t> | |||
| <t>Unicode is not directly supported in Strings, because it causes a | ||||
| <t>Unicode is not directly supported in Strings, because it causes a number of i | number of interoperability issues, and -- with few exceptions -- field | |||
| nteroperability issues, and – with few exceptions – field values do not require | values do not require it.</t> | |||
| it.</t> | <t>When it is necessary for a field value to convey non-ASCII | |||
| content, a Byte Sequence (<xref target="binary"/>) | ||||
| <t>When it is necessary for a field value to convey non-ASCII content, a Byte Se | can be specified, along with a character encoding (preferably UTF-8 <xr | |||
| quence (<xref target="binary"/>) can be specified, along with a character encodi | ef target="STD63"/>).</t> | |||
| ng (preferably <xref target="UTF-8"/>).</t> | <t>Parsers <bcp14>MUST</bcp14> support Strings (after any decoding) wi | |||
| th at least | ||||
| <t>Parsers MUST support Strings (after any decoding) with at least 1024 characte | 1024 characters.</t> | |||
| rs.</t> | </section> | |||
| <section anchor="token"> | ||||
| </section> | <name>Tokens</name> | |||
| <section anchor="token" title="Tokens"> | <t>Tokens are short textual words; their abstract model is identical | |||
| to their expression in the HTTP field value serialization.</t> | ||||
| <t>Tokens are short textual words; their abstract model is identical to their ex | <t>The ABNF for Tokens is:</t> | |||
| pression in the HTTP field value serialization.</t> | <sourcecode type="abnf"> | |||
| <t>The ABNF for Tokens is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) | sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>For example:</t> | ||||
| <t>For example:</t> | <sourcecode type="http-message"> | |||
| <figure><artwork type="example"><![CDATA[ | ||||
| Example-Token: foo123/456 | Example-Token: foo123/456 | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Tokens with at least 512 charac | ||||
| <t>Parsers MUST support Tokens with at least 512 characters.</t> | ters.</t> | |||
| <t>Note that Token allows the same characters as the "token" ABNF | ||||
| <t>Note that Token allows the same characters as the “token” ABNF rule defined i | rule defined in <xref target="RFC7230"/>, with the | |||
| n <xref target="RFC7230"/>, with the exceptions that the first character is requ | exceptions that the first character is required to be either ALPHA | |||
| ired to be either ALPHA or “*”, and “:” and “/” are also allowed in subsequent c | or "*", and ":" and "/" are also allowed in subsequent | |||
| haracters.</t> | characters.</t> | |||
| </section> | ||||
| </section> | <section anchor="binary"> | |||
| <section anchor="binary" title="Byte Sequences"> | <name>Byte Sequences</name> | |||
| <t>Byte Sequences can be conveyed in Structured Fields.</t> | ||||
| <t>Byte Sequences can be conveyed in Structured Fields.</t> | <t>The ABNF for a Byte Sequence is:</t> | |||
| <sourcecode type="abnf"> | ||||
| <t>The ABNF for a Byte Sequence is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-binary = ":" *(base64) ":" | sf-binary = ":" *(base64) ":" | |||
| base64 = ALPHA / DIGIT / "+" / "/" / "=" | base64 = ALPHA / DIGIT / "+" / "/" / "=" | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>A Byte Sequence is delimited with colons and encoded using base64 | ||||
| <t>A Byte Sequence is delimited with colons and encoded using base64 (<xref targ | (<xref target="RFC4648" sectionFormat="comma" section="4"/>). For | |||
| et="RFC4648"/>, Section 4). For example:</t> | example:</t> | |||
| <sourcecode type="http-message"> | ||||
| <figure><artwork type="example"><![CDATA[ | Example-ByteSequence: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | |||
| Example-Binary: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | </sourcecode> | |||
| ]]></artwork></figure> | <t>Parsers <bcp14>MUST</bcp14> support Byte Sequences with at least 16 | |||
| 384 octets | ||||
| <t>Parsers MUST support Byte Sequences with at least 16384 octets after decoding | after decoding.</t> | |||
| .</t> | </section> | |||
| <section anchor="boolean"> | ||||
| </section> | <name>Booleans</name> | |||
| <section anchor="boolean" title="Booleans"> | <t>Boolean values can be conveyed in Structured Fields.</t> | |||
| <t>The ABNF for a Boolean is:</t> | ||||
| <t>Boolean values can be conveyed in Structured Fields.</t> | <sourcecode type="abnf"> | |||
| <t>The ABNF for a Boolean is:</t> | ||||
| <figure><artwork type="abnf"><![CDATA[ | ||||
| sf-boolean = "?" boolean | sf-boolean = "?" boolean | |||
| boolean = "0" / "1" | boolean = "0" / "1" | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>A Boolean is indicated with a leading "?" character followed by a | ||||
| <t>A Boolean is indicated with a leading “?” character followed by a “1” for a t | "1" for a true value or "0" for false. For example:</t> | |||
| rue value or “0” for false. For example:</t> | <sourcecode type="http-message"> | |||
| Example-Boolean: ?1 | ||||
| <figure><artwork type="example"><![CDATA[ | </sourcecode> | |||
| Example-Bool: ?1 | <t>Note that in Dictionary (<xref target="dictionary"/>) and Parameter | |||
| ]]></artwork></figure> | (<xref target="param"/>) values, Boolean true is indicated by omitting | |||
| the value.</t> | ||||
| <t>Note that in Dictionary (<xref target="dictionary"/>) and Parameter (<xref ta | </section> | |||
| rget="param"/>) values, Boolean true is indicated by omitting the value.</t> | </section> | |||
| </section> | ||||
| </section> | <section anchor="text"> | |||
| </section> | <name>Working with Structured Fields in HTTP</name> | |||
| </section> | <t>This section defines how to serialize and parse Structured Fields in | |||
| <section anchor="text" title="Working With Structured Fields in HTTP"> | textual HTTP field values and other encodings compatible with them | |||
| (e.g., in HTTP/2 <xref target="RFC7540"/> before | ||||
| <t>This section defines how to serialize and parse Structured Fields in textual | compression with HPACK <xref target="RFC7541"/>).</t> | |||
| HTTP field values and other encodings compatible with them (e.g., in HTTP/2 <xre | <section anchor="text-serialize"> | |||
| f target="RFC7540"/> before compression with HPACK <xref target="RFC7541"/>).</t | <name>Serializing Structured Fields</name> | |||
| > | <t>Given a structure defined in this specification, return an ASCII | |||
| string suitable for use in an HTTP field value.</t> | ||||
| <section anchor="text-serialize" title="Serializing Structured Fields"> | <ol> | |||
| <li>If the structure is a Dictionary or List and its value is empty | ||||
| <t>Given a structure defined in this specification, return an ASCII string suita | (i.e., it has no members), do not serialize the field at all (i.e., | |||
| ble for use in a HTTP field value.</t> | omit both the field-name and field-value).</li> | |||
| <li>If the structure is a List, let output_string be the result of | ||||
| <t><list style="numbers"> | running Serializing a List (<xref target="ser-list"/>) with the structu | |||
| <t>If the structure is a Dictionary or List and its value is empty (i.e., it h | re.</li> | |||
| as no members), do not serialize the field at all (i.e., omit both the field-nam | <li>Else, if the structure is a Dictionary, let output_string be the | |||
| e and field-value).</t> | result of running Serializing a Dictionary (<xref target="ser-dictionar | |||
| <t>If the structure is a List, let output_string be the result of running Seri | y"/>) with the structure.</li> | |||
| alizing a List (<xref target="ser-list"/>) with the structure.</t> | <li>Else, if the structure is an Item, let output_string be the | |||
| <t>Else if the structure is a Dictionary, let output_string be the result of r | result of running Serializing an Item (<xref target="ser-item"/>) with | |||
| unning Serializing a Dictionary (<xref target="ser-dictionary"/>) with the struc | the structure.</li> | |||
| ture.</t> | <li>Else, fail serialization.</li> | |||
| <t>Else if the structure is an Item, let output_string be the result of runnin | <li>Return output_string converted into an array of bytes, using | |||
| g Serializing an Item (<xref target="ser-item"/>) with the structure.</t> | ASCII encoding <xref target="RFC0020"/>.</li> | |||
| <t>Else, fail serialization.</t> | </ol> | |||
| <t>Return output_string converted into an array of bytes, using ASCII encoding | <section anchor="ser-list"> | |||
| <xref target="RFC0020"/>.</t> | <name>Serializing a List</name> | |||
| </list></t> | <t>Given an array of (member_value, parameters) tuples as | |||
| input_list, return an ASCII string suitable for use in an HTTP field | ||||
| <section anchor="ser-list" title="Serializing a List"> | value.</t> | |||
| <ol> | ||||
| <t>Given an array of (member_value, parameters) tuples as input_list, return an | <li>Let output be an empty string.</li> | |||
| ASCII string suitable for use in a HTTP field value.</t> | <li> | |||
| <t>For each (member_value, parameters) of input_list: | ||||
| <t><list style="numbers"> | </t> | |||
| <t>Let output be an empty string.</t> | <ol> | |||
| <t>For each (member_value, parameters) of input_list: | <li>If member_value is an array, append the result of running | |||
| <list style="numbers"> | Serializing an Inner List (<xref target="ser-innerlist"/>) with ( | |||
| <t>If member_value is an array, append the result of running Serializing a | member_value, parameters) to | |||
| n Inner List (<xref target="ser-innerlist"/>) with (member_value, parameters) to | output.</li> | |||
| output.</t> | <li>Otherwise, append the result of running Serializing an | |||
| <t>Otherwise, append the result of running Serializing an Item (<xref targ | Item (<xref target="ser-item"/>) with | |||
| et="ser-item"/>) with (member_value, parameters) to output.</t> | (member_value, parameters) to output.</li> | |||
| <t>If more member_values remain in input_list: | <li> | |||
| <list style="numbers"> | <t>If more member_values remain in input_list: | |||
| <t>Append “,” to output.</t> | </t> | |||
| <t>Append a single SP to output.</t> | <ol> | |||
| </list></t> | <li>Append "," to output.</li> | |||
| </list></t> | <li>Append a single SP to output.</li> | |||
| <t>Return output.</t> | </ol> | |||
| </list></t> | </li> | |||
| </ol> | ||||
| <section anchor="ser-innerlist" title="Serializing an Inner List"> | </li> | |||
| <li>Return output.</li> | ||||
| <t>Given an array of (member_value, parameters) tuples as inner_list, and parame | </ol> | |||
| ters as list_parameters, return an ASCII string suitable for use in a HTTP field | <section anchor="ser-innerlist"> | |||
| value.</t> | <name>Serializing an Inner List</name> | |||
| <t>Given an array of (member_value, parameters) tuples as | ||||
| <t><list style="numbers"> | inner_list, and parameters as list_parameters, return an ASCII | |||
| <t>Let output be the string “(“.</t> | string suitable for use in an HTTP field value.</t> | |||
| <t>For each (member_value, parameters) of inner_list: | <ol> | |||
| <list style="numbers"> | <li>Let output be the string "(".</li> | |||
| <t>Append the result of running Serializing an Item (<xref target="ser-ite | <li> | |||
| m"/>) with (member_value, parameters) to output.</t> | <t>For each (member_value, parameters) of inner_list: | |||
| <t>If more values remain in inner_list, append a single SP to output.</t> | </t> | |||
| </list></t> | <ol> | |||
| <t>Append “)” to output.</t> | <li>Append the result of running Serializing an Item (<xref ta | |||
| <t>Append the result of running Serializing Parameters (<xref target="ser-para | rget="ser-item"/>) with (member_value, | |||
| ms"/>) with list_parameters to output.</t> | parameters) to output.</li> | |||
| <t>Return output.</t> | <li>If more values remain in inner_list, append a single SP to | |||
| </list></t> | output.</li> | |||
| </ol> | ||||
| </section> | </li> | |||
| <section anchor="ser-params" title="Serializing Parameters"> | <li>Append ")" to output.</li> | |||
| <li>Append the result of running Serializing Parameters (<xref tar | ||||
| <t>Given an ordered Dictionary as input_parameters (each member having a param_n | get="ser-params"/>) with list_parameters to | |||
| ame and a param_value), return an ASCII string suitable for use in a HTTP field | output.</li> | |||
| value.</t> | <li>Return output.</li> | |||
| </ol> | ||||
| <t><list style="numbers"> | </section> | |||
| <t>Let output be an empty string.</t> | <section anchor="ser-params"> | |||
| <t>For each param_name with a value of param_value in input_parameters: | <name>Serializing Parameters</name> | |||
| <list style="numbers"> | <t>Given an ordered Dictionary as input_parameters (each member | |||
| <t>Append “;” to output.</t> | having a param_key and a param_value), return an ASCII string | |||
| <t>Append the result of running Serializing a Key (<xref target="ser-key"/ | suitable for use in an HTTP field value.</t> | |||
| >) with param_name to output.</t> | <ol> | |||
| <t>If param_value is not Boolean true: | <li>Let output be an empty string.</li> | |||
| <list style="numbers"> | <li> | |||
| <t>Append “=” to output.</t> | <t>For each param_key with a value of param_value in input_param | |||
| <t>Append the result of running Serializing a bare Item (<xref target= | eters: | |||
| "ser-bare-item"/>) with param_value to output.</t> | </t> | |||
| </list></t> | <ol> | |||
| </list></t> | <li>Append ";" to output.</li> | |||
| <t>Return output.</t> | <li>Append the result of running Serializing a Key (<xref targ | |||
| </list></t> | et="ser-key"/>) with param_key to | |||
| output.</li> | ||||
| </section> | <li> | |||
| <section anchor="ser-key" title="Serializing a Key"> | <t>If param_value is not Boolean true: | |||
| </t> | ||||
| <t>Given a key as input_key, return an ASCII string suitable for use in a HTTP f | <ol> | |||
| ield value.</t> | <li>Append "=" to output.</li> | |||
| <li>Append the result of running Serializing a bare Item | ||||
| <t><list style="numbers"> | (<xref target="ser-bare-item"/>) with | |||
| <t>Convert input_key into a sequence of ASCII characters; if conversion fails, | param_value to output.</li> | |||
| fail serialization.</t> | </ol> | |||
| <t>If input_key contains characters not in lcalpha, DIGIT, “_”, “-“, “.”, or “ | </li> | |||
| *” fail serialization.</t> | </ol> | |||
| <t>If the first character of input_key is not lcalpha or “*”, fail serializati | </li> | |||
| on.</t> | <li>Return output.</li> | |||
| <t>Let output be an empty string.</t> | </ol> | |||
| <t>Append input_key to output.</t> | </section> | |||
| <t>Return output.</t> | <section anchor="ser-key"> | |||
| </list></t> | <name>Serializing a Key</name> | |||
| <t>Given a key as input_key, return an ASCII string suitable for | ||||
| </section> | use in an HTTP field value.</t> | |||
| </section> | <ol> | |||
| <section anchor="ser-dictionary" title="Serializing a Dictionary"> | <li>Convert input_key into a sequence of ASCII characters; if | |||
| conversion fails, fail serialization.</li> | ||||
| <t>Given an ordered Dictionary as input_dictionary (each member having a member_ | <li>If input_key contains characters not in lcalpha, DIGIT, "_", | |||
| name and a tuple value of (member_value, parameters)), return an ASCII string su | "-", ".", or "*", fail serialization.</li> | |||
| itable for use in a HTTP field value.</t> | <li>If the first character of input_key is not lcalpha or "*", | |||
| fail serialization.</li> | ||||
| <t><list style="numbers"> | <li>Let output be an empty string.</li> | |||
| <t>Let output be an empty string.</t> | <li>Append input_key to output.</li> | |||
| <t>For each member_name with a value of (member_value, parameters) in input_di | <li>Return output.</li> | |||
| ctionary: | </ol> | |||
| <list style="numbers"> | </section> | |||
| <t>Append the result of running Serializing a Key (<xref target="ser-key"/ | </section> | |||
| >) with member’s member_name to output.</t> | <section anchor="ser-dictionary"> | |||
| <t>If member_value is Boolean true: | <name>Serializing a Dictionary</name> | |||
| <list style="numbers"> | <t>Given an ordered Dictionary as input_dictionary (each member | |||
| <t>Append the result of running Serializing Parameters (<xref target=" | having a member_key and a tuple value of (member_value, | |||
| ser-params"/>) with parameters to output.</t> | parameters)), return an ASCII string suitable for use in an HTTP | |||
| </list></t> | field value.</t> | |||
| <t>Otherwise: | <ol> | |||
| <list style="numbers"> | <li>Let output be an empty string.</li> | |||
| <t>Append “=” to output.</t> | <li> | |||
| <t>If member_value is an array, append the result of running Serializi | <t>For each member_key with a value of (member_value, parameters) | |||
| ng an Inner List (<xref target="ser-innerlist"/>) with (member_value, parameters | in input_dictionary: | |||
| ) to output.</t> | </t> | |||
| <t>Otherwise, append the result of running Serializing an Item (<xref | <ol> | |||
| target="ser-item"/>) with (member_value, parameters) to output.</t> | <li>Append the result of running Serializing a Key (<xref target | |||
| </list></t> | ="ser-key"/>) with member's member_key | |||
| <t>If more members remain in input_dictionary: | to output.</li> | |||
| <list style="numbers"> | <li> | |||
| <t>Append “,” to output.</t> | <t>If member_value is Boolean true: | |||
| <t>Append a single SP to output.</t> | </t> | |||
| </list></t> | <ol> | |||
| </list></t> | <li>Append the result of running Serializing Parameters | |||
| <t>Return output.</t> | (<xref target="ser-params"/>) with | |||
| </list></t> | parameters to output.</li> | |||
| </ol> | ||||
| </section> | </li> | |||
| <section anchor="ser-item" title="Serializing an Item"> | <li> | |||
| <t>Otherwise: | ||||
| <t>Given an Item as bare_item and Parameters as item_parameters, return an ASCII | </t> | |||
| string suitable for use in a HTTP field value.</t> | <ol> | |||
| <li>Append "=" to output.</li> | ||||
| <t><list style="numbers"> | <li>If member_value is an array, append the result of | |||
| <t>Let output be an empty string.</t> | running Serializing an Inner List (<xref target="ser-innerlis | |||
| <t>Append the result of running Serializing a Bare Item <xref target="ser-bare | t"/>) with | |||
| -item"/> with bare_item to output.</t> | (member_value, parameters) to output.</li> | |||
| <t>Append the result of running Serializing Parameters <xref target="ser-param | <li>Otherwise, append the result of running Serializing an | |||
| s"/> with item_parameters to output.</t> | Item (<xref target="ser-item"/>) with | |||
| <t>Return output.</t> | (member_value, parameters) to output.</li> | |||
| </list></t> | </ol> | |||
| </li> | ||||
| <section anchor="ser-bare-item" title="Serializing a Bare Item"> | <li> | |||
| <t>If more members remain in input_dictionary: | ||||
| <t>Given an Item as input_item, return an ASCII string suitable for use in a HTT | </t> | |||
| P field value.</t> | <ol> | |||
| <li>Append "," to output.</li> | ||||
| <t><list style="numbers"> | <li>Append a single SP to output.</li> | |||
| <t>If input_item is an Integer, return the result of running Serializing an In | </ol> | |||
| teger (<xref target="ser-integer"/>) with input_item.</t> | </li> | |||
| <t>If input_item is a Decimal, return the result of running Serializing a Deci | </ol> | |||
| mal (<xref target="ser-decimal"/>) with input_item.</t> | </li> | |||
| <t>If input_item is a String, return the result of running Serializing a Strin | <li>Return output.</li> | |||
| g (<xref target="ser-string"/>) with input_item.</t> | </ol> | |||
| <t>If input_item is a Token, return the result of running Serializing a Token | </section> | |||
| (<xref target="ser-token"/>) with input_item.</t> | <section anchor="ser-item"> | |||
| <t>If input_item is a Boolean, return the result of running Serializing a Bool | <name>Serializing an Item</name> | |||
| ean (<xref target="ser-boolean"/>) with input_item.</t> | <t>Given an Item as bare_item and Parameters as item_parameters, | |||
| <t>If input_item is a Byte Sequence, return the result of running Serializing | return an ASCII string suitable for use in an HTTP field value.</t> | |||
| a Byte Sequence (<xref target="ser-binary"/>) with input_item.</t> | <ol> | |||
| <t>Otherwise, fail serialization.</t> | <li>Let output be an empty string.</li> | |||
| </list></t> | <li>Append the result of running Serializing a Bare Item (<xref targ | |||
| et="ser-bare-item"/>) with bare_item to | ||||
| </section> | output.</li> | |||
| </section> | <li>Append the result of running Serializing Parameters (<xref targe | |||
| <section anchor="ser-integer" title="Serializing an Integer"> | t="ser-params"/>) with item_parameters to | |||
| output.</li> | ||||
| <t>Given an Integer as input_integer, return an ASCII string suitable for use in | <li>Return output.</li> | |||
| a HTTP field value.</t> | </ol> | |||
| <section anchor="ser-bare-item"> | ||||
| <t><list style="numbers"> | <name>Serializing a Bare Item</name> | |||
| <t>If input_integer is not an integer in the range of -999,999,999,999,999 to | <t>Given an Item as input_item, return an ASCII string suitable | |||
| 999,999,999,999,999 inclusive, fail serialization.</t> | for use in an HTTP field value.</t> | |||
| <t>Let output be an empty string.</t> | <ol> | |||
| <t>If input_integer is less than (but not equal to) 0, append “-“ to output.</ | <li>If input_item is an Integer, return the result of running | |||
| t> | Serializing an Integer (<xref target="ser-integer"/>) with input_it | |||
| <t>Append input_integer’s numeric value represented in base 10 using only deci | em.</li> | |||
| mal digits to output.</t> | <li>If input_item is a Decimal, return the result of running | |||
| <t>Return output.</t> | Serializing a Decimal (<xref target="ser-decimal"/>) with input_ite | |||
| </list></t> | m.</li> | |||
| <li>If input_item is a String, return the result of running | ||||
| </section> | Serializing a String (<xref target="ser-string"/>) with input_item. | |||
| <section anchor="ser-decimal" title="Serializing a Decimal"> | </li> | |||
| <li>If input_item is a Token, return the result of running | ||||
| <t>Given a decimal number as input_decimal, return an ASCII string suitable for | Serializing a Token (<xref target="ser-token"/>) with input_item.</ | |||
| use in a HTTP field value.</t> | li> | |||
| <li>If input_item is a Byte Sequence, return the result of | ||||
| <t><list style="numbers"> | running Serializing a Byte Sequence (<xref target="ser-binary"/>) w | |||
| <t>If input_decimal is not a decimal number, fail serialization.</t> | ith input_item.</li> | |||
| <t>If input_decimal has more than three significant digits to the right of the | <li>If input_item is a Boolean, return the result of running | |||
| decimal point, round it to three decimal places, rounding the final digit to th | Serializing a Boolean (<xref target="ser-boolean"/>) with | |||
| e nearest value, or to the even value if it is equidistant.</t> | input_item.</li> | |||
| <t>If input_decimal has more than 12 significant digits to the left of the dec | <li>Otherwise, fail serialization.</li> | |||
| imal point after rounding, fail serialization.</t> | ||||
| <t>Let output be an empty string.</t> | ||||
| <t>If input_decimal is less than (but not equal to) 0, append “-“ to output.</ | ||||
| t> | ||||
| <t>Append input_decimal’s integer component represented in base 10 (using only | ||||
| decimal digits) to output; if it is zero, append “0”.</t> | ||||
| <t>Append “.” to output.</t> | ||||
| <t>If input_decimal’s fractional component is zero, append “0” to output.</t> | ||||
| <t>Otherwise, append the significant digits of input_decimal’s fractional comp | ||||
| onent represented in base 10 (using only decimal digits) to output.</t> | ||||
| <t>Return output.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="ser-string" title="Serializing a String"> | ||||
| <t>Given a String as input_string, return an ASCII string suitable for use in a | ||||
| HTTP field value.</t> | ||||
| <t><list style="numbers"> | ||||
| <t>Convert input_string into a sequence of ASCII characters; if conversion fai | ||||
| ls, fail serialization.</t> | ||||
| <t>If input_string contains characters in the range %x00-1f or %x7f (i.e., not | ||||
| in VCHAR or SP), fail serialization.</t> | ||||
| <t>Let output be the string DQUOTE.</t> | ||||
| <t>For each character char in input_string: | ||||
| <list style="numbers"> | ||||
| <t>If char is “\” or DQUOTE: | ||||
| <list style="numbers"> | ||||
| <t>Append “\” to output.</t> | ||||
| </list></t> | ||||
| <t>Append char to output.</t> | ||||
| </list></t> | ||||
| <t>Append DQUOTE to output.</t> | ||||
| <t>Return output.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="ser-token" title="Serializing a Token"> | ||||
| <t>Given a Token as input_token, return an ASCII string suitable for use in a HT | ||||
| TP field value.</t> | ||||
| <t><list style="numbers"> | ||||
| <t>Convert input_token into a sequence of ASCII characters; if conversion fail | ||||
| s, fail serialization.</t> | ||||
| <t>If the first character of input_token is not ALPHA or “*”, or the remaining | ||||
| portion contains a character not in tchar, “:” or “/”, fail serialization.</t> | ||||
| <t>Let output be an empty string.</t> | ||||
| <t>Append input_token to output.</t> | ||||
| <t>Return output.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="ser-binary" title="Serializing a Byte Sequence"> | ||||
| <t>Given a Byte Sequence as input_bytes, return an ASCII string suitable for use | ||||
| in a HTTP field value.</t> | ||||
| <t><list style="numbers"> | ||||
| <t>If input_bytes is not a sequence of bytes, fail serialization.</t> | ||||
| <t>Let output be an empty string.</t> | ||||
| <t>Append “:” to output.</t> | ||||
| <t>Append the result of base64-encoding input_bytes as per <xref target="RFC46 | ||||
| 48"/>, Section 4, taking account of the requirements below.</t> | ||||
| <t>Append “:” to output.</t> | ||||
| <t>Return output.</t> | ||||
| </list></t> | ||||
| <t>The encoded data is required to be padded with “=”, as per <xref target="RFC4 | ||||
| 648"/>, Section 3.2.</t> | ||||
| <t>Likewise, encoded data SHOULD have pad bits set to zero, as per <xref target= | ||||
| "RFC4648"/>, Section 3.5, unless it is not possible to do so due to implementati | ||||
| on constraints.</t> | ||||
| </section> | ||||
| <section anchor="ser-boolean" title="Serializing a Boolean"> | ||||
| <t>Given a Boolean as input_boolean, return an ASCII string suitable for use in | ||||
| a HTTP field value.</t> | ||||
| <t><list style="numbers"> | ||||
| <t>If input_boolean is not a boolean, fail serialization.</t> | ||||
| <t>Let output be an empty string.</t> | ||||
| <t>Append “?” to output.</t> | ||||
| <t>If input_boolean is true, append “1” to output.</t> | ||||
| <t>If input_boolean is false, append “0” to output.</t> | ||||
| <t>Return output.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="text-parse" title="Parsing Structured Fields"> | ||||
| <t>When a receiving implementation parses HTTP fields that are known to be Struc | ||||
| tured Fields, it is important that care be taken, as there are a number of edge | ||||
| cases that can cause interoperability or even security problems. This section sp | ||||
| ecifies the algorithm for doing so.</t> | ||||
| <t>Given an array of bytes input_bytes that represents the chosen field’s field- | ||||
| value (which is empty if that field is not present), and field_type (one of “dic | ||||
| tionary”, “list”, or “item”), return the parsed header value.</t> | ||||
| <t><list style="numbers"> | ||||
| <t>Convert input_bytes into an ASCII string input_string; if conversion fails, | ||||
| fail parsing.</t> | ||||
| <t>Discard any leading SP characters from input_string.</t> | ||||
| <t>If field_type is “list”, let output be the result of running Parsing a List | ||||
| (<xref target="parse-list"/>) with input_string.</t> | ||||
| <t>If field_type is “dictionary”, let output be the result of running Parsing | ||||
| a Dictionary (<xref target="parse-dictionary"/>) with input_string.</t> | ||||
| <t>If field_type is “item”, let output be the result of running Parsing an Ite | ||||
| m (<xref target="parse-item"/>) with input_string.</t> | ||||
| <t>Discard any leading SP characters from input_string.</t> | ||||
| <t>If input_string is not empty, fail parsing.</t> | ||||
| <t>Otherwise, return output.</t> | ||||
| </list></t> | ||||
| <t>When generating input_bytes, parsers MUST combine all field lines in the same | ||||
| section (header or trailer) that case-insensitively match the field name into o | ||||
| ne comma-separated field-value, as per <xref target="RFC7230"/>, Section 3.2.2; | ||||
| this assures that the entire field value is processed correctly.</t> | ||||
| <t>For Lists and Dictionaries, this has the effect of correctly concatenating al | ||||
| l of the field’s lines, as long as individual members of the top-level data stru | ||||
| cture are not split across multiple header instances. The parsing algorithms for | ||||
| both types allow tab characters, since these might | ||||
| be used to combine field lines by some implementations.</t> | ||||
| <t>Strings split across multiple field lines will have unpredictable results, be | ||||
| cause comma(s) and whitespace inserted upon combination will become part of the | ||||
| string output by the parser. Since concatenation might be done by an upstream in | ||||
| termediary, the results are not under the control of the serializer or the parse | ||||
| r, even when they are both under the control of the same party.</t> | ||||
| <t>Tokens, Integers, Decimals and Byte Sequences cannot be split across multiple | ||||
| field lines because the inserted commas will cause parsing to fail.</t> | ||||
| <t>Parsers MAY fail when processing a field value spread across multiple field l | ||||
| ines, when one of those lines does not parse as that field. For example, a parsi | ||||
| ng handling an Example-String field that’s defined as a sf-string is allowed to | ||||
| fail when processing this field section:</t> | ||||
| <figure><artwork type="example"><![CDATA[ | </ol> | |||
| </section> | ||||
| </section> | ||||
| <section anchor="ser-integer"> | ||||
| <name>Serializing an Integer</name> | ||||
| <t>Given an Integer as input_integer, return an ASCII string | ||||
| suitable for use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>If input_integer is not an integer in the range of | ||||
| -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | ||||
| serialization.</li> | ||||
| <li>Let output be an empty string.</li> | ||||
| <li>If input_integer is less than (but not equal to) 0, append "-" | ||||
| to output.</li> | ||||
| <li>Append input_integer's numeric value represented in base 10 | ||||
| using only decimal digits to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section anchor="ser-decimal"> | ||||
| <name>Serializing a Decimal</name> | ||||
| <t>Given a decimal number as input_decimal, return an ASCII string | ||||
| suitable for use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>If input_decimal is not a decimal number, fail serialization.</l | ||||
| i> | ||||
| <li>If input_decimal has more than three significant digits to the | ||||
| right of the decimal point, round it to three decimal places, | ||||
| rounding the final digit to the nearest value, or to the even | ||||
| value if it is equidistant.</li> | ||||
| <li>If input_decimal has more than 12 significant digits to the | ||||
| left of the decimal point after rounding, fail serialization.</li> | ||||
| <li>Let output be an empty string.</li> | ||||
| <li>If input_decimal is less than (but not equal to) 0, append "-" | ||||
| to output.</li> | ||||
| <li>Append input_decimal's integer component represented in base | ||||
| 10 (using only decimal digits) to output; if it is zero, append | ||||
| "0".</li> | ||||
| <li>Append "." to output.</li> | ||||
| <li>If input_decimal's fractional component is zero, append "0" to | ||||
| output.</li> | ||||
| <li>Otherwise, append the significant digits of input_decimal's | ||||
| fractional component represented in base 10 (using only decimal | ||||
| digits) to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section anchor="ser-string"> | ||||
| <name>Serializing a String</name> | ||||
| <t>Given a String as input_string, return an ASCII string suitable | ||||
| for use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>Convert input_string into a sequence of ASCII characters; if | ||||
| conversion fails, fail serialization.</li> | ||||
| <li>If input_string contains characters in the range %x00-1f or | ||||
| %x7f-ff (i.e., not in VCHAR or SP), fail serialization.</li> | ||||
| <li>Let output be the string DQUOTE.</li> | ||||
| <li> | ||||
| <t>For each character char in input_string: | ||||
| </t> | ||||
| <ol> | ||||
| <li> | ||||
| <t>If char is "\" or DQUOTE: | ||||
| </t> | ||||
| <ol> | ||||
| <li>Append "\" to output.</li> | ||||
| </ol> | ||||
| </li> | ||||
| <li>Append char to output.</li> | ||||
| </ol> | ||||
| </li> | ||||
| <li>Append DQUOTE to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section anchor="ser-token"> | ||||
| <name>Serializing a Token</name> | ||||
| <t>Given a Token as input_token, return an ASCII string suitable for | ||||
| use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>Convert input_token into a sequence of ASCII characters; if | ||||
| conversion fails, fail serialization.</li> | ||||
| <li>If the first character of input_token is not ALPHA or "*", or | ||||
| the remaining portion contains a character not in tchar, ":", or | ||||
| "/", fail serialization.</li> | ||||
| <li>Let output be an empty string.</li> | ||||
| <li>Append input_token to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| </section> | ||||
| <section anchor="ser-binary"> | ||||
| <name>Serializing a Byte Sequence</name> | ||||
| <t>Given a Byte Sequence as input_bytes, return an ASCII string | ||||
| suitable for use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>If input_bytes is not a sequence of bytes, fail serialization.</ | ||||
| li> | ||||
| <li>Let output be an empty string.</li> | ||||
| <li>Append ":" to output.</li> | ||||
| <li>Append the result of base64-encoding input_bytes as per <xref ta | ||||
| rget="RFC4648" sectionFormat="comma" section="4"/>, taking account of | ||||
| the requirements below.</li> | ||||
| <li>Append ":" to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| <t>The encoded data is required to be padded with "=", as per <xref ta | ||||
| rget="RFC4648" sectionFormat="comma" section="3.2"/>.</t> | ||||
| <t>Likewise, encoded data <bcp14>SHOULD</bcp14> have pad bits set to z | ||||
| ero, as per | ||||
| <xref target="RFC4648" sectionFormat="comma" section="3.5"/>, unless it | ||||
| is | ||||
| not possible to do so due to implementation constraints.</t> | ||||
| </section> | ||||
| <section anchor="ser-boolean"> | ||||
| <name>Serializing a Boolean</name> | ||||
| <t>Given a Boolean as input_boolean, return an ASCII string suitable | ||||
| for use in an HTTP field value.</t> | ||||
| <ol> | ||||
| <li>If input_boolean is not a boolean, fail serialization.</li> | ||||
| <li>Let output be an empty string.</li> | ||||
| <li>Append "?" to output.</li> | ||||
| <li>If input_boolean is true, append "1" to output.</li> | ||||
| <li>If input_boolean is false, append "0" to output.</li> | ||||
| <li>Return output.</li> | ||||
| </ol> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="text-parse"> | ||||
| <name>Parsing Structured Fields</name> | ||||
| <t>When a receiving implementation parses HTTP fields that are known | ||||
| to be Structured Fields, it is important that care be taken, as there | ||||
| are a number of edge cases that can cause interoperability or even | ||||
| security problems. This section specifies the algorithm for doing | ||||
| so.</t> | ||||
| <t>Given an array of bytes as input_bytes that represent the chosen | ||||
| field's field-value (which is empty if that field is not present) and | ||||
| field_type (one of "dictionary", "list", or "item"), return the parsed | ||||
| header value.</t> | ||||
| <ol> | ||||
| <li>Convert input_bytes into an ASCII string input_string; if | ||||
| conversion fails, fail parsing.</li> | ||||
| <li>Discard any leading SP characters from input_string.</li> | ||||
| <li>If field_type is "list", let output be the result of running | ||||
| Parsing a List (<xref target="parse-list"/>) with | ||||
| input_string.</li> | ||||
| <li>If field_type is "dictionary", let output be the result of | ||||
| running Parsing a Dictionary (<xref target="parse-dictionary"/>) with i | ||||
| nput_string.</li> | ||||
| <li>If field_type is "item", let output be the result of running | ||||
| Parsing an Item (<xref target="parse-item"/>) with | ||||
| input_string.</li> | ||||
| <li>Discard any leading SP characters from input_string.</li> | ||||
| <li>If input_string is not empty, fail parsing.</li> | ||||
| <li>Otherwise, return output.</li> | ||||
| </ol> | ||||
| <t>When generating input_bytes, parsers <bcp14>MUST</bcp14> combine all | ||||
| field lines | ||||
| in the same section (header or trailer) that case-insensitively match | ||||
| the field name into one comma-separated field-value, as per <xref target= | ||||
| "RFC7230" sectionFormat="comma" section="3.2.2"/>; this assures that | ||||
| the entire field value is processed correctly.</t> | ||||
| <t>For Lists and Dictionaries, this has the effect of correctly | ||||
| concatenating all of the field's lines, as long as individual members | ||||
| of the top-level data structure are not split across multiple header | ||||
| instances. The parsing algorithms for both types allow tab characters, | ||||
| since these might be used to combine field lines by some | ||||
| implementations.</t> | ||||
| <t>Strings split across multiple field lines will have unpredictable | ||||
| results, because one or more commas (with optional whitespace) | ||||
| will become part of the string output by the parser. Since | ||||
| concatenation might be done by an upstream intermediary, the results | ||||
| are not under the control of the serializer or the parser, even when | ||||
| they are both under the control of the same party.</t> | ||||
| <t>Tokens, Integers, Decimals, and Byte Sequences cannot be split | ||||
| across multiple field lines because the inserted commas will cause | ||||
| parsing to fail.</t> | ||||
| <t>Parsers <bcp14>MAY</bcp14> fail when processing a field value spread | ||||
| across | ||||
| multiple field lines, when one of those lines does not parse as that | ||||
| field. For example, a parsing handling an Example-String field that's | ||||
| defined as an sf-string is allowed to fail when processing this field | ||||
| section:</t> | ||||
| <sourcecode type="http-message"> | ||||
| Example-String: "foo | Example-String: "foo | |||
| Example-String: bar" | Example-String: bar" | |||
| ]]></artwork></figure> | </sourcecode> | |||
| <t>If parsing fails -- including when calling another algorithm -- the | ||||
| <t>If parsing fails – including when calling another algorithm – the entire fiel | entire field value <bcp14>MUST</bcp14> be ignored (i.e., treated as if th | |||
| d value MUST be ignored (i.e., treated as if the field were not present in the s | e field were | |||
| ection). This is intentionally strict, to improve interoperability and safety, a | not present in the section). This is intentionally strict, to improve | |||
| nd specifications referencing this document are not allowed to loosen this requi | interoperability and safety, and specifications referencing this | |||
| rement.</t> | document are not allowed to loosen this requirement.</t> | |||
| <t>Note that this requirement does not apply to an implementation that | ||||
| <t>Note that this requirement does not apply to an implementation that is not pa | is not parsing the field; for example, an intermediary is not required | |||
| rsing the field; for example, an intermediary is not required to strip a failing | to strip a failing field from a message before forwarding it.</t> | |||
| field from a message before forwarding it.</t> | <section anchor="parse-list"> | |||
| <name>Parsing a List</name> | ||||
| <section anchor="parse-list" title="Parsing a List"> | <t>Given an ASCII string as input_string, return an array of | |||
| (item_or_inner_list, parameters) tuples. input_string is modified to | ||||
| <t>Given an ASCII string as input_string, return an array of (item_or_inner_list | remove the parsed value.</t> | |||
| , parameters) tuples. input_string is modified to remove the parsed value.</t> | <ol> | |||
| <li>Let members be an empty array.</li> | ||||
| <t><list style="numbers"> | <li> | |||
| <t>Let members be an empty array.</t> | <t>While input_string is not empty: | |||
| <t>While input_string is not empty: | </t> | |||
| <list style="numbers"> | <ol> | |||
| <t>Append the result of running Parsing an Item or Inner List (<xref targe | <li>Append the result of running Parsing an Item or Inner List | |||
| t="parse-item-or-list"/>) with input_string to members.</t> | (<xref target="parse-item-or-list"/>) with | |||
| <t>Discard any leading OWS characters from input_string.</t> | input_string to members.</li> | |||
| <t>If input_string is empty, return members.</t> | <li>Discard any leading OWS characters from input_string.</li> | |||
| <t>Consume the first character of input_string; if it is not “,”, fail par | <li>If input_string is empty, return members.</li> | |||
| sing.</t> | <li>Consume the first character of input_string; if it is not | |||
| <t>Discard any leading OWS characters from input_string.</t> | ",", fail parsing.</li> | |||
| <t>If input_string is empty, there is a trailing comma; fail parsing.</t> | <li>Discard any leading OWS characters from input_string.</li> | |||
| </list></t> | <li>If input_string is empty, there is a trailing comma; fail pa | |||
| <t>No structured data has been found; return members (which is empty).</t> | rsing.</li> | |||
| </list></t> | </ol> | |||
| </li> | ||||
| <section anchor="parse-item-or-list" title="Parsing an Item or Inner List"> | <li>No structured data has been found; return members (which is empt | |||
| y).</li> | ||||
| <t>Given an ASCII string as input_string, return the tuple (item_or_inner_list, | </ol> | |||
| parameters), where item_or_inner_list can be either a single bare item, or an ar | <section anchor="parse-item-or-list"> | |||
| ray of (bare_item, parameters) tuples. input_string is modified to remove the pa | <name>Parsing an Item or Inner List</name> | |||
| rsed value.</t> | <t>Given an ASCII string as input_string, return the tuple | |||
| (item_or_inner_list, parameters), where item_or_inner_list can be | ||||
| <t><list style="numbers"> | either a single bare item or an array of (bare_item, parameters) | |||
| <t>If the first character of input_string is “(“, return the result of running | tuples. input_string is modified to remove the parsed value.</t> | |||
| Parsing an Inner List (<xref target="parse-innerlist"/>) with input_string.</t> | <ol> | |||
| <t>Return the result of running Parsing an Item (<xref target="parse-item"/>) | <li>If the first character of input_string is "(", return the | |||
| with input_string.</t> | result of running Parsing an Inner List (<xref target="parse-innerl | |||
| </list></t> | ist"/>) with | |||
| input_string.</li> | ||||
| </section> | <li>Return the result of running Parsing an Item (<xref target="pa | |||
| <section anchor="parse-innerlist" title="Parsing an Inner List"> | rse-item"/>) with input_string.</li> | |||
| </ol> | ||||
| <t>Given an ASCII string as input_string, return the tuple (inner_list, paramete | </section> | |||
| rs), where inner_list is an array of (bare_item, parameters) tuples. input_strin | <section anchor="parse-innerlist"> | |||
| g is modified to remove the parsed value.</t> | <name>Parsing an Inner List</name> | |||
| <t>Given an ASCII string as input_string, return the tuple | ||||
| <t><list style="numbers"> | (inner_list, parameters), where inner_list is an array of | |||
| <t>Consume the first character of input_string; if it is not “(“, fail parsing | (bare_item, parameters) tuples. input_string is modified to remove | |||
| .</t> | the parsed value.</t> | |||
| <t>Let inner_list be an empty array.</t> | <ol> | |||
| <t>While input_string is not empty: | <li>Consume the first character of input_string; if it is not | |||
| <list style="numbers"> | "(", fail parsing.</li> | |||
| <t>Discard any leading SP characters from input_string.</t> | <li>Let inner_list be an empty array.</li> | |||
| <t>If the first character of input_string is “)”: | <li> | |||
| <list style="numbers"> | <t>While input_string is not empty: | |||
| <t>Consume the first character of input_string.</t> | </t> | |||
| <t>Let parameters be the result of running Parsing Parameters (<xref t | <ol> | |||
| arget="parse-param"/>) with input_string.</t> | <li>Discard any leading SP characters from input_string.</li> | |||
| <t>Return the tuple (inner_list, parameters).</t> | <li> | |||
| </list></t> | <t>If the first character of input_string is ")": | |||
| <t>Let item be the result of running Parsing an Item (<xref target="parse- | </t> | |||
| item"/>) with input_string.</t> | <ol> | |||
| <t>Append item to inner_list.</t> | <li>Consume the first character of input_string.</li> | |||
| <t>If the first character of input_string is not SP or “)”, fail parsing.< | <li>Let parameters be the result of running Parsing | |||
| /t> | Parameters (<xref target="parse-param"/>) with input_string | |||
| </list></t> | .</li> | |||
| <t>The end of the inner list was not found; fail parsing.</t> | <li>Return the tuple (inner_list, parameters).</li> | |||
| </list></t> | </ol> | |||
| </li> | ||||
| </section> | <li>Let item be the result of running Parsing an Item (<xref t | |||
| </section> | arget="parse-item"/>) with | |||
| <section anchor="parse-dictionary" title="Parsing a Dictionary"> | input_string.</li> | |||
| <li>Append item to inner_list.</li> | ||||
| <t>Given an ASCII string as input_string, return an ordered map whose values are | <li>If the first character of input_string is not SP or ")", | |||
| (item_or_inner_list, parameters) tuples. input_string is modified to remove the | fail parsing.</li> | |||
| parsed value.</t> | </ol> | |||
| </li> | ||||
| <t><list style="numbers"> | <li>The end of the Inner List was not found; fail parsing.</li> | |||
| <t>Let dictionary be an empty, ordered map.</t> | </ol> | |||
| <t>While input_string is not empty: | </section> | |||
| <list style="numbers"> | </section> | |||
| <t>Let this_key be the result of running Parsing a Key (<xref target="pars | <section anchor="parse-dictionary"> | |||
| e-key"/>) with input_string.</t> | <name>Parsing a Dictionary</name> | |||
| <t>If the first character of input_string is “=”: | <t>Given an ASCII string as input_string, return an ordered map | |||
| <list style="numbers"> | whose values are (item_or_inner_list, parameters) | |||
| <t>Consume the first character of input_string.</t> | tuples. input_string is modified to remove the parsed value.</t> | |||
| <t>Let member be the result of running Parsing an Item or Inner List ( | <ol> | |||
| <xref target="parse-item-or-list"/>) with input_string.</t> | <li>Let dictionary be an empty, ordered map.</li> | |||
| </list></t> | <li> | |||
| <t>Otherwise: | <t>While input_string is not empty: | |||
| <list style="numbers"> | </t> | |||
| <t>Let value be Boolean true.</t> | <ol> | |||
| <t>Let parameters be the result of running Parsing Parameters <xref ta | <li>Let this_key be the result of running Parsing a Key (<xref t | |||
| rget="parse-param"/> with input_string.</t> | arget="parse-key"/>) with input_string.</li> | |||
| <t>Let member be the tuple (value, parameters).</t> | <li> | |||
| </list></t> | <t>If the first character of input_string is "=": | |||
| <t>Add name this_key with value member to dictionary. If dictionary alread | </t> | |||
| y contains a name this_key (comparing character-for-character), overwrite its va | <ol> | |||
| lue.</t> | <li>Consume the first character of input_string.</li> | |||
| <t>Discard any leading OWS characters from input_string.</t> | <li>Let member be the result of running Parsing an Item or | |||
| <t>If input_string is empty, return dictionary.</t> | Inner List (<xref target="parse-item-or-list"/>) with input_s | |||
| <t>Consume the first character of input_string; if it is not “,”, fail par | tring.</li> | |||
| sing.</t> | </ol> | |||
| <t>Discard any leading OWS characters from input_string.</t> | </li> | |||
| <t>If input_string is empty, there is a trailing comma; fail parsing.</t> | <li> | |||
| </list></t> | <t>Otherwise: | |||
| <t>No structured data has been found; return dictionary (which is empty).</t> | </t> | |||
| </list></t> | <ol> | |||
| <li>Let value be Boolean true.</li> | ||||
| <t>Note that when duplicate Dictionary keys are encountered, this has the effect | <li>Let parameters be the result of running Parsing | |||
| of ignoring all but the last instance.</t> | Parameters (<xref target="parse-param"/>) | |||
| with input_string.</li> | ||||
| </section> | <li>Let member be the tuple (value, parameters).</li> | |||
| <section anchor="parse-item" title="Parsing an Item"> | </ol> | |||
| </li> | ||||
| <t>Given an ASCII string as input_string, return a (bare_item, parameters) tuple | <li>If dictionary already contains a key this_key (comparing cha | |||
| . input_string is modified to remove the parsed value.</t> | racter for character), overwrite its value with member.</li> | |||
| <li>Otherwise, append key this_key with value member to dictionar | ||||
| <t><list style="numbers"> | y.</li> | |||
| <t>Let bare_item be the result of running Parsing a Bare Item (<xref target="p | <li>Discard any leading OWS characters from input_string.</li> | |||
| arse-bare-item"/>) with input_string.</t> | <li>If input_string is empty, return dictionary.</li> | |||
| <t>Let parameters be the result of running Parsing Parameters (<xref target="p | <li>Consume the first character of input_string; if it is not | |||
| arse-param"/>) with input_string.</t> | ",", fail parsing.</li> | |||
| <t>Return the tuple (bare_item, parameters).</t> | <li>Discard any leading OWS characters from input_string.</li> | |||
| </list></t> | <li>If input_string is empty, there is a trailing comma; fail pa | |||
| rsing.</li> | ||||
| <section anchor="parse-bare-item" title="Parsing a Bare Item"> | </ol> | |||
| </li> | ||||
| <t>Given an ASCII string as input_string, return a bare Item. input_string is mo | <li>No structured data has been found; return dictionary (which is e | |||
| dified to remove the parsed value.</t> | mpty).</li> | |||
| </ol> | ||||
| <t><list style="numbers"> | <t>Note that when duplicate Dictionary keys are encountered, all but | |||
| <t>If the first character of input_string is a “-“ or a DIGIT, return the resu | the last instance are ignored.</t> | |||
| lt of running Parsing an Integer or Decimal (<xref target="parse-number"/>) with | </section> | |||
| input_string.</t> | <section anchor="parse-item"> | |||
| <t>If the first character of input_string is a DQUOTE, return the result of ru | <name>Parsing an Item</name> | |||
| nning Parsing a String (<xref target="parse-string"/>) with input_string.</t> | <t>Given an ASCII string as input_string, return a (bare_item, | |||
| <t>If the first character of input_string is “:”, return the result of running | parameters) tuple. input_string is modified to remove the parsed | |||
| Parsing a Byte Sequence (<xref target="parse-binary"/>) with input_string.</t> | value.</t> | |||
| <t>If the first character of input_string is “?”, return the result of running | <ol> | |||
| Parsing a Boolean (<xref target="parse-boolean"/>) with input_string.</t> | <li>Let bare_item be the result of running Parsing a Bare Item | |||
| <t>If the first character of input_string is an ALPHA or “*”, return the resul | (<xref target="parse-bare-item"/>) with | |||
| t of running Parsing a Token (<xref target="parse-token"/>) with input_string.</ | input_string.</li> | |||
| t> | <li>Let parameters be the result of running Parsing Parameters | |||
| <t>Otherwise, the item type is unrecognized; fail parsing.</t> | (<xref target="parse-param"/>) with | |||
| </list></t> | input_string.</li> | |||
| <li>Return the tuple (bare_item, parameters).</li> | ||||
| </section> | </ol> | |||
| <section anchor="parse-param" title="Parsing Parameters"> | <section anchor="parse-bare-item"> | |||
| <name>Parsing a Bare Item</name> | ||||
| <t>Given an ASCII string as input_string, return an ordered map whose values are | <t>Given an ASCII string as input_string, return a bare | |||
| bare Items. input_string is modified to remove the parsed value.</t> | Item. input_string is modified to remove the parsed value.</t> | |||
| <ol> | ||||
| <t><list style="numbers"> | <li>If the first character of input_string is a "-" or a DIGIT, | |||
| <t>Let parameters be an empty, ordered map.</t> | return the result of running Parsing an Integer or Decimal | |||
| <t>While input_string is not empty: | (<xref target="parse-number"/>) with | |||
| <list style="numbers"> | input_string.</li> | |||
| <t>If the first character of input_string is not “;”, exit the loop.</t> | <li>If the first character of input_string is a DQUOTE, return | |||
| <t>Consume a “;” character from the beginning of input_string.</t> | the result of running Parsing a String (<xref target="parse-string" | |||
| <t>Discard any leading SP characters from input_string.</t> | />) with | |||
| <t>let param_name be the result of running Parsing a Key (<xref target="pa | input_string.</li> | |||
| rse-key"/>) with input_string.</t> | <li>If the first character of input_string is an ALPHA or "*", | |||
| <t>Let param_value be Boolean true.</t> | return the result of running Parsing a Token (<xref target="parse-t | |||
| <t>If the first character of input_string is “=”: | oken"/>) with input_string.</li> | |||
| <list style="numbers"> | <li>If the first character of input_string is ":", return the | |||
| <t>Consume the “=” character at the beginning of input_string.</t> | result of running Parsing a Byte Sequence (<xref target="parse-bina | |||
| <t>Let param_value be the result of running Parsing a Bare Item (<xref | ry"/>) with | |||
| target="parse-bare-item"/>) with input_string.</t> | input_string.</li> | |||
| </list></t> | <li>If the first character of input_string is "?", return the | |||
| <t>Append key param_name with value param_value to parameters. If paramete | result of running Parsing a Boolean (<xref target="parse-boolean"/> | |||
| rs already contains a name param_name (comparing character-for-character), overw | ) with | |||
| rite its value.</t> | input_string.</li> | |||
| </list></t> | <li>Otherwise, the item type is unrecognized; fail parsing.</li> | |||
| <t>Return parameters.</t> | </ol> | |||
| </list></t> | </section> | |||
| <section anchor="parse-param"> | ||||
| <t>Note that when duplicate Parameter keys are encountered, this has the effect | <name>Parsing Parameters</name> | |||
| of ignoring all but the last instance.</t> | <t>Given an ASCII string as input_string, return an ordered map | |||
| whose values are bare Items. input_string is modified to remove | ||||
| </section> | the parsed value.</t> | |||
| <section anchor="parse-key" title="Parsing a Key"> | <ol> | |||
| <li>Let parameters be an empty, ordered map.</li> | ||||
| <t>Given an ASCII string as input_string, return a key. input_string is modified | <li> | |||
| to remove the parsed value.</t> | <t>While input_string is not empty: | |||
| </t> | ||||
| <t><list style="numbers"> | <ol> | |||
| <t>If the first character of input_string is not lcalpha or “*”, fail parsing. | <li>If the first character of input_string is not ";", exit th | |||
| </t> | e loop.</li> | |||
| <t>Let output_string be an empty string.</t> | <li>Consume the ";" character from the beginning of input_stri | |||
| <t>While input_string is not empty: | ng.</li> | |||
| <list style="numbers"> | <li>Discard any leading SP characters from input_string.</li> | |||
| <t>If the first character of input_string is not one of lcalpha, DIGIT, “_ | <li>Let param_key be the result of running Parsing a Key | |||
| ”, “-“, “.”, or “*”, return output_string.</t> | (<xref target="parse-key"/>) with | |||
| <t>Let char be the result of consuming the first character of input_string | input_string.</li> | |||
| .</t> | <li>Let param_value be Boolean true.</li> | |||
| <t>Append char to output_string.</t> | <li> | |||
| </list></t> | <t>If the first character of input_string is "=": | |||
| <t>Return output_string.</t> | </t> | |||
| </list></t> | <ol> | |||
| <li>Consume the "=" character at the beginning of input_st | ||||
| </section> | ring.</li> | |||
| </section> | <li>Let param_value be the result of running Parsing a | |||
| <section anchor="parse-number" title="Parsing an Integer or Decimal"> | Bare Item (<xref target="parse-bare-item"/>) with input_str | |||
| ing.</li> | ||||
| <t>Given an ASCII string as input_string, return an Integer or Decimal. input_st | </ol> | |||
| ring is modified to remove the parsed value.</t> | </li> | |||
| <li>If parameters already contains a key param_key (comparing | ||||
| <t>NOTE: This algorithm parses both Integers (<xref target="integer"/>) and Deci | character for character), overwrite its value with param_value.</li> | |||
| mals (<xref target="decimal"/>), and returns the corresponding structure.</t> | <li>Otherwise, append key param_key with value param_value to p | |||
| arameters.</li> | ||||
| <t><list style="numbers"> | </ol> | |||
| <t>Let type be “integer”.</t> | </li> | |||
| <t>Let sign be 1.</t> | <li>Return parameters.</li> | |||
| <t>Let input_number be an empty string.</t> | </ol> | |||
| <t>If the first character of input_string is “-“, consume it and set sign to - | <t>Note that when duplicate parameter keys are encountered, | |||
| 1.</t> | all but the last instance are ignored.</t> | |||
| <t>If input_string is empty, there is an empty integer; fail parsing.</t> | </section> | |||
| <t>If the first character of input_string is not a DIGIT, fail parsing.</t> | <section anchor="parse-key"> | |||
| <t>While input_string is not empty: | <name>Parsing a Key</name> | |||
| <list style="numbers"> | <t>Given an ASCII string as input_string, return a | |||
| <t>Let char be the result of consuming the first character of input_string | key. input_string is modified to remove the parsed value.</t> | |||
| .</t> | <ol> | |||
| <t>If char is a DIGIT, append it to input_number.</t> | <li>If the first character of input_string is not lcalpha or | |||
| <t>Else, if type is “integer” and char is “.”: | "*", fail parsing.</li> | |||
| <list style="numbers"> | <li>Let output_string be an empty string.</li> | |||
| <t>If input_number contains more than 12 characters, fail parsing.</t> | <li> | |||
| <t>Otherwise, append char to input_number and set type to “decimal”.</ | <t>While input_string is not empty: | |||
| t> | </t> | |||
| </list></t> | <ol> | |||
| <t>Otherwise, prepend char to input_string, and exit the loop.</t> | <li>If the first character of input_string is not one of | |||
| <t>If type is “integer” and input_number contains more than 15 characters, | lcalpha, DIGIT, "_", "-", ".", or "*", return | |||
| fail parsing.</t> | output_string.</li> | |||
| <t>If type is “decimal” and input_number contains more than 16 characters, | <li>Let char be the result of consuming the first character of | |||
| fail parsing.</t> | input_string.</li> | |||
| </list></t> | <li>Append char to output_string.</li> | |||
| <t>If type is “integer”: | </ol> | |||
| <list style="numbers"> | </li> | |||
| <t>Parse input_number as an integer and let output_number be the product o | <li>Return output_string.</li> | |||
| f the result and sign.</t> | </ol> | |||
| <t>If output_number is outside the range -999,999,999,999,999 to 999,999,9 | </section> | |||
| 99,999,999 inclusive, fail parsing.</t> | </section> | |||
| </list></t> | <section anchor="parse-number"> | |||
| <t>Otherwise: | <name>Parsing an Integer or Decimal</name> | |||
| <list style="numbers"> | <t>Given an ASCII string as input_string, return an Integer or | |||
| <t>If the final character of input_number is “.”, fail parsing.</t> | Decimal. input_string is modified to remove the parsed value.</t> | |||
| <t>If the number of characters after “.” in input_number is greater than t | <t>NOTE: This algorithm parses both Integers (<xref target="integer"/> | |||
| hree, fail parsing.</t> | ) and Decimals (<xref target="decimal"/>), and returns the corresponding structu | |||
| <t>Parse input_number as a decimal number and let output_number be the pro | re.</t> | |||
| duct of the result and sign.</t> | <ol> | |||
| </list></t> | <li>Let type be "integer".</li> | |||
| <t>Return output_number.</t> | <li>Let sign be 1.</li> | |||
| </list></t> | <li>Let input_number be an empty string.</li> | |||
| <li>If the first character of input_string is "-", consume it and | ||||
| </section> | set sign to -1.</li> | |||
| <section anchor="parse-string" title="Parsing a String"> | <li>If input_string is empty, there is an empty integer; fail | |||
| parsing.</li> | ||||
| <t>Given an ASCII string as input_string, return an unquoted String. input_strin | <li>If the first character of input_string is not a DIGIT, fail | |||
| g is modified to remove the parsed value.</t> | parsing.</li> | |||
| <li> | ||||
| <t><list style="numbers"> | <t>While input_string is not empty: | |||
| <t>Let output_string be an empty string.</t> | </t> | |||
| <t>If the first character of input_string is not DQUOTE, fail parsing.</t> | <ol> | |||
| <t>Discard the first character of input_string.</t> | <li>Let char be the result of consuming the first character of | |||
| <t>While input_string is not empty: | input_string.</li> | |||
| <list style="numbers"> | <li>If char is a DIGIT, append it to input_number.</li> | |||
| <t>Let char be the result of consuming the first character of input_string | <li> | |||
| .</t> | <t>Else, if type is "integer" and char is ".": | |||
| <t>If char is a backslash (“\”): | </t> | |||
| <list style="numbers"> | <ol> | |||
| <t>If input_string is now empty, fail parsing.</t> | <li>If input_number contains more than 12 characters, fail p | |||
| <t>Let next_char be the result of consuming the first character of inp | arsing.</li> | |||
| ut_string.</t> | <li>Otherwise, append char to input_number and set type to " | |||
| <t>If next_char is not DQUOTE or “\”, fail parsing.</t> | decimal".</li> | |||
| <t>Append next_char to output_string.</t> | </ol> | |||
| </list></t> | </li> | |||
| <t>Else, if char is DQUOTE, return output_string.</t> | <li>Otherwise, prepend char to input_string, and exit the loop.< | |||
| <t>Else, if char is in the range %x00-1f or %x7f (i.e., is not in VCHAR or | /li> | |||
| SP), fail parsing.</t> | <li>If type is "integer" and input_number contains more than | |||
| <t>Else, append char to output_string.</t> | 15 characters, fail parsing.</li> | |||
| </list></t> | <li>If type is "decimal" and input_number contains more than | |||
| <t>Reached the end of input_string without finding a closing DQUOTE; fail pars | 16 characters, fail parsing.</li> | |||
| ing.</t> | </ol> | |||
| </list></t> | </li> | |||
| <li> | ||||
| </section> | <t>If type is "integer": | |||
| <section anchor="parse-token" title="Parsing a Token"> | </t> | |||
| <ol> | ||||
| <t>Given an ASCII string as input_string, return a Token. input_string is modifi | <li>Parse input_number as an integer and let output_number be | |||
| ed to remove the parsed value.</t> | the product of the result and sign.</li> | |||
| </ol> | ||||
| <t><list style="numbers"> | </li> | |||
| <t>If the first character of input_string is not ALPHA or “*”, fail parsing.</ | <li> | |||
| t> | <t>Otherwise: | |||
| <t>Let output_string be an empty string.</t> | </t> | |||
| <t>While input_string is not empty: | <ol> | |||
| <list style="numbers"> | <li>If the final character of input_number is ".", fail parsing. | |||
| <t>If the first character of input_string is not in tchar, “:” or “/”, ret | </li> | |||
| urn output_string.</t> | <li>If the number of characters after "." in input_number is | |||
| <t>Let char be the result of consuming the first character of input_string | greater than three, fail parsing.</li> | |||
| .</t> | <li>Parse input_number as a decimal number and let | |||
| <t>Append char to output_string.</t> | output_number be the product of the result and sign.</li> | |||
| </list></t> | </ol> | |||
| <t>Return output_string.</t> | </li> | |||
| </list></t> | <li>Return output_number.</li> | |||
| </ol> | ||||
| </section> | </section> | |||
| <section anchor="parse-binary" title="Parsing a Byte Sequence"> | <section anchor="parse-string"> | |||
| <name>Parsing a String</name> | ||||
| <t>Given an ASCII string as input_string, return a Byte Sequence. input_string i | <t>Given an ASCII string as input_string, return an unquoted | |||
| s modified to remove the parsed value.</t> | String. input_string is modified to remove the parsed value.</t> | |||
| <ol> | ||||
| <t><list style="numbers"> | <li>Let output_string be an empty string.</li> | |||
| <t>If the first character of input_string is not “:”, fail parsing.</t> | <li>If the first character of input_string is not DQUOTE, fail parsi | |||
| <t>Discard the first character of input_string.</t> | ng.</li> | |||
| <t>If there is not a “:” character before the end of input_string, fail parsin | <li>Discard the first character of input_string.</li> | |||
| g.</t> | <li> | |||
| <t>Let b64_content be the result of consuming content of input_string up to bu | <t>While input_string is not empty: | |||
| t not including the first instance of the character “:”.</t> | </t> | |||
| <t>Consume the “:” character at the beginning of input_string.</t> | <ol> | |||
| <t>If b64_content contains a character not included in ALPHA, DIGIT, “+”, “/” | <li>Let char be the result of consuming the first character of i | |||
| and “=”, fail parsing.</t> | nput_string.</li> | |||
| <t>Let binary_content be the result of Base 64 Decoding <xref target="RFC4648" | <li> | |||
| /> b64_content, synthesizing padding if necessary (note the requirements about r | <t>If char is a backslash ("\"): | |||
| ecipient behavior below).</t> | </t> | |||
| <t>Return binary_content.</t> | <ol> | |||
| </list></t> | <li>If input_string is now empty, fail parsing.</li> | |||
| <li>Let next_char be the result of consuming the first | ||||
| <t>Because some implementations of base64 do not allow rejection of encoded data | character of input_string.</li> | |||
| that is not properly “=” padded (see <xref target="RFC4648"/>, Section 3.2), pa | <li>If next_char is not DQUOTE or "\", fail parsing.</li> | |||
| rsers SHOULD NOT fail when “=” padding is not present, unless they cannot be con | <li>Append next_char to output_string.</li> | |||
| figured to do so.</t> | </ol> | |||
| </li> | ||||
| <t>Because some implementations of base64 do not allow rejection of encoded data | <li>Else, if char is DQUOTE, return output_string.</li> | |||
| that has non-zero pad bits (see <xref target="RFC4648"/>, Section 3.5), parsers | <li>Else, if char is in the range %x00-1f or %x7f-ff (i.e., it i | |||
| SHOULD NOT fail when non-zero pad bits are present, unless they cannot be confi | s | |||
| gured to do so.</t> | not in VCHAR or SP), fail parsing.</li> | |||
| <li>Else, append char to output_string.</li> | ||||
| <t>This specification does not relax the requirements in <xref target="RFC4648"/ | </ol> | |||
| >, Section 3.1 and 3.3; therefore, parsers MUST fail on characters outside the b | </li> | |||
| ase64 alphabet, and on line feeds in encoded data.</t> | <li>Reached the end of input_string without finding a closing | |||
| DQUOTE; fail parsing.</li> | ||||
| </section> | </ol> | |||
| <section anchor="parse-boolean" title="Parsing a Boolean"> | </section> | |||
| <section anchor="parse-token"> | ||||
| <t>Given an ASCII string as input_string, return a Boolean. input_string is modi | <name>Parsing a Token</name> | |||
| fied to remove the parsed value.</t> | <t>Given an ASCII string as input_string, return a | |||
| Token. input_string is modified to remove the parsed value.</t> | ||||
| <t><list style="numbers"> | <ol> | |||
| <t>If the first character of input_string is not “?”, fail parsing.</t> | <li>If the first character of input_string is not ALPHA or "*", | |||
| <t>Discard the first character of input_string.</t> | fail parsing.</li> | |||
| <t>If the first character of input_string matches “1”, discard the first chara | <li>Let output_string be an empty string.</li> | |||
| cter, and return true.</t> | <li> | |||
| <t>If the first character of input_string matches “0”, discard the first chara | <t>While input_string is not empty: | |||
| cter, and return false.</t> | </t> | |||
| <t>No value has matched; fail parsing.</t> | <ol> | |||
| </list></t> | <li>If the first character of input_string is not in tchar, | |||
| ":", or "/", return output_string.</li> | ||||
| </section> | <li>Let char be the result of consuming the first character of | |||
| </section> | input_string.</li> | |||
| </section> | <li>Append char to output_string.</li> | |||
| <section anchor="iana-considerations" title="IANA Considerations"> | </ol> | |||
| </li> | ||||
| <t>This document has no actions for IANA.</t> | <li>Return output_string.</li> | |||
| </ol> | ||||
| </section> | </section> | |||
| <section anchor="security-considerations" title="Security Considerations"> | <section anchor="parse-binary"> | |||
| <name>Parsing a Byte Sequence</name> | ||||
| <t>The size of most types defined by Structured Fields is not limited; as a resu | <t>Given an ASCII string as input_string, return a Byte | |||
| lt, extremely large fields could be an attack vector (e.g., for resource consump | Sequence. input_string is modified to remove the parsed value.</t> | |||
| tion). Most HTTP implementations limit the sizes of individual fields as well as | <ol> | |||
| the overall header or trailer section size to mitigate such attacks.</t> | <li>If the first character of input_string is not ":", fail parsing. | |||
| </li> | ||||
| <t>It is possible for parties with the ability to inject new HTTP fields to chan | <li>Discard the first character of input_string.</li> | |||
| ge the meaning | <li>If there is not a ":" character before the end of input_string, | |||
| of a Structured Field. In some circumstances, this will cause parsing to fail, b | fail parsing.</li> | |||
| ut it is not possible to reliably fail in all such circumstances.</t> | <li>Let b64_content be the result of consuming content of | |||
| input_string up to but not including the first instance of the | ||||
| </section> | character ":".</li> | |||
| <li>Consume the ":" character at the beginning of input_string.</li> | ||||
| <li>If b64_content contains a character not included in ALPHA, | ||||
| DIGIT, "+", "/", and "=", fail parsing.</li> | ||||
| <li>Let binary_content be the result of base64-decoding <xref target | ||||
| ="RFC4648"/> b64_content, synthesizing | ||||
| padding if necessary (note the requirements about recipient | ||||
| behavior below). If base64 decoding fails, parsing fails.</li> | ||||
| <li>Return binary_content.</li> | ||||
| </ol> | ||||
| <t>Because some implementations of base64 do not allow rejection of | ||||
| encoded data that is not properly "=" padded (see <xref target="RFC4648 | ||||
| " sectionFormat="comma" section="3.2"/>), parsers <bcp14>SHOULD | ||||
| NOT</bcp14> fail when "=" padding is not present, unless they cannot be | ||||
| configured to do so.</t> | ||||
| <t>Because some implementations of base64 do not allow rejection of | ||||
| encoded data that has non-zero pad bits (see <xref target="RFC4648" sec | ||||
| tionFormat="comma" section="3.5"/>), parsers <bcp14>SHOULD NOT</bcp14> fail when | ||||
| non-zero pad bits are present, unless they cannot be configured to | ||||
| do so.</t> | ||||
| <t>This specification does not relax the requirements in <xref target= | ||||
| "RFC4648"/>, Sections <xref target="RFC4648" sectionFormat="bare" section="3.1"/ | ||||
| > and <xref target="RFC4648" sectionFormat="bare" section="3.3"/>; therefore, | ||||
| parsers <bcp14>MUST</bcp14> fail on characters outside the base64 alpha | ||||
| bet and on line | ||||
| feeds in encoded data.</t> | ||||
| </section> | ||||
| <section anchor="parse-boolean"> | ||||
| <name>Parsing a Boolean</name> | ||||
| <t>Given an ASCII string as input_string, return a | ||||
| Boolean. input_string is modified to remove the parsed value.</t> | ||||
| <ol> | ||||
| <li>If the first character of input_string is not "?", fail parsing. | ||||
| </li> | ||||
| <li>Discard the first character of input_string.</li> | ||||
| <li>If the first character of input_string matches "1", discard | ||||
| the first character, and return true.</li> | ||||
| <li>If the first character of input_string matches "0", discard | ||||
| the first character, and return false.</li> | ||||
| <li>No value has matched; fail parsing.</li> | ||||
| </ol> | ||||
| </section> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="iana-considerations"> | ||||
| <name>IANA Considerations</name> | ||||
| <t>This document has no IANA actions.</t> | ||||
| </section> | ||||
| <section anchor="security-considerations"> | ||||
| <name>Security Considerations</name> | ||||
| <t>The size of most types defined by Structured Fields is not limited; | ||||
| as a result, extremely large fields could be an attack vector (e.g., for | ||||
| resource consumption). Most HTTP implementations limit the sizes of | ||||
| individual fields as well as the overall header or trailer section size | ||||
| to mitigate such attacks.</t> | ||||
| <t>It is possible for parties with the ability to inject new HTTP fields | ||||
| to change the meaning of a Structured Field. In some circumstances, this | ||||
| will cause parsing to fail, but it is not possible to reliably fail in | ||||
| all such circumstances.</t> | ||||
| </section> | ||||
| </middle> | </middle> | |||
| <back> | <back> | |||
| <references> | ||||
| <name>References</name> | ||||
| <references> | ||||
| <name>Normative References</name> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7230.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.2119.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8174.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.5234.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.0020.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.4648.xml"/> | ||||
| </references> | ||||
| <references> | ||||
| <name>Informative References</name> | ||||
| <reference anchor="IEEE754" target="https://ieeexplore.ieee.org/document | ||||
| /8766229"> | ||||
| <front> | ||||
| <title>IEEE Standard for Floating-Point Arithmetic</title> | ||||
| <seriesInfo name="DOI" value="10.1109/IEEESTD.2019.8766229"/> | ||||
| <seriesInfo name="IEEE" value="754-2019"/> | ||||
| <author> | ||||
| <organization>IEEE</organization> | ||||
| </author> | ||||
| <date year="2019" month="July"/> | ||||
| </front> | ||||
| </reference> | ||||
| <references title='Normative References'> | <reference anchor='STD63' target='https://www.rfc-editor.org/info/std63'> | |||
| <reference anchor="RFC7230" target='https://www.rfc-editor.org/info/rfc7230'> | ||||
| <front> | ||||
| <title>Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title | ||||
| > | ||||
| <author initials='R.' surname='Fielding' fullname='R. Fielding' role='editor'><o | ||||
| rganization /></author> | ||||
| <author initials='J.' surname='Reschke' fullname='J. Reschke' role='editor'><org | ||||
| anization /></author> | ||||
| <date year='2014' month='June' /> | ||||
| <abstract><t>The Hypertext Transfer Protocol (HTTP) is a stateless application-l | ||||
| evel protocol for distributed, collaborative, hypertext information systems. Th | ||||
| is document provides an overview of HTTP architecture and its associated termino | ||||
| logy, defines the "http" and "https" Uniform Resource Identi | ||||
| fier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements | ||||
| , and describes related security concerns for implementations.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='RFC' value='7230'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC7230'/> | ||||
| </reference> | ||||
| <reference anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'> | ||||
| <front> | ||||
| <title>Key words for use in RFCs to Indicate Requirement Levels</title> | ||||
| <author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></ | ||||
| author> | ||||
| <date year='1997' month='March' /> | ||||
| <abstract><t>In many standards track documents several words are used to signify | ||||
| the requirements in the specification. These words are often capitalized. This | ||||
| document defines these words as they should be interpreted in IETF documents. | ||||
| This document specifies an Internet Best Current Practices for the Internet Comm | ||||
| unity, and requests discussion and suggestions for improvements.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='BCP' value='14'/> | ||||
| <seriesInfo name='RFC' value='2119'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC2119'/> | ||||
| </reference> | ||||
| <reference anchor="RFC8174" target='https://www.rfc-editor.org/info/rfc8174'> | ||||
| <front> | ||||
| <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title> | ||||
| <author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></auth | ||||
| or> | ||||
| <date year='2017' month='May' /> | ||||
| <abstract><t>RFC 2119 specifies common key words that may be used in protocol s | ||||
| pecifications. This document aims to reduce the ambiguity by clarifying that on | ||||
| ly UPPERCASE usage of the key words have the defined special meanings.</t></abs | ||||
| tract> | ||||
| </front> | ||||
| <seriesInfo name='BCP' value='14'/> | ||||
| <seriesInfo name='RFC' value='8174'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC8174'/> | ||||
| </reference> | ||||
| <reference anchor="RFC5234" target='https://www.rfc-editor.org/info/rfc5234'> | ||||
| <front> | ||||
| <title>Augmented BNF for Syntax Specifications: ABNF</title> | ||||
| <author initials='D.' surname='Crocker' fullname='D. Crocker' role='editor'><org | ||||
| anization /></author> | ||||
| <author initials='P.' surname='Overell' fullname='P. Overell'><organization /></ | ||||
| author> | ||||
| <date year='2008' month='January' /> | ||||
| <abstract><t>Internet technical specifications often need to define a formal syn | ||||
| tax. Over the years, a modified version of Backus-Naur Form (BNF), called Augme | ||||
| nted BNF (ABNF), has been popular among many Internet specifications. The curre | ||||
| nt specification documents ABNF. It balances compactness and simplicity with rea | ||||
| sonable representational power. The differences between standard BNF and ABNF i | ||||
| nvolve naming rules, repetition, alternatives, order-independence, and value ran | ||||
| ges. This specification also supplies additional rule definitions and encoding | ||||
| for a core lexical analyzer of the type common to several Internet specification | ||||
| s. [STANDARDS-TRACK]</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='STD' value='68'/> | ||||
| <seriesInfo name='RFC' value='5234'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC5234'/> | ||||
| </reference> | ||||
| <reference anchor="RFC0020" target='https://www.rfc-editor.org/info/rfc20'> | ||||
| <front> | ||||
| <title>ASCII format for network interchange</title> | ||||
| <author initials='V.G.' surname='Cerf' fullname='V.G. Cerf'><organization /></au | ||||
| thor> | ||||
| <date year='1969' month='October' /> | ||||
| </front> | ||||
| <seriesInfo name='STD' value='80'/> | ||||
| <seriesInfo name='RFC' value='20'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC0020'/> | ||||
| </reference> | ||||
| <reference anchor="RFC4648" target='https://www.rfc-editor.org/info/rfc4648'> | ||||
| <front> | ||||
| <title>The Base16, Base32, and Base64 Data Encodings</title> | ||||
| <author initials='S.' surname='Josefsson' fullname='S. Josefsson'><organization | ||||
| /></author> | ||||
| <date year='2006' month='October' /> | ||||
| <abstract><t>This document describes the commonly used base 64, base 32, and bas | ||||
| e 16 encoding schemes. It also discusses the use of line-feeds in encoded data, | ||||
| use of padding in encoded data, use of non-alphabet characters in encoded data, | ||||
| use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK | ||||
| ]</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='RFC' value='4648'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC4648'/> | ||||
| </reference> | ||||
| </references> | ||||
| <references title='Informative References'> | ||||
| <reference anchor="IEEE754" target="https://ieeexplore.ieee.org/document/8766229 | ||||
| "> | ||||
| <front> | ||||
| <title>IEEE Standard for Floating-Point Arithmetic</title> | ||||
| <author > | ||||
| <organization>IEEE</organization> | ||||
| </author> | ||||
| <date year="2019" month="July"/> | ||||
| </front> | ||||
| <seriesInfo name="IEEE" value="754-2019"/> | ||||
| <seriesInfo name="DOI" value="10.1109/IEEESTD.2019.8766229"/> | ||||
| <seriesInfo name="ISBN" value="978-1-5044-5924-2"/> | ||||
| </reference> | ||||
| <reference anchor="UTF-8" target="http://www.rfc-editor.org/info/std63"> | ||||
| <front> | ||||
| <title>UTF-8, a transformation format of ISO 10646</title> | ||||
| <author initials="F." surname="Yergeau" fullname="F. Yergeau"> | ||||
| <organization></organization> | ||||
| </author> | ||||
| <date year="2003" month="November"/> | ||||
| </front> | ||||
| <seriesInfo name="STD" value="63"/> | ||||
| <seriesInfo name="RFC" value="3629"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC3629"/> | ||||
| </reference> | ||||
| <reference anchor="RFC7231" target='https://www.rfc-editor.org/info/rfc7231'> | ||||
| <front> | ||||
| <title>Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content</title> | ||||
| <author initials='R.' surname='Fielding' fullname='R. Fielding' role='editor'><o | ||||
| rganization /></author> | ||||
| <author initials='J.' surname='Reschke' fullname='J. Reschke' role='editor'><org | ||||
| anization /></author> | ||||
| <date year='2014' month='June' /> | ||||
| <abstract><t>The Hypertext Transfer Protocol (HTTP) is a stateless \%application | ||||
| - level protocol for distributed, collaborative, hypertext information systems. | ||||
| This document defines the semantics of HTTP/1.1 messages, as expressed by reque | ||||
| st methods, request header fields, response status codes, and response header fi | ||||
| elds, along with the payload of messages (metadata and body content) and mechani | ||||
| sms for content negotiation.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='RFC' value='7231'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC7231'/> | ||||
| </reference> | ||||
| <reference anchor="RFC7540" target='https://www.rfc-editor.org/info/rfc7540'> | ||||
| <front> | ||||
| <title>Hypertext Transfer Protocol Version 2 (HTTP/2)</title> | ||||
| <author initials='M.' surname='Belshe' fullname='M. Belshe'><organization /></au | ||||
| thor> | ||||
| <author initials='R.' surname='Peon' fullname='R. Peon'><organization /></author | ||||
| > | ||||
| <author initials='M.' surname='Thomson' fullname='M. Thomson' role='editor'><org | ||||
| anization /></author> | ||||
| <date year='2015' month='May' /> | ||||
| <abstract><t>This specification describes an optimized expression of the semanti | ||||
| cs of the Hypertext Transfer Protocol (HTTP), referred to as HTTP version 2 (HTT | ||||
| P/2). HTTP/2 enables a more efficient use of network resources and a reduced pe | ||||
| rception of latency by introducing header field compression and allowing multipl | ||||
| e concurrent exchanges on the same connection. It also introduces unsolicited p | ||||
| ush of representations from servers to clients.</t><t>This specification is an a | ||||
| lternative to, but does not obsolete, the HTTP/1.1 message syntax. HTTP's exist | ||||
| ing semantics remain unchanged.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='RFC' value='7540'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC7540'/> | ||||
| </reference> | ||||
| <reference anchor="RFC7541" target='https://www.rfc-editor.org/info/rfc7541'> | ||||
| <front> | ||||
| <title>HPACK: Header Compression for HTTP/2</title> | ||||
| <author initials='R.' surname='Peon' fullname='R. Peon'><organization /></author | ||||
| > | ||||
| <author initials='H.' surname='Ruellan' fullname='H. Ruellan'><organization /></ | ||||
| author> | ||||
| <date year='2015' month='May' /> | ||||
| <abstract><t>This specification defines HPACK, a compression format for efficien | ||||
| tly representing HTTP header fields, to be used in HTTP/2.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='RFC' value='7541'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC7541'/> | ||||
| </reference> | ||||
| <reference anchor="RFC8259" target='https://www.rfc-editor.org/info/rfc8259'> | ||||
| <front> | ||||
| <title>The JavaScript Object Notation (JSON) Data Interchange Format</title> | ||||
| <author initials='T.' surname='Bray' fullname='T. Bray' role='editor'><organizat | ||||
| ion /></author> | ||||
| <date year='2017' month='December' /> | ||||
| <abstract><t>JavaScript Object Notation (JSON) is a lightweight, text-based, lan | ||||
| guage-independent data interchange format. It was derived from the ECMAScript P | ||||
| rogramming Language Standard. JSON defines a small set of formatting rules for | ||||
| the portable representation of structured data.</t><t>This document removes inco | ||||
| nsistencies with other specifications of JSON, repairs specification errors, and | ||||
| offers experience-based interoperability guidance.</t></abstract> | ||||
| </front> | ||||
| <seriesInfo name='STD' value='90'/> | ||||
| <seriesInfo name='RFC' value='8259'/> | ||||
| <seriesInfo name='DOI' value='10.17487/RFC8259'/> | ||||
| </reference> | ||||
| <reference anchor="RFC7493" target='https://www.rfc-editor.org/info/rfc7493'> | ||||
| <front> | <front> | |||
| <title>The I-JSON Message Format</title> | <title>UTF-8, a transformation format of ISO 10646</title> | |||
| <author initials='T.' surname='Bray' fullname='T. Bray' role='editor'><organizat | <author initials='F.' surname='Yergeau' fullname='F. Yergeau'><organization /></ | |||
| ion /></author> | author> | |||
| <date year='2015' month='March' /> | <date year='2003' month='November' /> | |||
| <abstract><t>I-JSON (short for "Internet JSON") is a restricted profil | ||||
| e of JSON designed to maximize interoperability and increase confidence that sof | ||||
| tware can process it successfully with predictable results.</t></abstract> | ||||
| </front> | </front> | |||
| <seriesInfo name='RFC' value='7493'/> | <seriesInfo name='STD' value='63'/> | |||
| <seriesInfo name='DOI' value='10.17487/RFC7493'/> | <seriesInfo name='RFC' value='3629'/> | |||
| </reference> | </reference> | |||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7231.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7540.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7541.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.8259.xml"/> | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer | ||||
| ence.RFC.7493.xml"/> | ||||
| </references> | ||||
| </references> | </references> | |||
| <section anchor="faq"> | ||||
| <section anchor="faq" title="Frequently Asked Questions"> | <name>Frequently Asked Questions</name> | |||
| <section anchor="why-not-json"> | ||||
| <section anchor="why-not-json" title="Why not JSON?"> | <name>Why Not JSON?</name> | |||
| <t>Earlier proposals for Structured Fields were based upon JSON <xref ta | ||||
| <t>Earlier proposals for Structured Fields were based upon JSON <xref target="RF | rget="RFC8259"/>. However, constraining its use to | |||
| C8259"/>. However, constraining its use to make it suitable for HTTP header fiel | make it suitable for HTTP header fields required senders and | |||
| ds required senders and recipients to implement specific additional handling.</t | recipients to implement specific additional handling.</t> | |||
| > | <t>For example, JSON has specification issues around large numbers and | |||
| objects with duplicate members. Although advice for avoiding these | ||||
| <t>For example, JSON has specification issues around large numbers and objects w | issues is available (e.g., <xref target="RFC7493"/>), | |||
| ith duplicate members. Although advice for avoiding these issues is available (e | it cannot be relied upon.</t> | |||
| .g., <xref target="RFC7493"/>), it cannot be relied upon.</t> | <t>Likewise, JSON strings are by default Unicode strings, which have a | |||
| number of potential interoperability issues (e.g., in | ||||
| <t>Likewise, JSON strings are by default Unicode strings, which have a number of | comparison). Although implementers can be advised to avoid non-ASCII | |||
| potential interoperability issues (e.g., in comparison). Although implementers | content where unnecessary, this is difficult to enforce.</t> | |||
| can be advised to avoid non-ASCII content where unnecessary, this is difficult t | <t>Another example is JSON's ability to nest content to arbitrary | |||
| o enforce.</t> | depths. Since the resulting memory commitment might be unsuitable | |||
| (e.g., in embedded and other limited server deployments), it's | ||||
| <t>Another example is JSON’s ability to nest content to arbitrary depths. Since | necessary to limit it in some fashion; however, existing JSON | |||
| the resulting memory commitment might be unsuitable (e.g., in embedded and other | implementations have no such limits, and even if a limit is specified, | |||
| limited server deployments), it’s necessary to limit it in some fashion; howeve | it's likely that some field definition will find a need to violate | |||
| r, existing JSON implementations have no such limits, and even if a limit is spe | it.</t> | |||
| cified, it’s likely that some field definition will find a need to violate it.</ | <t>Because of JSON's broad adoption and implementation, it is | |||
| t> | difficult to impose such additional constraints across all | |||
| implementations; some deployments would fail to enforce them, thereby | ||||
| <t>Because of JSON’s broad adoption and implementation, it is difficult to impos | harming interoperability. In short, if it looks like JSON, people will | |||
| e such additional constraints across all implementations; some deployments would | be tempted to use a JSON parser/serializer on field values.</t> | |||
| fail to enforce them, thereby harming interoperability. In short, if it looks l | <t>Since a major goal for Structured Fields is to improve | |||
| ike JSON, people will be tempted to use a JSON parser / serializer on field valu | interoperability and simplify implementation, these concerns led to a | |||
| es.</t> | format that requires a dedicated parser and serializer.</t> | |||
| <t>Additionally, there were widely shared feelings that JSON doesn't | ||||
| <t>Since a major goal for Structured Fields is to improve interoperability and s | "look right" in HTTP fields.</t> | |||
| implify implementation, these concerns led to a format that requires a dedicated | </section> | |||
| parser and serializer.</t> | </section> | |||
| <section anchor="implementation-notes"> | ||||
| <t>Additionally, there were widely shared feelings that JSON doesn’t “look right | <name>Implementation Notes</name> | |||
| ” in HTTP fields.</t> | <t>A generic implementation of this specification should expose the | |||
| top-level serialize (<xref target="text-serialize"/>) | ||||
| </section> | and parse (<xref target="text-parse"/>) functions. They | |||
| </section> | need not be functions; for example, it could be implemented as an | |||
| <section anchor="implementation-notes" title="Implementation Notes"> | object, with methods for each of the different top-level types.</t> | |||
| <t>For interoperability, it's important that generic implementations be | ||||
| <t>A generic implementation of this specification should expose the top-level se | complete and follow the algorithms closely; see <xref target="strict"/>. T | |||
| rialize (<xref target="text-serialize"/>) and parse (<xref target="text-parse"/> | o aid this, a common test suite is being maintained | |||
| ) functions. They need not be functions; for example, it could be implemented as | by the community at <eref brackets="angle" target="https://github.com/http | |||
| an object, with methods for each of the different top-level types.</t> | wg/structured-field-tests"/>.</t> | |||
| <t>Implementers should note that Dictionaries and Parameters are | ||||
| <t>For interoperability, it’s important that generic implementations be complete | order-preserving maps. Some fields may not convey meaning in the | |||
| and follow the algorithms closely; see <xref target="strict"/>. To aid this, a | ordering of these data types, but it should still be exposed so | |||
| common test suite is being maintained by the community at <eref target="https:// | that it will be available to applications that need to use it.</t> | |||
| github.com/httpwg/structured-field-tests">https://github.com/httpwg/structured-f | <t>Likewise, implementations should note that it's important to preserve | |||
| ield-tests</eref>.</t> | the distinction between Tokens and Strings. While most programming | |||
| languages have native types that map to the other types well, it may be | ||||
| <t>Implementers should note that Dictionaries and Parameters are order-preservin | necessary to create a wrapper "token" object or use a parameter on | |||
| g maps. Some fields may not convey meaning in the ordering of these data types, | functions to assure that these types remain separate.</t> | |||
| but it should still be exposed so that applications which need to use it will ha | <t>The serialization algorithm is defined in a way that it is not | |||
| ve it available.</t> | strictly limited to the data types defined in <xref target="types"/> in ev | |||
| ery case. For example, Decimals are designed to | ||||
| <t>Likewise, implementations should note that it’s important to preserve the dis | take broader input and round to allowed values.</t> | |||
| tinction between Tokens and Strings. While most programming languages have nativ | <t>Implementations are allowed to limit the size of different | |||
| e types that map to the other types well, it may be necessary to create a wrappe | structures, subject to the minimums defined for each type. When a | |||
| r “token” object or use a parameter on functions to assure that these types rema | structure exceeds an implementation limit, that structure fails parsing | |||
| in separate.</t> | or serialization.</t> | |||
| </section> | ||||
| <t>The serialization algorithm is defined in a way that it is not strictly limit | <section numbered="false" anchor="acknowledgements"> | |||
| ed to the data types defined in <xref target="types"/> in every case. For exampl | <name>Acknowledgements</name> | |||
| e, Decimals are designed to take broader input and round to allowed values.</t> | <t>Many thanks to <contact fullname="Matthew Kerwin"/> for his detailed fe | |||
| edback and careful | ||||
| <t>Implementations are allowed to limit the allowed size of different structures | consideration during the development of this specification.</t> | |||
| , subject to the minimums defined for each type. When a structure exceeds an imp | <t>Thanks also to <contact fullname="Ian Clelland"/>, <contact fullname="R | |||
| lementation limit, that structure fails parsing or serialisation.</t> | oy Fielding"/>, <contact fullname="Anne van Kesteren"/>, | |||
| <contact fullname="Kazuho Oku"/>, <contact fullname="Evert Pot"/>, | ||||
| </section> | <contact fullname="Julian Reschke"/>, <contact fullname="Martin Thom | |||
| <section anchor="changes" title="Changes"> | son"/>, <contact fullname="Mike West"/>, and <contact fullname="Jeffrey Yasskin" | |||
| /> for their contributions.</t> | ||||
| <t><spanx style="emph">RFC Editor: Please remove this section before publication | </section> | |||
| .</spanx></t> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-18" title="Since draf | ||||
| t-ietf-httpbis-header-structure-18"> | ||||
| <t><list style="symbols"> | ||||
| <t>Use “sf-“ prefix for ABNF, not “sh-“.</t> | ||||
| <t>Fix indentation in Dictionary serialisation (#1164).</t> | ||||
| <t>Add example for Token; tweak example field names (#1147).</t> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Note that exceeding implementation limits implies failure.</t> | ||||
| <t>Talk about specifying order of Dictionary members and Parameters, not cardi | ||||
| nality.</t> | ||||
| <t>Allow (but don’t require) parsers to fail when a single field line isn’t va | ||||
| lid.</t> | ||||
| <t>Note that some aspects of Integers and Decimals are not necessarily preserv | ||||
| ed.</t> | ||||
| <t>Allow Lists and Dictionaries to be delimited by OWS, rather than *SP, to ma | ||||
| ke parsing more robust.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-17" title="Since draf | ||||
| t-ietf-httpbis-header-structure-17"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-16" title="Since draf | ||||
| t-ietf-httpbis-header-structure-16"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Discussion on forwards compatibility.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-15" title="Since draf | ||||
| t-ietf-httpbis-header-structure-15"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Use HTTP field terminology more consistently, in line with recent changes t | ||||
| o HTTP-core.</t> | ||||
| <t>String length requirements apply to decoded strings (#1051).</t> | ||||
| <t>Correctly round decimals in serialisation (#1043).</t> | ||||
| <t>Clarify input to serialisation algorithms (#1055).</t> | ||||
| <t>Omitted True dictionary value can have parameters (#1083).</t> | ||||
| <t>Keys can now start with ‘*’ (#1068).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-14" title="Since draf | ||||
| t-ietf-httpbis-header-structure-14"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Allow empty dictionary values (#992).</t> | ||||
| <t>Change value of omitted parameter value to True (#995).</t> | ||||
| <t>Explain more about splitting dictionaries and lists across header instances | ||||
| (#997).</t> | ||||
| <t>Disallow HTAB, replace OWS with spaces (#998).</t> | ||||
| <t>Change byte sequence delimiters from “*” to “:” (#991).</t> | ||||
| <t>Allow tokens to start with “*” (#991).</t> | ||||
| <t>Change Floats to fixed-precision Decimals (#982).</t> | ||||
| <t>Round the fractional component of decimal, rather than truncating it (#982) | ||||
| .</t> | ||||
| <t>Handle duplicate dictionary and parameter keys by overwriting their values, | ||||
| rather than failing (#997).</t> | ||||
| <t>Allow “.” in key (#1027).</t> | ||||
| <t>Check first character of key in serialisation (#1037).</t> | ||||
| <t>Talk about greasing headers (#1015).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-13" title="Since draf | ||||
| t-ietf-httpbis-header-structure-13"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Define “structured header name” and “structured header value” terms (#908). | ||||
| </t> | ||||
| <t>Corrected text about valid characters in strings (#931).</t> | ||||
| <t>Removed most instances of the word “textual”, as it was redundant (#915).</ | ||||
| t> | ||||
| <t>Allowed parameters on Items and Inner Lists (#907).</t> | ||||
| <t>Expand the range of characters in token (#961).</t> | ||||
| <t>Disallow OWS before “;” delimiter in parameters (#961).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-12" title="Since draf | ||||
| t-ietf-httpbis-header-structure-12"> | ||||
| <t><list style="symbols"> | ||||
| <t>Editorial improvements.</t> | ||||
| <t>Reworked float serialisation (#896).</t> | ||||
| <t>Don’t add a trailing space in inner-list (#904).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-11" title="Since draf | ||||
| t-ietf-httpbis-header-structure-11"> | ||||
| <t><list style="symbols"> | ||||
| <t>Allow * in key (#844).</t> | ||||
| <t>Constrain floats to six digits of precision (#848).</t> | ||||
| <t>Allow dictionary members to have parameters (#842).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-10" title="Since draf | ||||
| t-ietf-httpbis-header-structure-10"> | ||||
| <t><list style="symbols"> | ||||
| <t>Update abstract (#799).</t> | ||||
| <t>Input and output are now arrays of bytes (#662).</t> | ||||
| <t>Implementations need to preserve difference between token and string (#790) | ||||
| .</t> | ||||
| <t>Allow empty dictionaries and lists (#781).</t> | ||||
| <t>Change parameterized lists to have primary items (#797).</t> | ||||
| <t>Allow inner lists in both dictionaries and lists; removes lists of lists (# | ||||
| 816).</t> | ||||
| <t>Subsume Parameterised Lists into Lists (#839).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-09" title="Since draf | ||||
| t-ietf-httpbis-header-structure-09"> | ||||
| <t><list style="symbols"> | ||||
| <t>Changed Boolean from T/F to 1/0 (#784).</t> | ||||
| <t>Parameters are now ordered maps (#765).</t> | ||||
| <t>Clamp integers to 15 digits (#737).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-08" title="Since draf | ||||
| t-ietf-httpbis-header-structure-08"> | ||||
| <t><list style="symbols"> | ||||
| <t>Disallow whitespace before items properly (#703).</t> | ||||
| <t>Created “key” for use in dictionaries and parameters, rather than relying o | ||||
| n identifier (#702). Identifiers have a separate minimum supported size.</t> | ||||
| <t>Expanded the range of special characters allowed in identifier to include a | ||||
| ll of ALPHA, “.”, “:”, and “%” (#702).</t> | ||||
| <t>Use “?” instead of “!” to indicate a Boolean (#719).</t> | ||||
| <t>Added “Intentionally Strict Processing” (#684).</t> | ||||
| <t>Gave better names for referring specs to use in Parameterised Lists (#720). | ||||
| </t> | ||||
| <t>Added Lists of Lists (#721).</t> | ||||
| <t>Rename Identifier to Token (#725).</t> | ||||
| <t>Add implementation guidance (#727).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-07" title="Since draf | ||||
| t-ietf-httpbis-header-structure-07"> | ||||
| <t><list style="symbols"> | ||||
| <t>Make Dictionaries ordered mappings (#659).</t> | ||||
| <t>Changed “binary content” to “byte sequence” to align with Infra specificati | ||||
| on (#671).</t> | ||||
| <t>Changed “mapping” to “map” for #671.</t> | ||||
| <t>Don’t fail if byte sequences aren’t “=” padded (#658).</t> | ||||
| <t>Add Booleans (#683).</t> | ||||
| <t>Allow identifiers in items again (#629).</t> | ||||
| <t>Disallowed whitespace before items (#703).</t> | ||||
| <t>Explain the consequences of splitting a string across multiple headers (#68 | ||||
| 6).</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-06" title="Since draf | ||||
| t-ietf-httpbis-header-structure-06"> | ||||
| <t><list style="symbols"> | ||||
| <t>Add a FAQ.</t> | ||||
| <t>Allow non-zero pad bits.</t> | ||||
| <t>Explicitly check for integers that violate constraints.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-05" title="Since draf | ||||
| t-ietf-httpbis-header-structure-05"> | ||||
| <t><list style="symbols"> | ||||
| <t>Reorganise specification to separate parsing out.</t> | ||||
| <t>Allow referencing specs to use ABNF.</t> | ||||
| <t>Define serialisation algorithms.</t> | ||||
| <t>Refine relationship between ABNF, parsing and serialisation algorithms.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-04" title="Since draf | ||||
| t-ietf-httpbis-header-structure-04"> | ||||
| <t><list style="symbols"> | ||||
| <t>Remove identifiers from item.</t> | ||||
| <t>Remove most limits on sizes.</t> | ||||
| <t>Refine number parsing.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-03" title="Since draf | ||||
| t-ietf-httpbis-header-structure-03"> | ||||
| <t><list style="symbols"> | ||||
| <t>Strengthen language around failure handling.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-02" title="Since draf | ||||
| t-ietf-httpbis-header-structure-02"> | ||||
| <t><list style="symbols"> | ||||
| <t>Split Numbers into Integers and Floats.</t> | ||||
| <t>Define number parsing.</t> | ||||
| <t>Tighten up binary parsing and give it an explicit end delimiter.</t> | ||||
| <t>Clarify that mappings are unordered.</t> | ||||
| <t>Allow zero-length strings.</t> | ||||
| <t>Improve string parsing algorithm.</t> | ||||
| <t>Improve limits in algorithms.</t> | ||||
| <t>Require parsers to combine header fields before processing.</t> | ||||
| <t>Throw an error on trailing garbage.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-01" title="Since draf | ||||
| t-ietf-httpbis-header-structure-01"> | ||||
| <t><list style="symbols"> | ||||
| <t>Replaced with draft-nottingham-structured-headers.</t> | ||||
| </list></t> | ||||
| </section> | ||||
| <section anchor="since-draft-ietf-httpbis-header-structure-00" title="Since draf | ||||
| t-ietf-httpbis-header-structure-00"> | ||||
| <t><list style="symbols"> | ||||
| <t>Added signed 64bit integer type.</t> | ||||
| <t>Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1-unicode-string | ||||
| .</t> | ||||
| <t>Change h1_blob delimiter to “:” since “’” is valid t_char</t> | ||||
| </list></t> | ||||
| </section> | ||||
| </section> | ||||
| <section numbered="false" anchor="acknowledgements" title="Acknowledgements"> | ||||
| <t>Many thanks to Matthew Kerwin for his detailed feedback and careful considera | ||||
| tion during the development of this specification.</t> | ||||
| <t>Thanks also to Ian Clelland, Roy Fielding, Anne van Kesteren, Kazuho Oku, Eve | ||||
| rt Pot, Julian Reschke, Martin Thomson, Mike West, and Jeffrey Yasskin for their | ||||
| contributions.</t> | ||||
| </section> | ||||
| </back> | </back> | |||
| <!-- ##markdown-source: | ||||
| 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 | ||||
| jMG3RQf4b9bNHi+buhEk+gITyO3W7/QZYv/u9zGLnPRuh9l6LmjrGEg4JBq7 | ||||
| lK5+j8Cb5EQzMt2s6K/kytOum5b8BWypfCnZ7vem/y81+lamVQtSzcWzbtb3 | ||||
| t5EhNRGyWoLstqFEBEkzydnweSTxOUMXNAEvSMaie5GVEGmjHboMU/TYb9wj | ||||
| Xn+8Daop5zQE3dc+uDB98wk7yn0AvIKLGtta6u9rngqbO+vCVx5/ewP78CtW | ||||
| cPT7G9huQUnTxrY+M8UZoiXeB4/XeTvC19w6QneWottrGnY1w6oUbdA4KiZY | ||||
| UaoXdsPQ2OagJudNurujyNYW7rebXF8ptG02+j1ErE0MN9KoWVTWsJK/t02y | ||||
| 22aNtKOsaWF7ye71Ja2/Vabo7nfxcUJK5aPeI1KLdn+HhzP7MEnJ5qzz+vnk | ||||
| dfV+rgMfpyzdFy4nl51Bac1m90/u7qvGj+/tDjaTvoUu2tK+/RO8+wLzwxrA | ||||
| 2OR3AaM1/d3PDL3v/mT1pKh7AmVKABiktiIA57jQOf8jm5nMdDnlXGZFPM6n | ||||
| Gd+5VDOaPVb16p1dqfCtrWXDw19rEPtC76sN4vWcmO4JbGf8MREtlecLtX3V | ||||
| aAipGNppa4RqHR+213O3WbS7X+4OA5OkihcuTvymdv2+g/b3q63cgy80/2vW | ||||
| P1Ym2lflYPd21NXsawvjd1C8bCCKZ4ymrYN1x2qulYBbkrV161J7t8J0dob9 | ||||
| cuPZqnAHgFssOCMLvo8B96BGfipvvDr3e9sE8NbvYg2srhivh8UaDYTa0lO/ | ||||
| i1SSk9B7ltDX8kVqPjyuhJKlGww0JjZNzCHX3W767or0a1e/tzU+akR2Wk0r | ||||
| pR+xrL5AYTUH/VKSeo0Z6XzeaU9aJbWPTu9N13DvggROPtED+tolCfibNPqV | ||||
| Y/8CNmORm57I2ltKNSNpf9i2rkzQNaSJtRj4y9A0NuBlSjrgivYGa8hzpLGx | ||||
| iPGEO6KVOi8grj/0q2tu8WQVDllD3XpZS81wAqpwQyOBao2I2bdiiB2voMGA | ||||
| FmqkleOsdmeUi7h1GJ6+mzQ22WJCtamQGLhq1WBbdtnoGK/cys0CakQughUd | ||||
| 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 | ||||
| /f8BlP8Q65DmAAA= | ||||
| </rfc> | </rfc> | |||
| End of changes. 51 change blocks. | ||||
| 2313 lines changed or deleted | 1512 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||