| rfc8941v1.xml | rfc8941.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version='1.0' encoding='utf-8'?> | |||
| <!-- Note: updated by Chris 07/14/20 and formatted by AP--> | ||||
| <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | <!DOCTYPE rfc SYSTEM "rfc2629-xhtml.ent"> | |||
| <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft | ||||
| <rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" | -ietf-httpbis-header-structure-19" number="8941" submissionType="IETF" category= | |||
| docName="draft-ietf-httpbis-header-structure-19" number="8941" | "std" consensus="true" obsoletes="" updates="" xml:lang="en" tocInclude="true" s | |||
| submissionType="IETF" category="std" consensus="true" obsoletes="" | ortRefs="true" symRefs="true" tocDepth="3" version="3"> | |||
| updates="" xml:lang="en" tocInclude="true" sortRefs="true" symRefs="true" | ||||
| tocDepth="3" version="3"> | ||||
| <!-- xml2rfc v2v3 conversion 2.46.0 --> | <!-- 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"/> | <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="October" year="2020" /> | <date month="November" year="2020"/> | |||
| <area>Applications and Real-Time</area> | <area>Applications and Real-Time</area> | |||
| <workgroup>HTTP</workgroup> | <workgroup>HTTP</workgroup> | |||
| <!-- [rfced] Please insert any keywords (beyond those that appear in | ||||
| the title) for use on https://www.rfc-editor.org/search. --> | ||||
| <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 are intended to make it easier and safer to define and handle HTTP | that are intended to make it easier and safer to define and handle HTTP | |||
| header and trailer fields, known as "Structured Fields", "Structured | header and trailer fields, known as "Structured Fields", "Structured | |||
| Headers", or "Structured Trailers". It is intended for use by | Headers", or "Structured Trailers". It is intended for use by | |||
| specifications of new HTTP fields that wish to use a common syntax that | specifications of new HTTP fields that wish to use a common syntax that | |||
| is more restrictive than traditional HTTP field values.</t> | is more restrictive than traditional HTTP field values.</t> | |||
| </abstract> | </abstract> | |||
| </front> | </front> | |||
| <middle> | <middle> | |||
| <section anchor="introduction" numbered="true" toc="default"> | <section anchor="introduction"> | |||
| <name>Introduction</name> | <name>Introduction</name> | |||
| <t>Specifying the syntax of new HTTP header (and trailer) fields is an | <t>Specifying the syntax of new HTTP header (and trailer) fields is an | |||
| onerous task; even with the guidance in <xref target="RFC7231" sectionForm at="of" section="8.3.1"/>, there are many decisions -- and | 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> | pitfalls -- for a prospective HTTP field author.</t> | |||
| <t>Once a field is defined, bespoke parsers and serializers often need | <t>Once a field is defined, bespoke parsers and serializers often need | |||
| to be written, because each field value has a slightly different handling | to be written, because each field value has a slightly different handling | |||
| of what looks like common syntax.</t> | of what looks like common syntax.</t> | |||
| <t>This document introduces a set of common data structures for use in | <t>This document introduces a set of common data structures for use in | |||
| definitions of new HTTP field values to address these problems. In | definitions of new HTTP field values to address these problems. In | |||
| particular, it defines a generic, abstract model for them, along with a | particular, it defines a generic, abstract model for them, along with a | |||
| concrete serialization for expressing that model in HTTP <xref | concrete serialization for expressing that model in HTTP <xref target="RFC | |||
| target="RFC7230" format="default"/> header and trailer fields.</t> | 7230"/> header and trailer fields.</t> | |||
| <t>An HTTP field that is defined as a "Structured Header" or "Structured | <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 | 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 | the types defined in this specification to define its syntax and basic | |||
| handling rules, thereby simplifying both its definition by specification | handling rules, thereby simplifying both its definition by specification | |||
| writers and handling by implementations.</t> | writers and handling by implementations.</t> | |||
| <t>Additionally, future versions of HTTP can define alternative | <t>Additionally, future versions of HTTP can define alternative | |||
| serializations of the abstract model of these structures, allowing | serializations of the abstract model of these structures, allowing | |||
| fields that use that model to be transmitted more efficiently without | fields that use that model to be transmitted more efficiently without | |||
| being redefined.</t> | being redefined.</t> | |||
| <t>Note that it is not a goal of this document to redefine the syntax of | <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 | existing HTTP fields; the mechanisms described herein are only intended | |||
| to be used with fields that explicitly opt into them.</t> | to be used with fields that explicitly opt into them.</t> | |||
| <t><xref target="specify" format="default"/> describes how to specify a | <t><xref target="specify"/> describes how to specify a | |||
| Structured Field.</t> | Structured Field.</t> | |||
| <t><xref target="types" format="default"/> defines a number of abstract | <t><xref target="types"/> defines a number of abstract | |||
| data types that can be used in Structured Fields.</t> | data types that can be used in Structured Fields.</t> | |||
| <t>Those abstract types can be serialized into and parsed from HTTP | <t>Those abstract types can be serialized into and parsed from HTTP | |||
| field values using the algorithms described in <xref target="text" | field values using the algorithms described in <xref target="text"/>.</t> | |||
| format="default"/>.</t> | <section anchor="strict"> | |||
| <section anchor="strict" numbered="true" toc="default"> | ||||
| <name>Intentionally Strict Processing</name> | <name>Intentionally Strict Processing</name> | |||
| <t>This specification intentionally defines strict parsing and | <t>This specification intentionally defines strict parsing and | |||
| serialization behaviors using step-by-step algorithms; the only error | serialization behaviors using step-by-step algorithms; the only error | |||
| handling defined is to fail the operation altogether.</t> | handling defined is to fail the operation altogether.</t> | |||
| <t>It is designed to encourage faithful implementation and therefore | <t>It is designed to encourage faithful implementation and therefore | |||
| good interoperability. Therefore, an implementation that tried to be | good interoperability. Therefore, an implementation that tried to be | |||
| helpful by being more tolerant of input would make interoperability | helpful by being more tolerant of input would make interoperability | |||
| worse, since that would create pressure on other implementations to | worse, since that would create pressure on other implementations to | |||
| implement similar (but likely subtly different) workarounds.</t> | implement similar (but likely subtly different) workarounds.</t> | |||
| <t>In other words, strict processing is an intentional feature of this | <t>In other words, strict processing is an intentional feature of this | |||
| specification; it allows non-conformant input to be discovered and | specification; it allows non-conformant input to be discovered and | |||
| skipping to change at line 100 ¶ | skipping to change at line 89 ¶ | |||
| implement similar (but likely subtly different) workarounds.</t> | implement similar (but likely subtly different) workarounds.</t> | |||
| <t>In other words, strict processing is an intentional feature of this | <t>In other words, strict processing is an intentional feature of this | |||
| specification; it allows non-conformant input to be discovered and | specification; it allows non-conformant input to be discovered and | |||
| corrected by the producer early and avoids both interoperability and | corrected by the producer early and avoids both interoperability and | |||
| security issues that might otherwise result.</t> | security issues that might otherwise result.</t> | |||
| <t>Note that as a result of this strictness, if a field is appended to | <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 | by multiple parties (e.g., intermediaries or different components in | |||
| the sender), an error in one party's value is likely to cause the | the sender), an error in one party's value is likely to cause the | |||
| entire field value to fail parsing.</t> | entire field value to fail parsing.</t> | |||
| </section> | </section> | |||
| <section anchor="notational-conventions" numbered="true" toc="default"> | <section anchor="notational-conventions"> | |||
| <name>Notational Conventions</name> | <name>Notational Conventions</name> | |||
| <t> | <t> | |||
| The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | |||
| "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
| NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | |||
| "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | |||
| "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are | |||
| to be interpreted as | to be interpreted as | |||
| described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> | |||
| when, and only when, they appear in all capitals, as shown here. | when, and only when, they appear in all capitals, as shown here. | |||
| </t> | </t> | |||
| <t>This document uses algorithms to specify parsing and serialization | <t>This document uses algorithms to specify parsing and serialization | |||
| behaviors and the Augmented Backus-Naur Form (ABNF) notation of <xref | behaviors and the Augmented Backus-Naur Form (ABNF) notation of <xref tar | |||
| target="RFC5234" format="default"/> to illustrate expected syntax in | get="RFC5234"/> to illustrate expected syntax in | |||
| HTTP header fields. In doing so, it uses the VCHAR, SP, DIGIT, ALPHA, | HTTP header fields. In doing so, it uses the VCHAR, SP, DIGIT, ALPHA, | |||
| and DQUOTE rules from <xref target="RFC5234" format="default"/>. It | and DQUOTE rules from <xref target="RFC5234"/>. It | |||
| also includes the tchar and OWS rules from <xref target="RFC7230" | also includes the tchar and OWS rules from <xref target="RFC7230"/>.</t> | |||
| format="default"/>.</t> | ||||
| <t>When parsing from HTTP fields, implementations <bcp14>MUST</bcp14> ha ve behavior | <t>When parsing from HTTP fields, implementations <bcp14>MUST</bcp14> ha ve behavior | |||
| that is indistinguishable from following the algorithms. If there is | that is indistinguishable from following the algorithms. If there is | |||
| disagreement between the parsing algorithms and ABNF, the specified | disagreement between the parsing algorithms and ABNF, the specified | |||
| algorithms take precedence.</t> | algorithms take precedence.</t> | |||
| <t>For serialization to HTTP fields, the ABNF illustrates their | <t>For serialization to HTTP fields, the ABNF illustrates their | |||
| expected wire representations, and the algorithms define the | expected wire representations, and the algorithms define the | |||
| recommended way to produce them. Implementations <bcp14>MAY</bcp14> vary from 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 | specified behavior so long as the output is still correctly handled by | |||
| the parsing algorithm.</t> | the parsing algorithm described in <xref target="text-parse"/>.</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="specify" numbered="true" toc="default"> | <section anchor="specify"> | |||
| <name>Defining New Structured Fields</name> | <name>Defining New Structured Fields</name> | |||
| <t>To specify an HTTP field as a Structured Field, its authors need to:</t > | <t>To specify an HTTP field as a Structured Field, its authors need to:</t > | |||
| <ul spacing="normal"> | <ul> | |||
| <li>Normatively reference this specification. Recipients and | <li>Normatively reference this specification. Recipients and | |||
| generators of the field need to know that the requirements of this | generators of the field need to know that the requirements of this | |||
| document are in effect.</li> | document are in effect.</li> | |||
| <li>Identify whether the field is a Structured Header (i.e., it can | <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 | only be used in the header section -- the common case), a Structured | |||
| Trailer (only in the trailer section), or a Structured Field | Trailer (only in the trailer section), or a Structured Field | |||
| (both).</li> | (both).</li> | |||
| <li>Specify the type of the field value; either List (<xref | <li>Specify the type of the field value; either List (<xref target="list | |||
| target="list" format="default"/>), Dictionary (<xref | "/>), Dictionary (<xref target="dictionary"/>), or Item (<xref target="item"/>). | |||
| target="dictionary" format="default"/>), or Item (<xref target="item" | </li> | |||
| format="default"/>).</li> | ||||
| <li>Define the semantics of the field value.</li> | <li>Define the semantics of the field value.</li> | |||
| <li>Specify any additional constraints upon the field value, as well | <li>Specify any additional constraints upon the field value, as well | |||
| as the consequences when those constraints are violated.</li> | as the consequences when those constraints are violated.</li> | |||
| </ul> | </ul> | |||
| <t>Typically, this means that a field definition will specify the | <t>Typically, this means that a field definition will specify the | |||
| top-level type -- List, Dictionary, or Item -- and then define its | top-level type -- List, Dictionary, or Item -- and then define its | |||
| allowable types and constraints upon them. For example, a header | 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 | 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 | header defined as an Item might allow only Strings, and additionally | |||
| only strings beginning with the letter "Q", or strings in | only strings beginning with the letter "Q", or strings in | |||
| lowercase. Likewise, Inner Lists (<xref target="inner-list" | lowercase. Likewise, Inner Lists (<xref target="inner-list"/>) are only va | |||
| format="default"/>) are only valid when a field definition explicitly | lid when a field definition explicitly | |||
| allows them.</t> | allows them.</t> | |||
| <t>When parsing fails, the entire field is ignored (see <xref | <t>When parsing fails, the entire field is ignored (see <xref target="text | |||
| target="text-parse" format="default"/>); in most situations, violating | -parse"/>); in most situations, violating | |||
| field-specific constraints should have the same effect. Thus, if a | 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 | 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 | is received, the field will by default be ignored. If the field requires | |||
| different error handling, this should be explicitly specified.</t> | different error handling, this should be explicitly specified.</t> | |||
| <t>Both Items and Inner Lists allow parameters as an extensibility | <t>Both Items and Inner Lists allow parameters as an extensibility | |||
| mechanism; this means that values can later be extended to accommodate | mechanism; this means that values can later be extended to accommodate | |||
| more information, if need be. To preserve forward compatibility, field | more information, if need be. To preserve forward compatibility, field | |||
| specifications are discouraged from defining the presence of an | specifications are discouraged from defining the presence of an | |||
| unrecognized Parameter as an error condition.</t> | unrecognized parameter as an error condition.</t> | |||
| <t>To further assure that this extensibility is available in the future, | <t>To further assure that this extensibility is available in the future, | |||
| and to encourage consumers to use a complete parser implementation, a | and to encourage consumers to use a complete parser implementation, a | |||
| field definition can specify that "grease" Parameters be added by | field definition can specify that "grease" parameters be added by | |||
| senders. A specification could stipulate that all Parameters that fit a | senders. A specification could stipulate that all parameters that fit a | |||
| defined pattern are reserved for this use and then encourage them to be | defined pattern are reserved for this use and then encourage them to be | |||
| sent on some portion of requests. This helps to discourage recipients | sent on some portion of requests. This helps to discourage recipients | |||
| from writing a parser that does not account for Parameters.</t> | from writing a parser that does not account for Parameters.</t> | |||
| <t>Specifications that use Dictionaries can also allow for forward | <t>Specifications that use Dictionaries can also allow for forward | |||
| compatibility by requiring that the presence of -- as well as value and | compatibility by requiring that the presence of -- as well as value and | |||
| type associated with -- unknown members be ignored. Later, specifications | type associated with -- unknown members be ignored. Subsequent specificati ons | |||
| can then add additional members, specifying constraints on them as | can then add additional members, specifying constraints on them as | |||
| appropriate.</t> | appropriate.</t> | |||
| <t>An extension to a structured field can then require that an entire | <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 | field value be ignored by a recipient that understands the extension if | |||
| constraints on the value it defines are not met.</t> | constraints on the value it defines are not met.</t> | |||
| <t>A field definition cannot relax the requirements of this | <t>A field definition cannot relax the requirements of this | |||
| specification because doing so would preclude handling by generic | specification because doing so would preclude handling by generic | |||
| software; they can only add additional constraints (for example, on the | software; they can only add additional constraints (for example, on the | |||
| numeric range of Integers and Decimals, the format of Strings and | numeric range of Integers and Decimals, the format of Strings and | |||
| Tokens, the types allowed in a Dictionary's values, or the number of | Tokens, the types allowed in a Dictionary's values, or the number of | |||
| Items in a List). Likewise, field definitions can only use this | Items in a List). Likewise, field definitions can only use this | |||
| specification for the entire field value, not a portion thereof.</t> | specification for the entire field value, not a portion thereof.</t> | |||
| <t>This specification defines minimums for the length or number of | <t>This specification defines minimums for the length or number of | |||
| various structures supported by implementations. It does not specify | various structures supported by implementations. It does not specify | |||
| maximum sizes in most cases, but authors should be aware that HTTP | maximum sizes in most cases, but authors should be aware that HTTP | |||
| implementations do impose various limits on the size of individual | implementations do impose various limits on the size of individual | |||
| fields, the total number of fields, and/or the size of the entire header | fields, the total number of fields, and/or the size of the entire header | |||
| or trailer section.</t> | or trailer section.</t> | |||
| <t>Specifications can refer to a field name as a "structured header | <t>Specifications can refer to a field name as a "structured header | |||
| name", "structured trailer name", or "structured field name" as | name", "structured trailer name", or "structured field name" as | |||
| appropriate. Likewise, they can refer its field value as a "structured | appropriate. Likewise, they can refer its field value as a "structured | |||
| header value", "structured trailer value", or "structured field value" as | header value", "structured trailer value", or "structured field value" as | |||
| necessary. | necessary. | |||
| <!-- [rfced] May we update this sentence to clarify "their"? | ||||
| Original: | ||||
| Field definitions are encouraged to use | ||||
| the ABNF rules beginning with "sf-" defined in this specification; | ||||
| other rules in this specification are not intended for their use. | ||||
| Perhaps (a little redundant, but perhaps more clear): | ||||
| Field definitions are encouraged to use | ||||
| the ABNF rules beginning with "sf-" defined in this specification; | ||||
| other ABNF rules in this specification are not intended to be used in field | ||||
| definitions. | ||||
| Field definitions are encouraged to use the ABNF rules | Field definitions are encouraged to use the ABNF rules | |||
| beginning with "sf-" defined in this specification; other rules in this | beginning with "sf-" defined in this specification; other rules in this | |||
| specification are not intended for their use.</t> | specification are not intended to be used in field definitions.</t> | |||
| <t>For example, a fictitious Foo-Example header field might be specified | <t>For example, a fictitious Foo-Example header field might be specified | |||
| as:</t> | as:</t> | |||
| <!-- [rfced] Throughout, we have marked the example as <sourcecode>. There is | <blockquote> | |||
| no "example" type; do you want to mark the <sourcecode> with no type as | <t>42. Foo-Example Header</t> | |||
| pseudocode? The current list of types is available here: | ||||
| https://www.rfc-editor.org/materials/sourcecode-types.txt | ||||
| <sourcecode><![CDATA[ | ||||
| 42. Foo-Example Header | ||||
| ]]></sourcecode> | ||||
| <t>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.</t> | much Foo the message has.</t> | |||
| <t>Foo-Example is an Item Structured Header [RFCxxxx]. Its value <bcp14>MUST</bc | <t>Foo-Example is an Item Structured Header [RFCxxxx]. Its value MUST be | |||
| p14> be | an Integer (Section 3.3.1 of [RFC8941]). Its ABNF is:</t> | |||
| an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is:</t> | ||||
| <sourcecode type="abnf"><![CDATA[ | <artwork> | |||
| Foo-Example = sf-integer | Foo-Example = sf-integer | |||
| ]]></sourcecode> | </artwork> | |||
| <t>Its value indicates the amount of Foo in the message, and it <bcp14>MUST</bcp | <t>Its value indicates the amount of Foo in the message, and it MUST | |||
| 14> | be between 0 and 10, inclusive; other values MUST cause | |||
| be between 0 and 10, inclusive; other values <bcp14>MUST</bcp14> cause | ||||
| the entire header field to be ignored.</t> | the entire header field to be ignored.</t> | |||
| <!--[rfced] Since only 1 parameter ("foourl") is being defined below, | <t>The following parameter is defined:</t> | |||
| may we update the text as follows ('parameter' instead of 'parameters'?) | ||||
| Original: | ||||
| The following parameters are defined: | ||||
| * 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. | ||||
| Perhaps: | <ul> | |||
| The following parameter is defined: | <li>A parameter whose name is "foourl", and whose value is a String | |||
| * A Parameter whose name is "foourl", and whose value is a String | (Section 3.3.3 of [RFC8941]), conveying the Foo URL | |||
| (Section Y.Y of [RFCxxxx]), conveying the Foo URL | for the message. See below for processing requirements.</li> | |||
| for the message. See below for processing requirements. | </ul> | |||
| <t>The following parameters are defined: | ||||
| * 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.</t> | ||||
| <t>"foourl" contains a URI-reference (<xref target="RFC3986" | <t>"foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | |||
| sectionFormat="of" section="4.1"/>). 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 | |||
| <bcp14>MUST</bcp14> be ignored. If its value is a relative reference (<xref | MUST be ignored. If its value is a relative reference (Section 4.2 | |||
| target="RFC3986" sectionFormat="of" section="4.2"/>), it <bcp14>MUST</bcp14> | of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | |||
| be resolved (<xref target="RFC3986" sectionFormat="of" section="5"/>) before | ||||
| being used.</t> | being used.</t> | |||
| <t>For example:</t> | <t>For example:</t> | |||
| <sourcecode type="" name=""><![CDATA[ | <artwork> | |||
| Foo-Example: 2; foourl="https://foo.example.com/" | Foo-Example: 2; foourl="https://foo.example.com/" | |||
| ]]></sourcecode> | </artwork> | |||
| </blockquote> | ||||
| </section> | </section> | |||
| <section anchor="types" numbered="true" toc="default"> | <section anchor="types"> | |||
| <name>Structured Data Types</name> | <name>Structured Data Types</name> | |||
| <t>This section defines the abstract types for Structured Fields. The | <t>This section defines the abstract types for Structured Fields. The | |||
| ABNF provided represents the on-wire format in HTTP field values.</t> | ABNF provided represents the on-wire format in HTTP field values.</t> | |||
| <t>In summary:</t> | <t>In summary:</t> | |||
| <ul spacing="normal"> | <ul> | |||
| <li>There are three top-level types that an HTTP field can be defined | <li>There are three top-level types that an HTTP field can be defined | |||
| as: Lists, Dictionaries, and Items.</li> | as: Lists, Dictionaries, and Items.</li> | |||
| <li>Lists and Dictionaries are containers; their members can be Items | <li>Lists and Dictionaries are containers; their members can be Items | |||
| or Inner Lists (which are themselves arrays of Items).</li> | or Inner Lists (which are themselves arrays of Items).</li> | |||
| <li>Both Items and Inner Lists can be parameterized with key/value pairs .</li> | <li>Both Items and Inner Lists can be Parameterized with key/value pairs .</li> | |||
| </ul> | </ul> | |||
| <section anchor="list" numbered="true" toc="default"> | <section anchor="list"> | |||
| <name>Lists</name> | <name>Lists</name> | |||
| <t>Lists are arrays of zero or more members, each of which can be an | <t>Lists are arrays of zero or more members, each of which can be an | |||
| Item (<xref target="item" format="default"/>) or an Inner List (<xref | Item (<xref target="item"/>) or an Inner List (<xref target="inner-list"/ | |||
| target="inner-list" format="default"/>), both of which can be | >), both of which can be | |||
| Parameterized (<xref target="param" format="default"/>).</t> | Parameterized (<xref target="param"/>).</t> | |||
| <t>The ABNF for Lists in HTTP fields is:</t> | <t>The ABNF for Lists in HTTP fields is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <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 | |||
| ]]></sourcecode> | </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 field whose value is defined as a List of Strings could | example, a field whose value is defined as a List of Strings could | |||
| look like:</t> | look like:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-StrList: "foo", "bar", "It was the best of times." | Example-List: "foo", "bar", "It was the best of times." | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>An empty List is denoted by not serializing the field at all. This | <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> | implies that fields defined as Lists have a default empty value.</t> | |||
| <t>Note that Lists can have their members split across multiple lines | <t>Note that Lists can have their members split across multiple lines | |||
| inside a header or trailer section, as per <xref target="RFC7230" | inside a header or trailer section, as per <xref target="RFC7230" section | |||
| sectionFormat="of" section="3.2.2"/>; for example, the following are | ="3.2.2"/>; for example, the following are | |||
| equivalent:</t> | equivalent:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Hdr: foo, bar | Example-List: foo, bar | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>and</t> | <t>and</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Hdr: foo | Example-List: foo | |||
| Example-Hdr: bar | Example-List: bar | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>However, individual members of a List cannot be safely split | <t>However, individual members of a List cannot be safely split | |||
| between lines; see <xref target="text-parse" format="default"/> | between lines; see <xref target="text-parse"/> | |||
| for details.</t> | for details.</t> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Lists containing at least 1024 me mbers. Field | <t>Parsers <bcp14>MUST</bcp14> support Lists containing at least 1024 me mbers. Field | |||
| specifications can constrain the types and cardinality of individual | specifications can constrain the types and cardinality of individual | |||
| List values as they require.</t> | List values as they require.</t> | |||
| <section anchor="inner-list" numbered="true" toc="default"> | <section anchor="inner-list"> | |||
| <name>Inner Lists</name> | <name>Inner Lists</name> | |||
| <t>An Inner List is an array of zero or more Items (<xref | <t>An Inner List is an array of zero or more Items (<xref target="item | |||
| target="item" format="default"/>). Both the individual Items and the | "/>). Both the individual Items and the | |||
| Inner List itself can be Parameterized (<xref target="param" | Inner List itself can be Parameterized (<xref target="param"/>).</t> | |||
| format="default"/>).</t> | ||||
| <t>The ABNF for Inner Lists is:</t> | <t>The ABNF for Inner Lists is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | |||
| parameters | parameters | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Inner Lists are denoted by surrounding parenthesis, and | <t>Inner Lists are denoted by surrounding parenthesis, and | |||
| their values are delimited by one or more spaces. A field whose value i s | their values are delimited by one or more spaces. A field whose value i s | |||
| defined as a List of Inner Lists of Strings could look like:</t> | defined as a List of Inner Lists of Strings could look like:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-StrListList: ("foo" "bar"), ("baz"), ("bat" "one"), () | Example-List: ("foo" "bar"), ("baz"), ("bat" "one"), () | |||
| ]]></sourcecode> | </sourcecode> | |||
| <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 | <t>A header field whose value is defined as a List of Inner Lists | |||
| with Parameters at both levels could look like:</t> | with Parameters at both levels could look like:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | Example-List: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Inner Lists containing at least 256 | <t>Parsers <bcp14>MUST</bcp14> support Inner Lists containing at least 256 | |||
| members. Field specifications can constrain the types and | members. Field specifications can constrain the types and | |||
| cardinality of individual Inner List members as they require.</t> | cardinality of individual Inner List members as they require.</t> | |||
| </section> | </section> | |||
| <section anchor="param" numbered="true" toc="default"> | <section anchor="param"> | |||
| <name>Parameters</name> | <name>Parameters</name> | |||
| <t>Parameters are an ordered map of key-value pairs that are | <t>Parameters are an ordered map of key-value pairs that are | |||
| associated with an Item (<xref target="item" format="default"/>) or | associated with an Item (<xref target="item"/>) or | |||
| Inner List (<xref target="inner-list" format="default"/>). | Inner List (<xref target="inner-list"/>). | |||
| <!--[rfced] Should the section reference for "parameterized" be | ||||
| Section 3.1.2 instead of Section 3.3? | ||||
| Original: | ||||
| The keys are unique within the scope the Parameters they occur within, | ||||
| and the values are bare items (i.e., they themselves cannot be | ||||
| parameterized; see Section 3.3). | ||||
| Perhaps: | ||||
| The keys are unique within the scope the Parameters they occur within, | ||||
| and the values are bare items (i.e., they themselves cannot be | ||||
| parameterized; see Section 3.1.2). | ||||
| The keys | The keys | |||
| are unique within the scope of the Parameters they occur within, and | are unique within the scope of the Parameters they occur within, and | |||
| the values are bare items (i.e., they themselves cannot be | the values are bare items (i.e., they themselves cannot be | |||
| parameterized; see <xref target="item" format="default"/>).</t> | parameterized; see <xref target="item"/>).</t> | |||
| <t>The ABNF for Parameters is:</t> | <t>The ABNF for Parameters is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| parameters = *( ";" *SP parameter ) | parameters = *( ";" *SP parameter ) | |||
| parameter = param-name [ "=" param-value ] | parameter = param-name [ "=" param-value ] | |||
| param-name = key | param-name = 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 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Note that Parameters are ordered as serialized, and Parameter | <t>Note that parameters are ordered as serialized, and parameter | |||
| keys cannot contain uppercase letters. A parameter is separated from | keys cannot contain uppercase letters. A parameter is separated from | |||
| its Item or Inner List and other parameters by a semicolon. For | its Item or Inner List and other parameters by a semicolon. For | |||
| example:</t> | example:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-ParamList: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | Example-List: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Parameters whose value is Boolean (see <xref target="boolean" | <t>Parameters whose value is Boolean (see <xref target="boolean"/>) tr | |||
| format="default"/>) true <bcp14>MUST</bcp14> omit that value when seria | ue <bcp14>MUST</bcp14> omit that value when serialized. For | |||
| lized. For | ||||
| example, the "a" parameter here is true, while the "b" parameter is | example, the "a" parameter here is true, while the "b" parameter is | |||
| false:</t> | false:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Int: 1; a; b=?0 | Example-Integer: 1; a; b=?0 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Note that this requirement is only on serialization; parsers are | <t>Note that this requirement is only on serialization; parsers are | |||
| still required to correctly handle the true value when it appears in | still required to correctly handle the true value when it appears in | |||
| a parameter.</t> | a parameter.</t> | |||
| <t>Parsers <bcp14>MUST</bcp14> support at least 256 parameters on an I tem or Inner | <t>Parsers <bcp14>MUST</bcp14> support at least 256 parameters on an I tem or Inner | |||
| List and support parameter keys with at least 64 characters. Field | List, and support parameter keys with at least 64 characters. Field | |||
| specifications can constrain the order of individual Parameters, as | specifications can constrain the order of individual parameters, as | |||
| well as their values' types as required.</t> | well as their values' types as required.</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="dictionary" numbered="true" toc="default"> | <section anchor="dictionary"> | |||
| <name>Dictionaries</name> | <name>Dictionaries</name> | |||
| <t>Dictionaries are ordered maps of name-value pairs, where the names | <t>Dictionaries are ordered maps of name-value pairs, where the names | |||
| are short textual strings and the values are Items (<xref | are short textual strings and the values are Items (<xref target="item"/> | |||
| target="item" format="default"/>) or arrays of Items, both of which | ) or arrays of Items, both of which | |||
| can be Parameterized (<xref target="param" format="default"/>). There | can be Parameterized (<xref target="param"/>). There | |||
| can be zero or more members, and their names are unique in the scope | can be zero or more members, and their names are unique in the scope | |||
| of the Dictionary they occur within.</t> | of the Dictionary they occur within.</t> | |||
| <t>Implementations <bcp14>MUST</bcp14> provide access to Dictionaries bo th by index | <t>Implementations <bcp14>MUST</bcp14> provide access to Dictionaries bo th by index | |||
| and by name. Specifications <bcp14>MAY</bcp14> use either means of access ing the | and by name. Specifications <bcp14>MAY</bcp14> use either means of access ing the | |||
| members.</t> | members.</t> | |||
| <t>The ABNF for Dictionaries is:</t> | <t>The ABNF for Dictionaries is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| 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-name ( parameters / ( "=" member-value )) | |||
| member-name = key | member-name = key | |||
| member-value = sf-item / inner-list | member-value = sf-item / inner-list | |||
| ]]></sourcecode> | </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 whitespace. Member names cannot contain uppercase | optional whitespace. Member names cannot contain uppercase | |||
| characters. Names and values are separated by "=" (without | characters. Names and values are separated by "=" (without | |||
| whitespace). For example:</t> | whitespace). For example:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | |||
| ]]></sourcecode> | </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 Sequence; see <xref target="binary" format="default"/>.</t> | a Byte Sequence; see <xref target="binary"/>.</t> | |||
| <t>Members whose value is Boolean (see <xref target="boolean" | <t>Members whose value is Boolean (see <xref target="boolean"/>) true <b | |||
| format="default"/>) true <bcp14>MUST</bcp14> omit that value when seriali | cp14>MUST</bcp14> omit that value when serialized. For | |||
| zed. For | ||||
| example, here both "b" and "c" are true:</t> | example, here both "b" and "c" are true:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Dict: a=?0, b, c; foo=bar | Example-Dict: a=?0, b, c; foo=bar | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Note that this requirement is only on serialization; parsers are | <t>Note that this requirement is only on serialization; parsers are | |||
| still required to correctly handle the true Boolean value when it | still required to correctly handle the true Boolean value when it | |||
| appears in Dictionary values.</t> | appears in Dictionary values.</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 name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-DictList: rating=1.5, feelings=(joy sadness) | Example-Dict: rating=1.5, feelings=(joy sadness) | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>A Dictionary with a mix of Items and Inner Lists, some with Parameter | <t>A Dictionary with a mix of Items and Inner Lists, some with parameter | |||
| s:</t> | s:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-MixDict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid | Example-Dict: a=(1 2), b=3, c=4;aa=bb, d=(5 6);valid | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>As with Lists, an empty Dictionary is represented by omitting the | <t>As with Lists, an empty Dictionary is represented by omitting the | |||
| entire field. This implies that fields defined as Dictionaries have a | entire field. This implies that fields defined as Dictionaries have a | |||
| default empty value.</t> | default empty value.</t> | |||
| <t>Typically, a field specification will define the semantics of | <t>Typically, a field specification will define the semantics of | |||
| Dictionaries by specifying the allowed type(s) for individual members | Dictionaries by specifying the allowed type(s) for individual members | |||
| by their names, as well as whether their presence is required or | by their names, as well as whether their presence is required or | |||
| optional. Recipients <bcp14>MUST</bcp14> ignore names that are undefined or unknown, | optional. Recipients <bcp14>MUST</bcp14> ignore names that are undefined or unknown, | |||
| unless the field's specification specifically disallows them.</t> | unless the field's specification specifically disallows them.</t> | |||
| <t>Note that Dictionaries can have their members split across multiple | <t>Note that Dictionaries can have their members split across multiple | |||
| lines inside a header or trailer section; for example, the following | lines inside a header or trailer section; for example, the following | |||
| are equivalent:</t> | are equivalent:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Hdr: foo=1, bar=2 | Example-Dict: foo=1, bar=2 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>and</t> | <t>and</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Hdr: foo=1 | Example-Dict: foo=1 | |||
| Example-Hdr: bar=2 | Example-Dict: bar=2 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>However, individual members of a Dictionary cannot be safely split | <t>However, individual members of a Dictionary cannot be safely split | |||
| between lines; see <xref target="text-parse" format="default"/> for | between lines; see <xref target="text-parse"/> for | |||
| details.</t> | details.</t> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Dictionaries containing at least 1024 | <t>Parsers <bcp14>MUST</bcp14> support Dictionaries containing at least 1024 | |||
| name/value pairs and names with at least 64 characters. Field | name/value pairs and names with at least 64 characters. Field | |||
| specifications can constrain the order of individual Dictionary | specifications can constrain the order of individual Dictionary | |||
| members, as well as their values' types as required.</t> | members, as well as their values' types as required.</t> | |||
| </section> | </section> | |||
| <section anchor="item" numbered="true" toc="default"> | <section anchor="item"> | |||
| <name>Items</name> | <name>Items</name> | |||
| <t>An Item can be an Integer (<xref target="integer" | <t>An Item can be an Integer (<xref target="integer"/>), a Decimal (<xre | |||
| format="default"/>), a Decimal (<xref target="decimal" | f target="decimal"/>), a String (<xref target="string"/>), a Token (<xref target | |||
| format="default"/>), a String (<xref target="string" | ="token"/>), | |||
| format="default"/>), a Token (<xref target="token" format="default"/>), | a Byte Sequence (<xref target="binary"/>), or a Boolean | |||
| a Byte Sequence (<xref target="binary" format="default"/>), or a Boolean | (<xref target="boolean"/>). It can have associated | |||
| (<xref target="boolean" format="default"/>). It can have associated | parameters (<xref target="param"/>).</t> | |||
| Parameters (<xref target="param" format="default"/>).</t> | ||||
| <t>The ABNF for Items is:</t> | <t>The ABNF for Items is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| 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 | |||
| ]]></sourcecode> | </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 might look like:</t> | an Integer might look like:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-IntItemHeader: 5 | Example-Integer: 5 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>or with Parameters:</t> | <t>or with parameters:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-IntItem: 5; foo=bar | Example-Integer: 5; foo=bar | |||
| ]]></sourcecode> | </sourcecode> | |||
| <section anchor="integer" numbered="true" toc="default"> | <section anchor="integer"> | |||
| <name>Integers</name> | <name>Integers</name> | |||
| <t>Integers have a range of -999,999,999,999,999 to | <t>Integers have a range of -999,999,999,999,999 to | |||
| 999,999,999,999,999 inclusive (i.e., up to fifteen digits, signed), | 999,999,999,999,999 inclusive (i.e., up to fifteen digits, signed), | |||
| for IEEE 754 compatibility <xref target="IEEE754" | for IEEE 754 compatibility <xref target="IEEE754"/>.</t> | |||
| format="default"/>.</t> | ||||
| <t>The ABNF for Integers is:</t> | <t>The ABNF for Integers is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| sf-integer = ["-"] 1*15DIGIT | sf-integer = ["-"] 1*15DIGIT | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>For example:</t> | <t>For example:</t> | |||
| <sourcecode name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Integer: 42 | Example-Integer: 42 | |||
| ]]></sourcecode> | </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 example, by using a String (<xref target="string" | ways; for example, by using a String (<xref target="string"/>), a Byte | |||
| format="default"/>), a Byte Sequence (<xref target="binary" | Sequence (<xref target="binary"/>), or a parameter on an Integer that acts as a | |||
| format="default"/>), 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 serialize Integers with leading zeros | |||
| (e.g., "0002", "-01") and signed zero ("-0"), these distinctions may | (e.g., "0002", "-01") and signed zero ("-0"), these distinctions may | |||
| not be preserved by implementations.</t> | not be preserved by implementations.</t> | |||
| <t>Note that commas in Integers are used in this section's prose | <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> | only for readability; they are not valid in the wire format.</t> | |||
| </section> | </section> | |||
| <section anchor="decimal" numbered="true" toc="default"> | <section anchor="decimal"> | |||
| <name>Decimals</name> | <name>Decimals</name> | |||
| <t>Decimals are numbers with an integer and a fractional | <t>Decimals are numbers with an integer and a fractional | |||
| component. The integer component has at most 12 digits; the | component. The integer component has at most 12 digits; the | |||
| fractional component has at most three digits.</t> | fractional component has at most three digits.</t> | |||
| <t>The ABNF for decimals is:</t> | <t>The ABNF for decimals is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | |||
| ]]></sourcecode> | </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 name=""><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Decimal: 4.5 | Example-Decimal: 4.5 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>While it is possible to serialize Decimals with leading zeros | <t>While it is possible to serialize Decimals with leading zeros | |||
| (e.g., "0002.5", "-01.334"), trailing zeros (e.g., "5.230", | (e.g., "0002.5", "-01.334"), trailing zeros (e.g., "5.230", | |||
| "-0.40"), and signed zero (e.g., "-0.0"), these distinctions may not | "-0.40"), and signed zero (e.g., "-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 serialization algorithm (<xref target="ser-decimal"/> | |||
| format="default"/>) rounds input with more than three digits of | ) rounds input with more than three digits of | |||
| precision in the fractional component. If an alternative rounding | precision in the fractional component. If an alternative rounding | |||
| strategy is desired, this should be specified by the header | strategy is desired, this should be specified by the header | |||
| definition to occur before serialization.</t> | definition to occur before serialization.</t> | |||
| </section> | </section> | |||
| <section anchor="string" numbered="true" toc="default"> | <section anchor="string"> | |||
| <name>Strings</name> | <name>Strings</name> | |||
| <t>Strings are zero or more printable ASCII <xref target="RFC0020" | <t>Strings are zero or more printable ASCII <xref target="RFC0020"/> c | |||
| format="default"/> characters (i.e., the range %x20 to %x7E). Note | haracters (i.e., the range %x20 to %x7E). Note | |||
| that this excludes tabs, newlines, carriage returns, etc.</t> | that this excludes tabs, newlines, carriage returns, etc.</t> | |||
| <t>The ABNF for Strings is:</t> | <t>The ABNF for Strings is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| 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 / "\" ) | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Strings are delimited with double quotes, using a backslash ("\") | <t>Strings are delimited with double quotes, using a backslash ("\") | |||
| to escape double quotes and backslashes. For example:</t> | to escape double quotes and backslashes. For example:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-String: "hello world" | Example-String: "hello world" | |||
| ]]></sourcecode> | </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 delimit Strings. Furthermore, only DQUOTE and "\" can be | do not delimit Strings. Furthermore, only DQUOTE and "\" can be | |||
| escaped; other characters after "\" <bcp14>MUST</bcp14> cause parsing t o fail.</t> | escaped; other characters after "\" <bcp14>MUST</bcp14> cause parsing 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 interoperability issues, and -- with few exceptions -- field | number of interoperability issues, and -- with few exceptions -- field | |||
| values do not require it.</t> | values do not require it.</t> | |||
| <t>When it is necessary for a field value to convey non-ASCII | <t>When it is necessary for a field value to convey non-ASCII | |||
| content, a Byte Sequence (<xref target="binary" format="default"/>) | content, a Byte Sequence (<xref target="binary"/>) | |||
| can be specified, along with a character encoding (preferably <xref | can be specified, along with a character encoding (preferably UTF-8 <xr | |||
| target="RFC3629" format="default"/>).</t> | ef target="STD63"/>).</t> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Strings (after any decoding) wi th at least | <t>Parsers <bcp14>MUST</bcp14> support Strings (after any decoding) wi th at least | |||
| 1024 characters.</t> | 1024 characters.</t> | |||
| </section> | </section> | |||
| <section anchor="token" numbered="true" toc="default"> | <section anchor="token"> | |||
| <name>Tokens</name> | <name>Tokens</name> | |||
| <t>Tokens are short textual words; their abstract model is identical | <t>Tokens are short textual words; their abstract model is identical | |||
| to their expression in the HTTP field value serialization.</t> | to their expression in the HTTP field value serialization.</t> | |||
| <t>The ABNF for Tokens is:</t> | <t>The ABNF for Tokens is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) | sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>For example:</t> | <t>For example:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Token: foo123/456 | Example-Token: foo123/456 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Tokens with at least 512 charac ters.</t> | <t>Parsers <bcp14>MUST</bcp14> support Tokens with at least 512 charac 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 in <xref target="RFC7230" format="default"/>, with the | rule defined in <xref target="RFC7230"/>, with the | |||
| exceptions that the first character is required to be either ALPHA | exceptions that the first character is required to be either ALPHA | |||
| or "*", and ":" and "/" are also allowed in subsequent | or "*", and ":" and "/" are also allowed in subsequent | |||
| characters.</t> | characters.</t> | |||
| </section> | </section> | |||
| <section anchor="binary" numbered="true" toc="default"> | <section anchor="binary"> | |||
| <name>Byte Sequences</name> | <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> | <t>The ABNF for a Byte Sequence is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| sf-binary = ":" *(base64) ":" | sf-binary = ":" *(base64) ":" | |||
| base64 = ALPHA / DIGIT / "+" / "/" / "=" | base64 = ALPHA / DIGIT / "+" / "/" / "=" | |||
| ]]></sourcecode> | </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 target="RFC4648" sectionFormat="comma" section="4"/>). For | (<xref target="RFC4648" sectionFormat="comma" section="4"/>). For | |||
| example:</t> | example:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Binary: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | Example-ByteSequence: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Parsers <bcp14>MUST</bcp14> support Byte Sequences with at least 16 384 octets | <t>Parsers <bcp14>MUST</bcp14> support Byte Sequences with at least 16 384 octets | |||
| after decoding.</t> | after decoding.</t> | |||
| </section> | </section> | |||
| <section anchor="boolean" numbered="true" toc="default"> | <section anchor="boolean"> | |||
| <name>Booleans</name> | <name>Booleans</name> | |||
| <t>Boolean values can be conveyed in Structured Fields.</t> | <t>Boolean values can be conveyed in Structured Fields.</t> | |||
| <t>The ABNF for a Boolean is:</t> | <t>The ABNF for a Boolean is:</t> | |||
| <sourcecode type="abnf"><![CDATA[ | <sourcecode type="abnf"> | |||
| sf-boolean = "?" boolean | sf-boolean = "?" boolean | |||
| boolean = "0" / "1" | boolean = "0" / "1" | |||
| ]]></sourcecode> | </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 true value or "0" for false. For example:</t> | "1" for a true value or "0" for false. For example:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-Bool: ?1 | Example-Boolean: ?1 | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>Note that in Dictionary (<xref target="dictionary" | <t>Note that in Dictionary (<xref target="dictionary"/>) and Parameter | |||
| format="default"/>) and Parameter (<xref target="param" | (<xref target="param"/>) values, Boolean true is indicated by omitting | |||
| format="default"/>) values, Boolean true is indicated by omitting | ||||
| the value.</t> | the value.</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="text" numbered="true" toc="default"> | <section anchor="text"> | |||
| <name>Working with Structured Fields in HTTP</name> | <name>Working with Structured Fields in HTTP</name> | |||
| <t>This section defines how to serialize and parse Structured Fields in | <t>This section defines how to serialize and parse Structured Fields in | |||
| textual HTTP field values and other encodings compatible with them | textual HTTP field values and other encodings compatible with them | |||
| (e.g., in HTTP/2 <xref target="RFC7540" format="default"/> before | (e.g., in HTTP/2 <xref target="RFC7540"/> before | |||
| compression with HPACK <xref target="RFC7541" format="default"/>).</t> | compression with HPACK <xref target="RFC7541"/>).</t> | |||
| <section anchor="text-serialize" numbered="true" toc="default"> | <section anchor="text-serialize"> | |||
| <name>Serializing Structured Fields</name> | <name>Serializing Structured Fields</name> | |||
| <t>Given a structure defined in this specification, return an ASCII | <t>Given a structure defined in this specification, return an ASCII | |||
| string suitable for use in an HTTP field value.</t> | string suitable for use in an HTTP field value.</t> | |||
| <ol> | ||||
| <ol spacing="normal" type="1"> | ||||
| <li>If the structure is a Dictionary or List and its value is empty | <li>If the structure is a Dictionary or List and its value is empty | |||
| (i.e., it has no members), do not serialize the field at all (i.e., | (i.e., it has no members), do not serialize the field at all (i.e., | |||
| omit both the field-name and field-value).</li> | omit both the field-name and field-value).</li> | |||
| <li>If the structure is a List, let output_string be the result of | <li>If the structure is a List, let output_string be the result of | |||
| running Serializing a List (<xref target="ser-list" | running Serializing a List (<xref target="ser-list"/>) with the structu | |||
| format="default"/>) with the structure.</li> | re.</li> | |||
| <li>Else, if the structure is a Dictionary, let output_string be the | <li>Else, if the structure is a Dictionary, let output_string be the | |||
| result of running Serializing a Dictionary (<xref | result of running Serializing a Dictionary (<xref target="ser-dictionar | |||
| target="ser-dictionary" format="default"/>) with the structure.</li> | y"/>) with the structure.</li> | |||
| <li>Else, if the structure is an Item, let output_string be the | <li>Else, if the structure is an Item, let output_string be the | |||
| result of running Serializing an Item (<xref target="ser-item" | result of running Serializing an Item (<xref target="ser-item"/>) with | |||
| format="default"/>) with the structure.</li> | the structure.</li> | |||
| <li>Else, fail serialization.</li> | <li>Else, fail serialization.</li> | |||
| <li>Return output_string converted into an array of bytes, using | <li>Return output_string converted into an array of bytes, using | |||
| ASCII encoding <xref target="RFC0020" format="default"/>.</li> | ASCII encoding <xref target="RFC0020"/>.</li> | |||
| </ol> | </ol> | |||
| <section anchor="ser-list"> | ||||
| <section anchor="ser-list" numbered="true" toc="default"> | ||||
| <name>Serializing a List</name> | <name>Serializing a List</name> | |||
| <t>Given an array of (member_value, parameters) tuples as | <t>Given an array of (member_value, parameters) tuples as | |||
| input_list, return an ASCII string suitable for use in an HTTP field | input_list, return an ASCII string suitable for use in an HTTP field | |||
| value.</t> | value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li> | <li> | |||
| <t>For each (member_value, parameters) of input_list: | <t>For each (member_value, parameters) of input_list: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If member_value is an array, append the result of running | <li>If member_value is an array, append the result of running | |||
| Serializing an Inner List (<xref target="ser-innerlist" | Serializing an Inner List (<xref target="ser-innerlist"/>) with ( | |||
| format="default"/>) with (member_value, parameters) to | member_value, parameters) to | |||
| output.</li> | output.</li> | |||
| <li>Otherwise, append the result of running Serializing an | <li>Otherwise, append the result of running Serializing an | |||
| Item (<xref target="ser-item" format="default"/>) with | Item (<xref target="ser-item"/>) with | |||
| (member_value, parameters) to output.</li> | (member_value, parameters) to output.</li> | |||
| <li> | <li> | |||
| <t>If more member_values remain in input_list: | <t>If more member_values remain in input_list: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append "," to output.</li> | <li>Append "," to output.</li> | |||
| <li>Append a single SP to output.</li> | <li>Append a single SP to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| <section anchor="ser-innerlist" numbered="true" toc="default"> | <section anchor="ser-innerlist"> | |||
| <name>Serializing an Inner List</name> | <name>Serializing an Inner List</name> | |||
| <t>Given an array of (member_value, parameters) tuples as | <t>Given an array of (member_value, parameters) tuples as | |||
| inner_list, and parameters as list_parameters, return an ASCII | inner_list, and parameters as list_parameters, return an ASCII | |||
| string suitable for use in an HTTP field value.</t> | string suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output be the string "(".</li> | <li>Let output be the string "(".</li> | |||
| <li> | <li> | |||
| <t>For each (member_value, parameters) of inner_list: | <t>For each (member_value, parameters) of inner_list: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append the result of running Serializing an Item (<xref | <li>Append the result of running Serializing an Item (<xref ta | |||
| target="ser-item" format="default"/>) with (member_value, | rget="ser-item"/>) with (member_value, | |||
| parameters) to output.</li> | parameters) to output.</li> | |||
| <li>If more values remain in inner_list, append a single SP to output.</li> | <li>If more values remain in inner_list, append a single SP to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Append ")" to output.</li> | <li>Append ")" to output.</li> | |||
| <li>Append the result of running Serializing Parameters (<xref | <li>Append the result of running Serializing Parameters (<xref tar | |||
| target="ser-params" format="default"/>) with list_parameters to | get="ser-params"/>) with list_parameters to | |||
| output.</li> | output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-params" numbered="true" toc="default"> | <section anchor="ser-params"> | |||
| <name>Serializing Parameters</name> | <name>Serializing Parameters</name> | |||
| <t>Given an ordered Dictionary as input_parameters (each member | <t>Given an ordered Dictionary as input_parameters (each member | |||
| having a param_name and a param_value), return an ASCII string | having a param_name and a param_value), return an ASCII string | |||
| suitable for use in an HTTP field value.</t> | suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li> | <li> | |||
| <t>For each param_name with a value of param_value in input_para meters: | <t>For each param_name with a value of param_value in input_para meters: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append ";" to output.</li> | <li>Append ";" to output.</li> | |||
| <li>Append the result of running Serializing a Key (<xref | <li>Append the result of running Serializing a Key (<xref targ | |||
| target="ser-key" format="default"/>) with param_name to | et="ser-key"/>) with param_name to | |||
| output.</li> | output.</li> | |||
| <li> | <li> | |||
| <t>If param_value is not Boolean true: | <t>If param_value is not Boolean true: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append "=" to output.</li> | <li>Append "=" to output.</li> | |||
| <li>Append the result of running Serializing a bare Item | <li>Append the result of running Serializing a bare Item | |||
| (<xref target="ser-bare-item" format="default"/>) with | (<xref target="ser-bare-item"/>) with | |||
| param_value to output.</li> | param_value to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-key" numbered="true" toc="default"> | <section anchor="ser-key"> | |||
| <name>Serializing a Key</name> | <name>Serializing a Key</name> | |||
| <t>Given a key as input_key, return an ASCII string suitable for | <t>Given a key as input_key, return an ASCII string suitable for | |||
| use in an HTTP field value.</t> | use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Convert input_key into a sequence of ASCII characters; if | <li>Convert input_key into a sequence of ASCII characters; if | |||
| conversion fails, fail serialization.</li> | conversion fails, fail serialization.</li> | |||
| <li>If input_key contains characters not in lcalpha, DIGIT, "_", | <li>If input_key contains characters not in lcalpha, DIGIT, "_", | |||
| "-", ".", or "*", fail serialization.</li> | "-", ".", or "*", fail serialization.</li> | |||
| <li>If the first character of input_key is not lcalpha or "*", | <li>If the first character of input_key is not lcalpha or "*", | |||
| fail serialization.</li> | fail serialization.</li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>Append input_key to output.</li> | <li>Append input_key to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="ser-dictionary" numbered="true" toc="default"> | <section anchor="ser-dictionary"> | |||
| <name>Serializing a Dictionary</name> | <name>Serializing a Dictionary</name> | |||
| <t>Given an ordered Dictionary as input_dictionary (each member | <t>Given an ordered Dictionary as input_dictionary (each member | |||
| having a member_name and a tuple value of (member_value, | having a member_name and a tuple value of (member_value, | |||
| parameters)), return an ASCII string suitable for use in an HTTP | parameters)), return an ASCII string suitable for use in an HTTP | |||
| field value.</t> | field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li> | <li> | |||
| <t>For each member_name with a value of (member_value, parameters) in input_dictionary: | <t>For each member_name with a value of (member_value, parameters) in input_dictionary: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append the result of running Serializing a Key (<xref | <li>Append the result of running Serializing a Key (<xref target | |||
| target="ser-key" format="default"/>) with member's member_name | ="ser-key"/>) with member's member_name | |||
| to output.</li> | to output.</li> | |||
| <li> | <li> | |||
| <t>If member_value is Boolean true: | <t>If member_value is Boolean true: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append the result of running Serializing Parameters | <li>Append the result of running Serializing Parameters | |||
| (<xref target="ser-params" format="default"/>) with | (<xref target="ser-params"/>) with | |||
| parameters to output.</li> | parameters to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>Otherwise: | <t>Otherwise: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append "=" to output.</li> | <li>Append "=" to output.</li> | |||
| <li>If member_value is an array, append the result of | <li>If member_value is an array, append the result of | |||
| running Serializing an Inner List (<xref | running Serializing an Inner List (<xref target="ser-innerlis | |||
| target="ser-innerlist" format="default"/>) with | t"/>) with | |||
| (member_value, parameters) to output.</li> | (member_value, parameters) to output.</li> | |||
| <li>Otherwise, append the result of running Serializing an | <li>Otherwise, append the result of running Serializing an | |||
| Item (<xref target="ser-item" format="default"/>) with | Item (<xref target="ser-item"/>) with | |||
| (member_value, parameters) to output.</li> | (member_value, parameters) to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>If more members remain in input_dictionary: | <t>If more members remain in input_dictionary: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append "," to output.</li> | <li>Append "," to output.</li> | |||
| <li>Append a single SP to output.</li> | <li>Append a single SP to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-item" numbered="true" toc="default"> | <section anchor="ser-item"> | |||
| <name>Serializing an Item</name> | <name>Serializing an Item</name> | |||
| <t>Given an Item as bare_item and Parameters as item_parameters, | <t>Given an Item as bare_item and Parameters as item_parameters, | |||
| return an ASCII string suitable for use in an HTTP field value.</t> | return an ASCII string suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>Append the result of running Serializing a Bare Item (<xref | <li>Append the result of running Serializing a Bare Item (<xref targ | |||
| target="ser-bare-item" format="default"/>) with bare_item to | et="ser-bare-item"/>) with bare_item to | |||
| output.</li> | output.</li> | |||
| <li>Append the result of running Serializing Parameters (<xref | <li>Append the result of running Serializing Parameters (<xref targe | |||
| target="ser-params" format="default"/>) with item_parameters to | t="ser-params"/>) with item_parameters to | |||
| output.</li> | output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| <section anchor="ser-bare-item" numbered="true" toc="default"> | <section anchor="ser-bare-item"> | |||
| <name>Serializing a Bare Item</name> | <name>Serializing a Bare Item</name> | |||
| <t>Given an Item as input_item, return an ASCII string suitable | <t>Given an Item as input_item, return an ASCII string suitable | |||
| for use in an HTTP field value.</t> | for use in an HTTP field value.</t> | |||
| <ol> | ||||
| <!--[rfced] Would you like to switch the order of #5 and #6 so that | ||||
| the section references will be in asending order? | ||||
| Original: | ||||
| 5. If input_item is a Boolean, return the result of running | ||||
| Serializing a Boolean (Section 4.1.9) with input_item. | ||||
| 6. If input_item is a Byte Sequence, return the result of running | ||||
| Serializing a Byte Sequence (Section 4.1.8) with input_item. | ||||
| Perhaps: | ||||
| 5. If input_item is a Byte Sequence, return the result of running | ||||
| Serializing a Byte Sequence (Section 4.1.8) with input_item. | ||||
| 6. If input_item is a Boolean, return the result of running | ||||
| Serializing a Boolean (Section 4.1.9) with input_item. | ||||
| <ol spacing="normal" type="1"> | ||||
| <li>If input_item is an Integer, return the result of running | <li>If input_item is an Integer, return the result of running | |||
| Serializing an Integer (<xref target="ser-integer" | Serializing an Integer (<xref target="ser-integer"/>) with input_it | |||
| format="default"/>) with input_item.</li> | em.</li> | |||
| <li>If input_item is a Decimal, return the result of running | <li>If input_item is a Decimal, return the result of running | |||
| Serializing a Decimal (<xref target="ser-decimal" | Serializing a Decimal (<xref target="ser-decimal"/>) with input_ite | |||
| format="default"/>) with input_item.</li> | m.</li> | |||
| <li>If input_item is a String, return the result of running | <li>If input_item is a String, return the result of running | |||
| Serializing a String (<xref target="ser-string" | Serializing a String (<xref target="ser-string"/>) with input_item. | |||
| format="default"/>) with input_item.</li> | </li> | |||
| <li>If input_item is a Token, return the result of running | <li>If input_item is a Token, return the result of running | |||
| Serializing a Token (<xref target="ser-token" | Serializing a Token (<xref target="ser-token"/>) with input_item.</ | |||
| format="default"/>) with input_item.</li> | li> | |||
| <li>If input_item is a Boolean, return the result of running | ||||
| Serializing a Boolean (<xref target="ser-boolean" | ||||
| format="default"/>) with input_item.</li> | ||||
| <li>If input_item is a Byte Sequence, return the result of | <li>If input_item is a Byte Sequence, return the result of | |||
| running Serializing a Byte Sequence (<xref target="ser-binary" | running Serializing a Byte Sequence (<xref target="ser-binary"/>) w | |||
| format="default"/>) with input_item.</li> | ith input_item.</li> | |||
| <li>If input_item is a Boolean, return the result of running | ||||
| Serializing a Boolean (<xref target="ser-boolean"/>) with | ||||
| input_item.</li> | ||||
| <li>Otherwise, fail serialization.</li> | <li>Otherwise, fail serialization.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="ser-integer" numbered="true" toc="default"> | <section anchor="ser-integer"> | |||
| <name>Serializing an Integer</name> | <name>Serializing an Integer</name> | |||
| <t>Given an Integer as input_integer, return an ASCII string | <t>Given an Integer as input_integer, return an ASCII string | |||
| suitable for use in an HTTP field value.</t> | suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_integer is not an integer in the range of | <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 | -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | |||
| serialization.</li> | serialization.</li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>If input_integer is less than (but not equal to) 0, append "-" | <li>If input_integer is less than (but not equal to) 0, append "-" | |||
| to output.</li> | to output.</li> | |||
| <li>Append input_integer's numeric value represented in base 10 | <li>Append input_integer's numeric value represented in base 10 | |||
| using only decimal digits to output.</li> | using only decimal digits to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-decimal" numbered="true" toc="default"> | <section anchor="ser-decimal"> | |||
| <name>Serializing a Decimal</name> | <name>Serializing a Decimal</name> | |||
| <t>Given a decimal number as input_decimal, return an ASCII string | <t>Given a decimal number as input_decimal, return an ASCII string | |||
| suitable for use in an HTTP field value.</t> | suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_decimal is not a decimal number, fail serialization.</l i> | <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 | <li>If input_decimal has more than three significant digits to the | |||
| right of the decimal point, round it to three decimal places, | right of the decimal point, round it to three decimal places, | |||
| rounding the final digit to the nearest value, or to the even | rounding the final digit to the nearest value, or to the even | |||
| value if it is equidistant.</li> | value if it is equidistant.</li> | |||
| <li>If input_decimal has more than 12 significant digits to the | <li>If input_decimal has more than 12 significant digits to the | |||
| left of the decimal point after rounding, fail serialization.</li> | left of the decimal point after rounding, fail serialization.</li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>If input_decimal is less than (but not equal to) 0, append "-" | <li>If input_decimal is less than (but not equal to) 0, append "-" | |||
| to output.</li> | to output.</li> | |||
| skipping to change at line 931 ¶ | skipping to change at line 807 ¶ | |||
| "0".</li> | "0".</li> | |||
| <li>Append "." to output.</li> | <li>Append "." to output.</li> | |||
| <li>If input_decimal's fractional component is zero, append "0" to | <li>If input_decimal's fractional component is zero, append "0" to | |||
| output.</li> | output.</li> | |||
| <li>Otherwise, append the significant digits of input_decimal's | <li>Otherwise, append the significant digits of input_decimal's | |||
| fractional component represented in base 10 (using only decimal | fractional component represented in base 10 (using only decimal | |||
| digits) to output.</li> | digits) to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-string" numbered="true" toc="default"> | <section anchor="ser-string"> | |||
| <name>Serializing a String</name> | <name>Serializing a String</name> | |||
| <t>Given a String as input_string, return an ASCII string suitable | <t>Given a String as input_string, return an ASCII string suitable | |||
| for use in an HTTP field value.</t> | for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Convert input_string into a sequence of ASCII characters; if | <li>Convert input_string into a sequence of ASCII characters; if | |||
| conversion fails, fail serialization.</li> | conversion fails, fail serialization.</li> | |||
| <li>If input_string contains characters in the range %x00-1f or | <li>If input_string contains characters in the range %x00-1f or | |||
| %x7f (i.e., not in VCHAR or SP), fail serialization.</li> | %x7f (i.e., not in VCHAR or SP), fail serialization.</li> | |||
| <li>Let output be the string DQUOTE.</li> | <li>Let output be the string DQUOTE.</li> | |||
| <li> | <li> | |||
| <t>For each character char in input_string: | <t>For each character char in input_string: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li> | <li> | |||
| <t>If char is "\" or DQUOTE: | <t>If char is "\" or DQUOTE: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append "\" to output.</li> | <li>Append "\" to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Append char to output.</li> | <li>Append char to output.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Append DQUOTE to output.</li> | <li>Append DQUOTE to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-token" numbered="true" toc="default"> | <section anchor="ser-token"> | |||
| <name>Serializing a Token</name> | <name>Serializing a Token</name> | |||
| <t>Given a Token as input_token, return an ASCII string suitable for | <t>Given a Token as input_token, return an ASCII string suitable for | |||
| use in an HTTP field value.</t> | use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Convert input_token into a sequence of ASCII characters; if | <li>Convert input_token into a sequence of ASCII characters; if | |||
| conversion fails, fail serialization.</li> | conversion fails, fail serialization.</li> | |||
| <li>If the first character of input_token is not ALPHA or "*", or | <li>If the first character of input_token is not ALPHA or "*", or | |||
| the remaining portion contains a character not in tchar, ":", or | the remaining portion contains a character not in tchar, ":", or | |||
| "/", fail serialization.</li> | "/", fail serialization.</li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>Append input_token to output.</li> | <li>Append input_token to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="ser-binary" numbered="true" toc="default"> | <section anchor="ser-binary"> | |||
| <name>Serializing a Byte Sequence</name> | <name>Serializing a Byte Sequence</name> | |||
| <t>Given a Byte Sequence as input_bytes, return an ASCII string | <t>Given a Byte Sequence as input_bytes, return an ASCII string | |||
| suitable for use in an HTTP field value.</t> | suitable for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_bytes is not a sequence of bytes, fail serialization.</ li> | <li>If input_bytes is not a sequence of bytes, fail serialization.</ li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>Append ":" to output.</li> | <li>Append ":" to output.</li> | |||
| <li>Append the result of base64-encoding input_bytes as per <xref | <li>Append the result of base64-encoding input_bytes as per <xref ta | |||
| target="RFC4648" sectionFormat="comma" section="4"/>, taking account | rget="RFC4648" sectionFormat="comma" section="4"/>, taking account of | |||
| of | ||||
| the requirements below.</li> | the requirements below.</li> | |||
| <li>Append ":" to output.</li> | <li>Append ":" to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| <t>The encoded data is required to be padded with "=", as per <xref | <t>The encoded data is required to be padded with "=", as per <xref ta | |||
| target="RFC4648" sectionFormat="comma" section="3.2"/>.</t> | rget="RFC4648" sectionFormat="comma" section="3.2"/>.</t> | |||
| <t>Likewise, encoded data <bcp14>SHOULD</bcp14> have pad bits set to z ero, as per | <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 | <xref target="RFC4648" sectionFormat="comma" section="3.5"/>, unless it is | |||
| not possible to do so due to implementation constraints.</t> | not possible to do so due to implementation constraints.</t> | |||
| </section> | </section> | |||
| <section anchor="ser-boolean" numbered="true" toc="default"> | <section anchor="ser-boolean"> | |||
| <name>Serializing a Boolean</name> | <name>Serializing a Boolean</name> | |||
| <t>Given a Boolean as input_boolean, return an ASCII string suitable | <t>Given a Boolean as input_boolean, return an ASCII string suitable | |||
| for use in an HTTP field value.</t> | for use in an HTTP field value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_boolean is not a boolean, fail serialization.</li> | <li>If input_boolean is not a boolean, fail serialization.</li> | |||
| <li>Let output be an empty string.</li> | <li>Let output be an empty string.</li> | |||
| <li>Append "?" to output.</li> | <li>Append "?" to output.</li> | |||
| <li>If input_boolean is true, append "1" 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>If input_boolean is false, append "0" to output.</li> | |||
| <li>Return output.</li> | <li>Return output.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="text-parse" numbered="true" toc="default"> | <section anchor="text-parse"> | |||
| <name>Parsing Structured Fields</name> | <name>Parsing Structured Fields</name> | |||
| <t>When a receiving implementation parses HTTP fields that are known | <t>When a receiving implementation parses HTTP fields that are known | |||
| to be Structured Fields, it is important that care be taken, as there | 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 | are a number of edge cases that can cause interoperability or even | |||
| security problems. This section specifies the algorithm for doing | security problems. This section specifies the algorithm for doing | |||
| so.</t> | so.</t> | |||
| <t>Given an array of bytes as input_bytes that represent the chosen | ||||
| <!--[rfced] Please clarify if "an array of bytes input_bytes" is | ||||
| correct, or should it perhaps be "an array of bytes as | ||||
| input_bytes"? | ||||
| Original: | ||||
| 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 "dictionary", "list", or "item"), return the | ||||
| parsed header value. | ||||
| Perhaps: | ||||
| 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>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's field-value (which is empty if that field is not present) and | |||
| field_type (one of "dictionary", "list", or "item"), return the parsed | field_type (one of "dictionary", "list", or "item"), return the parsed | |||
| header value.</t> | header value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Convert input_bytes into an ASCII string input_string; if | <li>Convert input_bytes into an ASCII string input_string; if | |||
| conversion fails, fail parsing.</li> | conversion fails, fail parsing.</li> | |||
| <li>Discard any leading SP characters from input_string.</li> | <li>Discard any leading SP characters from input_string.</li> | |||
| <li>If field_type is "list", let output be the result of running | <li>If field_type is "list", let output be the result of running | |||
| Parsing a List (<xref target="parse-list" format="default"/>) with | Parsing a List (<xref target="parse-list"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>If field_type is "dictionary", let output be the result of | <li>If field_type is "dictionary", let output be the result of | |||
| running Parsing a Dictionary (<xref target="parse-dictionary" | running Parsing a Dictionary (<xref target="parse-dictionary"/>) with i | |||
| format="default"/>) with input_string.</li> | nput_string.</li> | |||
| <li>If field_type is "item", let output be the result of running | <li>If field_type is "item", let output be the result of running | |||
| Parsing an Item (<xref target="parse-item" format="default"/>) with | Parsing an Item (<xref target="parse-item"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Discard any leading SP characters from input_string.</li> | <li>Discard any leading SP characters from input_string.</li> | |||
| <li>If input_string is not empty, fail parsing.</li> | <li>If input_string is not empty, fail parsing.</li> | |||
| <li>Otherwise, return output.</li> | <li>Otherwise, return output.</li> | |||
| </ol> | </ol> | |||
| <t>When generating input_bytes, parsers <bcp14>MUST</bcp14> combine all field lines | <t>When generating input_bytes, parsers <bcp14>MUST</bcp14> combine all field lines | |||
| in the same section (header or trailer) that case-insensitively match | in the same section (header or trailer) that case-insensitively match | |||
| the field name into one comma-separated field-value, as per <xref | the field name into one comma-separated field-value, as per <xref target= | |||
| target="RFC7230" sectionFormat="comma" section="3.2.2"/>; this assures th | "RFC7230" sectionFormat="comma" section="3.2.2"/>; this assures that | |||
| at | ||||
| the entire field value is processed correctly.</t> | the entire field value is processed correctly.</t> | |||
| <t>For Lists and Dictionaries, this has the effect of correctly | <t>For Lists and Dictionaries, this has the effect of correctly | |||
| concatenating all of the field's lines, as long as individual members | concatenating all of the field's lines, as long as individual members | |||
| of the top-level data structure are not split across multiple header | of the top-level data structure are not split across multiple header | |||
| instances. The parsing algorithms for both types allow tab characters, | instances. The parsing algorithms for both types allow tab characters, | |||
| since these might be used to combine field lines by some | since these might be used to combine field lines by some | |||
| implementations.</t> | implementations.</t> | |||
| <t>Strings split across multiple field lines will have unpredictable | <t>Strings split across multiple field lines will have unpredictable | |||
| results, because a comma(s) and whitespace inserted upon combination | results, because one or more commas (with optional whitespace) | |||
| will become part of the string output by the parser. Since | will become part of the string output by the parser. Since | |||
| concatenation might be done by an upstream intermediary, the results | concatenation might be done by an upstream intermediary, the results | |||
| are not under the control of the serializer or the parser, even when | are not under the control of the serializer or the parser, even when | |||
| they are both under the control of the same party.</t> | they are both under the control of the same party.</t> | |||
| <t>Tokens, Integers, Decimals, and Byte Sequences cannot be split | <t>Tokens, Integers, Decimals, and Byte Sequences cannot be split | |||
| across multiple field lines because the inserted commas will cause | across multiple field lines because the inserted commas will cause | |||
| parsing to fail.</t> | parsing to fail.</t> | |||
| <t>Parsers <bcp14>MAY</bcp14> fail when processing a field value spread across | <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 | 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 | 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 | defined as an sf-string is allowed to fail when processing this field | |||
| section:</t> | section:</t> | |||
| <sourcecode><![CDATA[ | <sourcecode type="http-message"> | |||
| Example-String: "foo | Example-String: "foo | |||
| Example-String: bar" | Example-String: bar" | |||
| ]]></sourcecode> | </sourcecode> | |||
| <t>If parsing fails -- including when calling another algorithm -- the | <t>If parsing fails -- including when calling another algorithm -- the | |||
| entire field value <bcp14>MUST</bcp14> be ignored (i.e., treated as if th e field were | entire field value <bcp14>MUST</bcp14> be ignored (i.e., treated as if th e field were | |||
| not present in the section). This is intentionally strict, to improve | not present in the section). This is intentionally strict, to improve | |||
| interoperability and safety, and specifications referencing this | interoperability and safety, and specifications referencing this | |||
| document are not allowed to loosen this requirement.</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 parsing the field; for example, an intermediary is not required | is not parsing the field; for example, an intermediary is not required | |||
| to strip a failing field from a message before forwarding it.</t> | to strip a failing field from a message before forwarding it.</t> | |||
| <section anchor="parse-list" numbered="true" toc="default"> | <section anchor="parse-list"> | |||
| <name>Parsing a List</name> | <name>Parsing a List</name> | |||
| <t>Given an ASCII string as input_string, return an array of | <t>Given an ASCII string as input_string, return an array of | |||
| (item_or_inner_list, parameters) tuples. input_string is modified to | (item_or_inner_list, parameters) tuples. input_string is modified to | |||
| remove the parsed value.</t> | remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let members be an empty array.</li> | <li>Let members be an empty array.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Append the result of running Parsing an Item or Inner List | <li>Append the result of running Parsing an Item or Inner List | |||
| (<xref target="parse-item-or-list" format="default"/>) with | (<xref target="parse-item-or-list"/>) with | |||
| input_string to members.</li> | input_string to members.</li> | |||
| <li>Discard any leading OWS characters from input_string.</li> | <li>Discard any leading OWS characters from input_string.</li> | |||
| <li>If input_string is empty, return members.</li> | <li>If input_string is empty, return members.</li> | |||
| <li>Consume the first character of input_string; if it is not | <li>Consume the first character of input_string; if it is not | |||
| ",", fail parsing.</li> | ",", fail parsing.</li> | |||
| <li>Discard any leading OWS characters from input_string.</li> | <li>Discard any leading OWS characters from input_string.</li> | |||
| <li>If input_string is empty, there is a trailing comma; fail pa rsing.</li> | <li>If input_string is empty, there is a trailing comma; fail pa rsing.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>No structured data has been found; return members (which is empt y).</li> | <li>No structured data has been found; return members (which is empt y).</li> | |||
| </ol> | </ol> | |||
| <section anchor="parse-item-or-list" numbered="true" toc="default"> | <section anchor="parse-item-or-list"> | |||
| <name>Parsing an Item or Inner List</name> | <name>Parsing an Item or Inner List</name> | |||
| <t>Given an ASCII string as input_string, return the tuple | <t>Given an ASCII string as input_string, return the tuple | |||
| (item_or_inner_list, parameters), where item_or_inner_list can be | (item_or_inner_list, parameters), where item_or_inner_list can be | |||
| either a single bare item or an array of (bare_item, parameters) | either a single bare item or an array of (bare_item, parameters) | |||
| tuples. input_string is modified to remove the parsed value.</t> | tuples. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is "(", return the | <li>If the first character of input_string is "(", return the | |||
| result of running Parsing an Inner List (<xref | result of running Parsing an Inner List (<xref target="parse-innerl | |||
| target="parse-innerlist" format="default"/>) with | ist"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Return the result of running Parsing an Item (<xref | <li>Return the result of running Parsing an Item (<xref target="pa | |||
| target="parse-item" format="default"/>) with input_string.</li> | rse-item"/>) with input_string.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="parse-innerlist" numbered="true" toc="default"> | <section anchor="parse-innerlist"> | |||
| <name>Parsing an Inner List</name> | <name>Parsing an Inner List</name> | |||
| <t>Given an ASCII string as input_string, return the tuple | <t>Given an ASCII string as input_string, return the tuple | |||
| (inner_list, parameters), where inner_list is an array of | (inner_list, parameters), where inner_list is an array of | |||
| (bare_item, parameters) tuples. input_string is modified to remove | (bare_item, parameters) tuples. input_string is modified to remove | |||
| the parsed value.</t> | the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Consume the first character of input_string; if it is not | <li>Consume the first character of input_string; if it is not | |||
| "(", fail parsing.</li> | "(", fail parsing.</li> | |||
| <li>Let inner_list be an empty array.</li> | <li>Let inner_list be an empty array.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Discard any leading SP characters from input_string.</li> | <li>Discard any leading SP characters from input_string.</li> | |||
| <li> | <li> | |||
| <t>If the first character of input_string is ")": | <t>If the first character of input_string is ")": | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Consume the first character of input_string.</li> | <li>Consume the first character of input_string.</li> | |||
| <li>Let parameters be the result of running Parsing | <li>Let parameters be the result of running Parsing | |||
| Parameters (<xref target="parse-param" | Parameters (<xref target="parse-param"/>) with input_string | |||
| format="default"/>) with input_string.</li> | .</li> | |||
| <li>Return the tuple (inner_list, parameters).</li> | <li>Return the tuple (inner_list, parameters).</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Let item be the result of running Parsing an Item (<xref | <li>Let item be the result of running Parsing an Item (<xref t | |||
| target="parse-item" format="default"/>) with | arget="parse-item"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Append item to inner_list.</li> | <li>Append item to inner_list.</li> | |||
| <li>If the first character of input_string is not SP or ")", | <li>If the first character of input_string is not SP or ")", | |||
| fail parsing.</li> | fail parsing.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>The end of the Inner List was not found; fail parsing.</li> | <li>The end of the Inner List was not found; fail parsing.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="parse-dictionary" numbered="true" toc="default"> | <section anchor="parse-dictionary"> | |||
| <name>Parsing a Dictionary</name> | <name>Parsing a Dictionary</name> | |||
| <t>Given an ASCII string as input_string, return an ordered map | <t>Given an ASCII string as input_string, return an ordered map | |||
| whose values are (item_or_inner_list, parameters) | whose values are (item_or_inner_list, parameters) | |||
| tuples. input_string is modified to remove the parsed value.</t> | tuples. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let dictionary be an empty, ordered map.</li> | <li>Let dictionary be an empty, ordered map.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let this_key be the result of running Parsing a Key (<xref | <li>Let this_key be the result of running Parsing a Key (<xref t | |||
| target="parse-key" format="default"/>) with input_string.</li> | arget="parse-key"/>) with input_string.</li> | |||
| <li> | <li> | |||
| <t>If the first character of input_string is "=": | <t>If the first character of input_string is "=": | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Consume the first character of input_string.</li> | <li>Consume the first character of input_string.</li> | |||
| <li>Let member be the result of running Parsing an Item or | <li>Let member be the result of running Parsing an Item or | |||
| Inner List (<xref target="parse-item-or-list" | Inner List (<xref target="parse-item-or-list"/>) with input_s | |||
| format="default"/>) with input_string.</li> | tring.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>Otherwise: | <t>Otherwise: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let value be Boolean true.</li> | <li>Let value be Boolean true.</li> | |||
| <li>Let parameters be the result of running Parsing | <li>Let parameters be the result of running Parsing | |||
| Parameters (<xref target="parse-param" format="default"/>) | Parameters (<xref target="parse-param"/>) | |||
| with input_string.</li> | with input_string.</li> | |||
| <li>Let member be the tuple (value, parameters).</li> | <li>Let member be the tuple (value, parameters).</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <!--[rfced] May we either add quote marks around "this_key" or delete | ||||
| "name" in the sentence below? Note that there is one other instance in the text. | ||||
| Original: | ||||
| 4. Add name this_key with value member to dictionary. If | ||||
| dictionary already contains a name this_key (comparing | ||||
| character-for-character), overwrite its value. | ||||
| Perhaps: | ||||
| A) 4. Add name "this_key" with value member to dictionary. If | ||||
| dictionary already contains a name "this_key" (comparing | ||||
| character-for-character), overwrite its value. | ||||
| or | ||||
| B) 4. Add this_key with value member to dictionary. If | ||||
| dictionary already contains this_key (comparing | ||||
| character-for-character), overwrite its value. | ||||
| Another instance: | ||||
| If parameters already contains a name param_name (comparing | ||||
| character-for-character), overwrite its value. | ||||
| <li>Add name this_key with value member to dictionary. If | <li>Add name this_key with value member to dictionary. If | |||
| dictionary already contains a name this_key (comparing | dictionary already contains a name this_key (comparing | |||
| character for character), overwrite its value.</li> | character for character), overwrite its value.</li> | |||
| <li>Discard any leading OWS characters from input_string.</li> | <li>Discard any leading OWS characters from input_string.</li> | |||
| <li>If input_string is empty, return dictionary.</li> | <li>If input_string is empty, return dictionary.</li> | |||
| <li>Consume the first character of input_string; if it is not | <li>Consume the first character of input_string; if it is not | |||
| ",", fail parsing.</li> | ",", fail parsing.</li> | |||
| <li>Discard any leading OWS characters from input_string.</li> | <li>Discard any leading OWS characters from input_string.</li> | |||
| <li>If input_string is empty, there is a trailing comma; fail pa rsing.</li> | <li>If input_string is empty, there is a trailing comma; fail pa rsing.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>No structured data has been found; return dictionary (which is e mpty).</li> | <li>No structured data has been found; return dictionary (which is e mpty).</li> | |||
| </ol> | </ol> | |||
| <!-- [rfced] Is specifying "has the effect" important"? We wonder whether | <t>Note that when duplicate Dictionary keys are encountered, all but | |||
| this sentence would be more clear if it were "all but the last instance are | the last instance are ignored.</t> | |||
| ignored". (Note: this sentece appearas in Sections 4.2.2 and 4.2.3.2.) | ||||
| Original: | ||||
| Note that when duplicate Dictionary keys are encountered, this has | ||||
| the effect of ignoring all but the last instance. | ||||
| <t>Note that when duplicate Dictionary keys are encountered, it | ||||
| has the effect of ignoring all but the last instance.</t> | ||||
| </section> | </section> | |||
| <section anchor="parse-item" numbered="true" toc="default"> | <section anchor="parse-item"> | |||
| <name>Parsing an Item</name> | <name>Parsing an Item</name> | |||
| <t>Given an ASCII string as input_string, return a (bare_item, | <t>Given an ASCII string as input_string, return a (bare_item, | |||
| parameters) tuple. input_string is modified to remove the parsed | parameters) tuple. input_string is modified to remove the parsed | |||
| value.</t> | value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let bare_item be the result of running Parsing a Bare Item | <li>Let bare_item be the result of running Parsing a Bare Item | |||
| (<xref target="parse-bare-item" format="default"/>) with | (<xref target="parse-bare-item"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Let parameters be the result of running Parsing Parameters | <li>Let parameters be the result of running Parsing Parameters | |||
| (<xref target="parse-param" format="default"/>) with | (<xref target="parse-param"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Return the tuple (bare_item, parameters).</li> | <li>Return the tuple (bare_item, parameters).</li> | |||
| </ol> | </ol> | |||
| <section anchor="parse-bare-item" numbered="true" toc="default"> | <section anchor="parse-bare-item"> | |||
| <name>Parsing a Bare Item</name> | <name>Parsing a Bare Item</name> | |||
| <t>Given an ASCII string as input_string, return a bare | <t>Given an ASCII string as input_string, return a bare | |||
| Item. input_string is modified to remove the parsed value.</t> | Item. input_string is modified to remove the parsed value.</t> | |||
| <ol> | ||||
| <!--[rfced] Would you like to move #5 up in the list so that the | ||||
| section mentions will be in ascending order? | ||||
| Original: | ||||
| 2. If the first character of input_string is a DQUOTE, return the | ||||
| result of running Parsing a String (Section 4.2.5) with | ||||
| input_string. | ||||
| 3. If the first character of input_string is ":", return the result | ||||
| of running Parsing a Byte Sequence (Section 4.2.7) with | ||||
| input_string. | ||||
| 4. If the first character of input_string is "?", return the result | ||||
| of running Parsing a Boolean (Section 4.2.8) with input_string. | ||||
| 5. If the first character of input_string is an ALPHA or "*", return | ||||
| the result of running Parsing a Token (Section 4.2.6) with | ||||
| input_string. | ||||
| Perhaps: | ||||
| 2. If the first character of input_string is a DQUOTE, return the | ||||
| result of running Parsing a String (Section 4.2.5) with | ||||
| input_string. | ||||
| 3. If the first character of input_string is an ALPHA or "*", return | ||||
| the result of running Parsing a Token (Section 4.2.6) with | ||||
| input_string. | ||||
| 4. If the first character of input_string is ":", return the result | ||||
| of running Parsing a Byte Sequence (Section 4.2.7) with | ||||
| input_string. | ||||
| 5. If the first character of input_string is "?", return the result | ||||
| of running Parsing a Boolean (Section 4.2.8) with input_string. | ||||
| <ol spacing="normal" type="1"> | ||||
| <li>If the first character of input_string is a "-" or a DIGIT, | <li>If the first character of input_string is a "-" or a DIGIT, | |||
| return the result of running Parsing an Integer or Decimal | return the result of running Parsing an Integer or Decimal | |||
| (<xref target="parse-number" format="default"/>) with | (<xref target="parse-number"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>If the first character of input_string is a DQUOTE, return | <li>If the first character of input_string is a DQUOTE, return | |||
| the result of running Parsing a String (<xref | the result of running Parsing a String (<xref target="parse-string" | |||
| target="parse-string" format="default"/>) with | />) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>If the first character of input_string is an ALPHA or "*", | ||||
| return the result of running Parsing a Token (<xref target="parse-t | ||||
| oken"/>) with input_string.</li> | ||||
| <li>If the first character of input_string is ":", return the | <li>If the first character of input_string is ":", return the | |||
| result of running Parsing a Byte Sequence (<xref | result of running Parsing a Byte Sequence (<xref target="parse-bina | |||
| target="parse-binary" format="default"/>) with | ry"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>If the first character of input_string is "?", return the | <li>If the first character of input_string is "?", return the | |||
| result of running Parsing a Boolean (<xref | result of running Parsing a Boolean (<xref target="parse-boolean"/> | |||
| target="parse-boolean" format="default"/>) with | ) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>If the first character of input_string is an ALPHA or "*", | ||||
| return the result of running Parsing a Token (<xref | ||||
| target="parse-token" format="default"/>) with input_string.</li> | ||||
| <li>Otherwise, the item type is unrecognized; fail parsing.</li> | <li>Otherwise, the item type is unrecognized; fail parsing.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="parse-param" numbered="true" toc="default"> | <section anchor="parse-param"> | |||
| <name>Parsing Parameters</name> | <name>Parsing Parameters</name> | |||
| <t>Given an ASCII string as input_string, return an ordered map | <t>Given an ASCII string as input_string, return an ordered map | |||
| whose values are bare Items. input_string is modified to remove | whose values are bare Items. input_string is modified to remove | |||
| the parsed value.</t> | the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let parameters be an empty, ordered map.</li> | <li>Let parameters be an empty, ordered map.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not ";", exit th e loop.</li> | <li>If the first character of input_string is not ";", exit th e loop.</li> | |||
| <li>Consume a ";" character from the beginning of input_string .</li> | <li>Consume the ";" character from the beginning of input_stri ng.</li> | |||
| <li>Discard any leading SP characters from input_string.</li> | <li>Discard any leading SP characters from input_string.</li> | |||
| <li>Let param_name be the result of running Parsing a Key | <li>Let param_name be the result of running Parsing a Key | |||
| (<xref target="parse-key" format="default"/>) with | (<xref target="parse-key"/>) with | |||
| input_string.</li> | input_string.</li> | |||
| <li>Let param_value be Boolean true.</li> | <li>Let param_value be Boolean true.</li> | |||
| <li> | <li> | |||
| <t>If the first character of input_string is "=": | <t>If the first character of input_string is "=": | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Consume the "=" character at the beginning of input_st ring.</li> | <li>Consume the "=" character at the beginning of input_st ring.</li> | |||
| <li>Let param_value be the result of running Parsing a | <li>Let param_value be the result of running Parsing a | |||
| Bare Item (<xref target="parse-bare-item" | Bare Item (<xref target="parse-bare-item"/>) with input_str | |||
| format="default"/>) with input_string.</li> | ing.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Append key param_name with value param_value to | <li>Append key param_name with value param_value to | |||
| parameters. If parameters already contains a name param_name | parameters. If parameters already contains a name param_name | |||
| (comparing character for character), overwrite its | (comparing character for character), overwrite its | |||
| value.</li> | value.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return parameters.</li> | <li>Return parameters.</li> | |||
| </ol> | </ol> | |||
| <t>Note that when duplicate Parameter keys are encountered, it | <t>Note that when duplicate parameter keys are encountered, | |||
| has the effect of ignoring all but the last instance.</t> | all but the last instance are ignored.</t> | |||
| </section> | </section> | |||
| <section anchor="parse-key" numbered="true" toc="default"> | <section anchor="parse-key"> | |||
| <name>Parsing a Key</name> | <name>Parsing a Key</name> | |||
| <t>Given an ASCII string as input_string, return a | <t>Given an ASCII string as input_string, return a | |||
| key. input_string is modified to remove the parsed value.</t> | key. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not lcalpha or | <li>If the first character of input_string is not lcalpha or | |||
| "*", fail parsing.</li> | "*", fail parsing.</li> | |||
| <li>Let output_string be an empty string.</li> | <li>Let output_string be an empty string.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not one of | <li>If the first character of input_string is not one of | |||
| lcalpha, DIGIT, "_", "-", ".", or "*", return | lcalpha, DIGIT, "_", "-", ".", or "*", return | |||
| output_string.</li> | output_string.</li> | |||
| <li>Let char be the result of consuming the first character of input_string.</li> | <li>Let char be the result of consuming the first character of input_string.</li> | |||
| <li>Append char to output_string.</li> | <li>Append char to output_string.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output_string.</li> | <li>Return output_string.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="parse-number" numbered="true" toc="default"> | <section anchor="parse-number"> | |||
| <name>Parsing an Integer or Decimal</name> | <name>Parsing an Integer or Decimal</name> | |||
| <t>Given an ASCII string as input_string, return an Integer or | <t>Given an ASCII string as input_string, return an Integer or | |||
| Decimal. input_string is modified to remove the parsed value.</t> | Decimal. input_string is modified to remove the parsed value.</t> | |||
| <t>NOTE: This algorithm parses both Integers (<xref target="integer" | <t>NOTE: This algorithm parses both Integers (<xref target="integer"/> | |||
| format="default"/>) and Decimals (<xref target="decimal" | ) and Decimals (<xref target="decimal"/>), and returns the corresponding structu | |||
| format="default"/>) and returns the corresponding structure.</t> | re.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let type be "integer".</li> | <li>Let type be "integer".</li> | |||
| <li>Let sign be 1.</li> | <li>Let sign be 1.</li> | |||
| <li>Let input_number be an empty string.</li> | <li>Let input_number be an empty string.</li> | |||
| <li>If the first character of input_string is "-", consume it and | <li>If the first character of input_string is "-", consume it and | |||
| set sign to -1.</li> | set sign to -1.</li> | |||
| <li>If input_string is empty, there is an empty integer; fail | <li>If input_string is empty, there is an empty integer; fail | |||
| parsing.</li> | parsing.</li> | |||
| <li>If the first character of input_string is not a DIGIT, fail | <li>If the first character of input_string is not a DIGIT, fail | |||
| parsing.</li> | parsing.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let char be the result of consuming the first character of | <li>Let char be the result of consuming the first character of | |||
| input_string.</li> | input_string.</li> | |||
| <li>If char is a DIGIT, append it to input_number.</li> | <li>If char is a DIGIT, append it to input_number.</li> | |||
| <li> | <li> | |||
| <t>Else, if type is "integer" and char is ".": | <t>Else, if type is "integer" and char is ".": | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_number contains more than 12 characters, fail p arsing.</li> | <li>If input_number contains more than 12 characters, fail p arsing.</li> | |||
| <li>Otherwise, append char to input_number and set type to " decimal".</li> | <li>Otherwise, append char to input_number and set type to " decimal".</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Otherwise, prepend char to input_string, and exit the loop.< /li> | <li>Otherwise, prepend char to input_string, and exit the loop.< /li> | |||
| <li>If type is "integer" and input_number contains more than | <li>If type is "integer" and input_number contains more than | |||
| 15 characters, fail parsing.</li> | 15 characters, fail parsing.</li> | |||
| <li>If type is "decimal" and input_number contains more than | <li>If type is "decimal" and input_number contains more than | |||
| 16 characters, fail parsing.</li> | 16 characters, fail parsing.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>If type is "integer": | <t>If type is "integer": | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Parse input_number as an integer and let output_number be | <li>Parse input_number as an integer and let output_number be | |||
| the product of the result and sign.</li> | the product of the result and sign.</li> | |||
| <li>If output_number is outside the range -999,999,999,999,999 | ||||
| to 999,999,999,999,999 inclusive, fail parsing.</li> | ||||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>Otherwise: | <t>Otherwise: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the final character of input_number is ".", fail parsing. </li> | <li>If the final character of input_number is ".", fail parsing. </li> | |||
| <li>If the number of characters after "." in input_number is | <li>If the number of characters after "." in input_number is | |||
| greater than three, fail parsing.</li> | greater than three, fail parsing.</li> | |||
| <li>Parse input_number as a decimal number and let | <li>Parse input_number as a decimal number and let | |||
| output_number be the product of the result and sign.</li> | output_number be the product of the result and sign.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output_number.</li> | <li>Return output_number.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="parse-string" numbered="true" toc="default"> | <section anchor="parse-string"> | |||
| <name>Parsing a String</name> | <name>Parsing a String</name> | |||
| <t>Given an ASCII string as input_string, return an unquoted | <t>Given an ASCII string as input_string, return an unquoted | |||
| String. input_string is modified to remove the parsed value.</t> | String. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let output_string be an empty string.</li> | <li>Let output_string be an empty string.</li> | |||
| <li>If the first character of input_string is not DQUOTE, fail parsi ng.</li> | <li>If the first character of input_string is not DQUOTE, fail parsi ng.</li> | |||
| <li>Discard the first character of input_string.</li> | <li>Discard the first character of input_string.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>Let char be the result of consuming the first character of i nput_string.</li> | <li>Let char be the result of consuming the first character of i nput_string.</li> | |||
| <li> | <li> | |||
| <t>If char is a backslash ("\"): | <t>If char is a backslash ("\"): | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If input_string is now empty, fail parsing.</li> | <li>If input_string is now empty, fail parsing.</li> | |||
| <li>Let next_char be the result of consuming the first | <li>Let next_char be the result of consuming the first | |||
| character of input_string.</li> | character of input_string.</li> | |||
| <li>If next_char is not DQUOTE or "\", fail parsing.</li> | <li>If next_char is not DQUOTE or "\", fail parsing.</li> | |||
| <li>Append next_char to output_string.</li> | <li>Append next_char to output_string.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Else, if char is DQUOTE, return output_string.</li> | <li>Else, if char is DQUOTE, return output_string.</li> | |||
| <li>Else, if char is in the range %x00-1f or %x7f (i.e., it's | <li>Else, if char is in the range %x00-1f or %x7f (i.e., it is | |||
| not in VCHAR or SP), fail parsing.</li> | not in VCHAR or SP), fail parsing.</li> | |||
| <li>Else, append char to output_string.</li> | <li>Else, append char to output_string.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Reached the end of input_string without finding a closing | <li>Reached the end of input_string without finding a closing | |||
| DQUOTE; fail parsing.</li> | DQUOTE; fail parsing.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="parse-token" numbered="true" toc="default"> | <section anchor="parse-token"> | |||
| <name>Parsing a Token</name> | <name>Parsing a Token</name> | |||
| <t>Given an ASCII string as input_string, return a | <t>Given an ASCII string as input_string, return a | |||
| Token. input_string is modified to remove the parsed value.</t> | Token. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not ALPHA or "*", | <li>If the first character of input_string is not ALPHA or "*", | |||
| fail parsing.</li> | fail parsing.</li> | |||
| <li>Let output_string be an empty string.</li> | <li>Let output_string be an empty string.</li> | |||
| <li> | <li> | |||
| <t>While input_string is not empty: | <t>While input_string is not empty: | |||
| </t> | </t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not in tchar, | <li>If the first character of input_string is not in tchar, | |||
| ":", or "/", return output_string.</li> | ":", or "/", return output_string.</li> | |||
| <li>Let char be the result of consuming the first character of | <li>Let char be the result of consuming the first character of | |||
| input_string.</li> | input_string.</li> | |||
| <li>Append char to output_string.</li> | <li>Append char to output_string.</li> | |||
| </ol> | </ol> | |||
| </li> | </li> | |||
| <li>Return output_string.</li> | <li>Return output_string.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| <section anchor="parse-binary" numbered="true" toc="default"> | <section anchor="parse-binary"> | |||
| <name>Parsing a Byte Sequence</name> | <name>Parsing a Byte Sequence</name> | |||
| <t>Given an ASCII string as input_string, return a Byte | <t>Given an ASCII string as input_string, return a Byte | |||
| Sequence. input_string is modified to remove the parsed value.</t> | Sequence. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not ":", fail parsing. </li> | <li>If the first character of input_string is not ":", fail parsing. </li> | |||
| <li>Discard the first character of input_string.</li> | <li>Discard the first character of input_string.</li> | |||
| <li>If there is not a ":" character before the end of input_string, fail parsing.</li> | <li>If there is not a ":" character before the end of input_string, fail parsing.</li> | |||
| <li>Let b64_content be the result of consuming content of | <li>Let b64_content be the result of consuming content of | |||
| input_string up to but not including the first instance of the | input_string up to but not including the first instance of the | |||
| character ":".</li> | character ":".</li> | |||
| <li>Consume the ":" character at the beginning of input_string.</li> | <li>Consume the ":" character at the beginning of input_string.</li> | |||
| <li>If b64_content contains a character not included in ALPHA, | <li>If b64_content contains a character not included in ALPHA, | |||
| DIGIT, "+", "/", and "=", fail parsing.</li> | DIGIT, "+", "/", and "=", fail parsing.</li> | |||
| <li>Let binary_content be the result of base64-decoding <xref | <li>Let binary_content be the result of base64-decoding <xref target | |||
| target="RFC4648" format="default"/> b64_content, synthesizing | ="RFC4648"/> b64_content, synthesizing | |||
| padding if necessary (note the requirements about recipient | padding if necessary (note the requirements about recipient | |||
| behavior below).</li> | behavior below). If base64 decoding fails, parsing fails.</li> | |||
| <li>Return binary_content.</li> | <li>Return binary_content.</li> | |||
| </ol> | </ol> | |||
| <t>Because some implementations of base64 do not allow rejection of | <t>Because some implementations of base64 do not allow rejection of | |||
| encoded data that is not properly "=" padded (see <xref | encoded data that is not properly "=" padded (see <xref target="RFC4648 | |||
| target="RFC4648" sectionFormat="comma" section="3.2"/>), parsers <bcp14 | " sectionFormat="comma" section="3.2"/>), parsers <bcp14>SHOULD | |||
| >SHOULD | ||||
| NOT</bcp14> fail when "=" padding is not present, unless they cannot be | NOT</bcp14> fail when "=" padding is not present, unless they cannot be | |||
| configured to do so.</t> | configured to do so.</t> | |||
| <t>Because some implementations of base64 do not allow rejection of | <t>Because some implementations of base64 do not allow rejection of | |||
| encoded data that has non-zero pad bits (see <xref target="RFC4648" | encoded data that has non-zero pad bits (see <xref target="RFC4648" sec | |||
| sectionFormat="comma" section="3.5"/>), parsers <bcp14>SHOULD NOT</bcp1 | tionFormat="comma" section="3.5"/>), parsers <bcp14>SHOULD NOT</bcp14> fail when | |||
| 4> fail when | ||||
| non-zero pad bits are present, unless they cannot be configured to | non-zero pad bits are present, unless they cannot be configured to | |||
| do so.</t> | do so.</t> | |||
| <t>This specification does not relax the requirements in <xref | <t>This specification does not relax the requirements in <xref target= | |||
| target="RFC4648"/>, Sections <xref | "RFC4648"/>, Sections <xref target="RFC4648" sectionFormat="bare" section="3.1"/ | |||
| target="RFC4648" sectionFormat="bare" section="3.1"/> and <xref | > and <xref target="RFC4648" sectionFormat="bare" section="3.3"/>; therefore, | |||
| target="RFC4648" sectionFormat="bare" section="3.3"/>; therefore, | ||||
| parsers <bcp14>MUST</bcp14> fail on characters outside the base64 alpha bet and on line | parsers <bcp14>MUST</bcp14> fail on characters outside the base64 alpha bet and on line | |||
| feeds in encoded data.</t> | feeds in encoded data.</t> | |||
| </section> | </section> | |||
| <section anchor="parse-boolean" numbered="true" toc="default"> | <section anchor="parse-boolean"> | |||
| <name>Parsing a Boolean</name> | <name>Parsing a Boolean</name> | |||
| <t>Given an ASCII string as input_string, return a | <t>Given an ASCII string as input_string, return a | |||
| Boolean. input_string is modified to remove the parsed value.</t> | Boolean. input_string is modified to remove the parsed value.</t> | |||
| <ol spacing="normal" type="1"> | <ol> | |||
| <li>If the first character of input_string is not "?", fail parsing. </li> | <li>If the first character of input_string is not "?", fail parsing. </li> | |||
| <li>Discard the first character of input_string.</li> | <li>Discard the first character of input_string.</li> | |||
| <li>If the first character of input_string matches "1", discard | <li>If the first character of input_string matches "1", discard | |||
| the first character, and return true.</li> | the first character, and return true.</li> | |||
| <li>If the first character of input_string matches "0", discard | <li>If the first character of input_string matches "0", discard | |||
| the first character, and return false.</li> | the first character, and return false.</li> | |||
| <li>If no value has matched; fail parsing.</li> | <li>No value has matched; fail parsing.</li> | |||
| </ol> | </ol> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="iana-considerations" numbered="true" toc="default"> | <section anchor="iana-considerations"> | |||
| <name>IANA Considerations</name> | <name>IANA Considerations</name> | |||
| <t>This document has no IANA actions.</t> | <t>This document has no IANA actions.</t> | |||
| </section> | </section> | |||
| <section anchor="security-considerations" numbered="true" toc="default"> | <section anchor="security-considerations"> | |||
| <name>Security Considerations</name> | <name>Security Considerations</name> | |||
| <t>The size of most types defined by Structured Fields is not limited; | <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 | as a result, extremely large fields could be an attack vector (e.g., for | |||
| resource consumption). Most HTTP implementations limit the sizes of | resource consumption). Most HTTP implementations limit the sizes of | |||
| individual fields as well as the overall header or trailer section size | individual fields as well as the overall header or trailer section size | |||
| to mitigate such attacks.</t> | to mitigate such attacks.</t> | |||
| <t>It is possible for parties with the ability to inject new HTTP fields | <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 | 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 | will cause parsing to fail, but it is not possible to reliably fail in | |||
| all such circumstances.</t> | all such circumstances.</t> | |||
| </section> | </section> | |||
| </middle> | </middle> | |||
| <back> | <back> | |||
| <displayreference target="RFC3629" to="UTF-8"/> | ||||
| <references> | <references> | |||
| <name>References</name> | <name>References</name> | |||
| <references> | <references> | |||
| <name>Normative References</name> | <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.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.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.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.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.0020.xml"/> | |||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer ence.RFC.4648.xml"/> | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer ence.RFC.4648.xml"/> | |||
| skipping to change at line 1608 ¶ | skipping to change at line 1368 ¶ | |||
| <front> | <front> | |||
| <title>IEEE Standard for Floating-Point Arithmetic</title> | <title>IEEE Standard for Floating-Point Arithmetic</title> | |||
| <seriesInfo name="DOI" value="10.1109/IEEESTD.2019.8766229"/> | <seriesInfo name="DOI" value="10.1109/IEEESTD.2019.8766229"/> | |||
| <seriesInfo name="IEEE" value="754-2019"/> | <seriesInfo name="IEEE" value="754-2019"/> | |||
| <author> | <author> | |||
| <organization>IEEE</organization> | <organization>IEEE</organization> | |||
| </author> | </author> | |||
| <date year="2019" month="July"/> | <date year="2019" month="July"/> | |||
| </front> | </front> | |||
| </reference> | </reference> | |||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer ence.RFC.3629.xml"/> | ||||
| <!--[rfced] RFC 3986 had no corresponding reference entry in the References | <reference anchor='STD63' target='https://www.rfc-editor.org/info/std63'> | |||
| section. We have listed it as an informative reference. Please let us know | <front> | |||
| this should instead be normative. | <title>UTF-8, a transformation format of ISO 10646</title> | |||
| <author initials='F.' surname='Yergeau' fullname='F. Yergeau'><organization /></ | ||||
| author> | ||||
| <date year='2003' month='November' /> | ||||
| </front> | ||||
| <seriesInfo name='STD' value='63'/> | ||||
| <seriesInfo name='RFC' value='3629'/> | ||||
| </reference> | ||||
| Original: | ||||
| "foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | ||||
| 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 | ||||
| of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | ||||
| being used. | ||||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refere | ||||
| nce.RFC.3986.xml"/> | ||||
| <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.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.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.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.8259.xml"/> | |||
| <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer ence.RFC.7493.xml"/> | <xi:include href="https://xml2rfc.tools.ietf.org/public/rfc/bibxml/refer ence.RFC.7493.xml"/> | |||
| </references> | </references> | |||
| </references> | </references> | |||
| <section anchor="faq" numbered="true" toc="default"> | <section anchor="faq"> | |||
| <name>Frequently Asked Questions</name> | <name>Frequently Asked Questions</name> | |||
| <section anchor="why-not-json" numbered="true" toc="default"> | <section anchor="why-not-json"> | |||
| <name>Why Not JSON?</name> | <name>Why Not JSON?</name> | |||
| <t>Earlier proposals for Structured Fields were based upon JSON <xref | <t>Earlier proposals for Structured Fields were based upon JSON <xref ta | |||
| target="RFC8259" format="default"/>. However, constraining its use to | rget="RFC8259"/>. However, constraining its use to | |||
| make it suitable for HTTP header fields required senders and | make it suitable for HTTP header fields 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 | <t>For example, JSON has specification issues around large numbers and | |||
| objects with duplicate members. Although advice for avoiding these | objects with duplicate members. Although advice for avoiding these | |||
| issues is available (e.g., <xref target="RFC7493" format="default"/>), | issues is available (e.g., <xref target="RFC7493"/>), | |||
| it cannot be relied upon.</t> | it cannot be relied upon.</t> | |||
| <t>Likewise, JSON strings are by default Unicode strings, which have a | <t>Likewise, JSON strings are by default Unicode strings, which have a | |||
| number of potential interoperability issues (e.g., in | number of potential interoperability issues (e.g., in | |||
| comparison). Although implementers can be advised to avoid non-ASCII | comparison). Although implementers can be advised to avoid non-ASCII | |||
| content where unnecessary, this is difficult to enforce.</t> | content where unnecessary, this is difficult to enforce.</t> | |||
| <t>Another example is JSON's ability to nest content to arbitrary | <t>Another example is JSON's ability to nest content to arbitrary | |||
| depths. Since the resulting memory commitment might be unsuitable | depths. Since the resulting memory commitment might be unsuitable | |||
| (e.g., in embedded and other limited server deployments), it's | (e.g., in embedded and other limited server deployments), it's | |||
| necessary to limit it in some fashion; however, existing JSON | necessary to limit it in some fashion; however, existing JSON | |||
| implementations have no such limits, and even if a limit is specified, | implementations have no such limits, and even if a limit is specified, | |||
| skipping to change at line 1664 ¶ | skipping to change at line 1420 ¶ | |||
| implementations; some deployments would fail to enforce them, thereby | implementations; some deployments would fail to enforce them, thereby | |||
| harming interoperability. In short, if it looks like JSON, people will | harming interoperability. In short, if it looks like JSON, people will | |||
| be tempted to use a JSON parser/serializer on field values.</t> | be tempted to use a JSON parser/serializer on field values.</t> | |||
| <t>Since a major goal for Structured Fields is to improve | <t>Since a major goal for Structured Fields is to improve | |||
| interoperability and simplify implementation, these concerns led to a | interoperability and simplify implementation, these concerns led to a | |||
| format that requires a dedicated parser and serializer.</t> | format that requires a dedicated parser and serializer.</t> | |||
| <t>Additionally, there were widely shared feelings that JSON doesn't | <t>Additionally, there were widely shared feelings that JSON doesn't | |||
| "look right" in HTTP fields.</t> | "look right" in HTTP fields.</t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="implementation-notes" numbered="true" toc="default"> | <section anchor="implementation-notes"> | |||
| <name>Implementation Notes</name> | <name>Implementation Notes</name> | |||
| <t>A generic implementation of this specification should expose the | <t>A generic implementation of this specification should expose the | |||
| top-level serialize (<xref target="text-serialize" format="default"/>) | top-level serialize (<xref target="text-serialize"/>) | |||
| and parse (<xref target="text-parse" format="default"/>) functions. They | and parse (<xref target="text-parse"/>) functions. They | |||
| need not be functions; for example, it could be implemented as an | need not be functions; for example, it could be implemented as an | |||
| object, with methods for each of the different top-level types.</t> | object, with methods for each of the different top-level types.</t> | |||
| <t>For interoperability, it's important that generic implementations be | <t>For interoperability, it's important that generic implementations be | |||
| complete and follow the algorithms closely; see <xref target="strict" | complete and follow the algorithms closely; see <xref target="strict"/>. T | |||
| format="default"/>. To aid this, a common test suite is being maintained | o aid this, a common test suite is being maintained | |||
| by the community at <eref brackets="angle" target="https://github.com/http wg/structured-field-tests"/>.</t> | by the community at <eref brackets="angle" target="https://github.com/http wg/structured-field-tests"/>.</t> | |||
| <t>Implementers should note that Dictionaries and Parameters are | <t>Implementers should note that Dictionaries and Parameters are | |||
| order-preserving maps. Some fields may not convey meaning in the | order-preserving maps. Some fields may not convey meaning in the | |||
| ordering of these data types, but it should still be exposed so | ordering of these data types, but it should still be exposed so | |||
| that it will be available to applications that need to use it.</t> | that it will be available to applications that need to use it.</t> | |||
| <t>Likewise, implementations should note that it's important to preserve | <t>Likewise, implementations should note that it's important to preserve | |||
| the distinction between Tokens and Strings. While most programming | the distinction between Tokens and Strings. While most programming | |||
| languages have native types that map to the other types well, it may be | languages have native types that map to the other types well, it may be | |||
| necessary to create a wrapper "token" object or use a parameter on | necessary to create a wrapper "token" object or use a parameter on | |||
| functions to assure that these types remain separate.</t> | functions to assure that these types remain separate.</t> | |||
| <t>The serialization algorithm is defined in a way that it is not | <t>The serialization algorithm is defined in a way that it is not | |||
| strictly limited to the data types defined in <xref target="types" | strictly limited to the data types defined in <xref target="types"/> in ev | |||
| format="default"/> in every case. For example, Decimals are designed to | ery case. For example, Decimals are designed to | |||
| take broader input and round to allowed values.</t> | take broader input and round to allowed values.</t> | |||
| <t>Implementations are allowed to limit the size of different | ||||
| <!--[rfced] May we update "allowed" to be "may" to avoid using allowed | ||||
| twice (e.g., "allowed to limit the allowed"). | ||||
| Original: | ||||
| Implementations are allowed to limit the allowed size of different | ||||
| structures, subject to the minimums defined for each type. | ||||
| Perhaps: | ||||
| Implementations may limit the allowed size of different | ||||
| structures, subject to the minimums defined for each type. | ||||
| <t>Implementations are allowed to limit the allowed size of different | ||||
| structures, subject to the minimums defined for each type. When a | structures, subject to the minimums defined for each type. When a | |||
| structure exceeds an implementation limit, that structure fails parsing | structure exceeds an implementation limit, that structure fails parsing | |||
| or serialization.</t> | or serialization.</t> | |||
| </section> | </section> | |||
| <section numbered="false" anchor="acknowledgements"> | ||||
| <section numbered="false" anchor="acknowledgements" toc="default"> | ||||
| <name>Acknowledgements</name> | <name>Acknowledgements</name> | |||
| <t>Many thanks to <contact fullname="Matthew Kerwin"/> for his detailed fe edback and careful | <t>Many thanks to <contact fullname="Matthew Kerwin"/> for his detailed fe edback and careful | |||
| consideration during the development of this specification.</t> | consideration during the development of this specification.</t> | |||
| <t>Thanks also to <contact fullname="Ian Clelland"/>, <contact | <t>Thanks also to <contact fullname="Ian Clelland"/>, <contact fullname="R | |||
| fullname="Roy Fielding"/>, <contact fullname="Anne van Kesteren"/>, | oy Fielding"/>, <contact fullname="Anne van Kesteren"/>, | |||
| <contact fullname="Kazuho Oku"/>, <contact fullname="Evert Pot"/>, | <contact fullname="Kazuho Oku"/>, <contact fullname="Evert Pot"/>, | |||
| <contact fullname="Julian Reschke"/>, <contact fullname="Martin | <contact fullname="Julian Reschke"/>, <contact fullname="Martin Thom | |||
| Thomson"/>, <contact fullname="Mike West"/>, and <contact | son"/>, <contact fullname="Mike West"/>, and <contact fullname="Jeffrey Yasskin" | |||
| fullname="Jeffrey Yasskin"/> for their contributions.</t> | /> for their contributions.</t> | |||
| </section> | </section> | |||
| </back> | </back> | |||
| <!-- [rfced] Throughout the text, the following terminology appears to | ||||
| be used inconsistently (a few examples are included below; see | ||||
| the text for more examples). Please review these occurrences and | ||||
| let us know if/how they may be made consistent. | ||||
| Bare Item vs. bare Item vs. bare item | ||||
| Integer vs. integer | ||||
| If input_item is an Integer, | ||||
| If input_integer is not an integer in the range | ||||
| Parameter vs. parameter | ||||
| If parameters already contains | ||||
| or a parameter on an Integer that | ||||
| within the scope the Parameters | ||||
| Parameter (Section 3.1.2) values | ||||
| and Parameter keys cannot | ||||
| and support parameter keys with | ||||
| Parameterized vs. parameterized | ||||
| can be parameterized with | ||||
| both of which can be Parameterized | ||||
| Structured Field vs. structured field | ||||
| An extension to a structured field can | ||||
| a major goal for Structured Fields is | ||||
| </rfc> | </rfc> | |||
| End of changes. 283 change blocks. | ||||
| 649 lines changed or deleted | 427 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/ | ||||