draft-ietf-httpbis-header-structure-19.txt | draft-ietf-httpbis-header-structure-latest.txt | |||
---|---|---|---|---|
HTTP Working Group M. Nottingham | HTTP Working Group M. Nottingham | |||
Internet-Draft Fastly | Internet-Draft Fastly | |||
Intended status: Standards Track P-H. Kamp | Intended status: Standards Track P. Kamp | |||
Expires: December 5, 2020 The Varnish Cache Project | Expires: February 23, 2025 The Varnish Cache Project | |||
June 3, 2020 | August 22, 2024 | |||
Structured Field Values for HTTP | Structured Field Values for HTTP | |||
draft-ietf-httpbis-header-structure-19 | draft-ietf-httpbis-header-structure-latest | |||
Abstract | Abstract | |||
This document describes a set of data types and associated algorithms | This document describes a set of data types and associated algorithms | |||
that are intended to make it easier and safer to define and handle | that are intended to make it easier and safer to define and handle | |||
HTTP header and trailer fields, known as "Structured Fields", | HTTP header and trailer fields, known as "Structured Fields", | |||
"Structured Headers", or "Structured Trailers". It is intended for | "Structured Headers", or "Structured Trailers". It is intended for | |||
use by specifications of new HTTP fields that wish to use a common | use by specifications of new HTTP fields that wish to use a common | |||
syntax that is more restrictive than traditional HTTP field values. | syntax that is more restrictive than traditional HTTP field values. | |||
skipping to change at page 2, line 10 ¶ | skipping to change at page 2, line 10 ¶ | |||
Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
This Internet-Draft will expire on December 5, 2020. | This Internet-Draft will expire on February 23, 2025. | |||
Copyright Notice | Copyright Notice | |||
Copyright (c) 2020 IETF Trust and the persons identified as the | Copyright (c) 2024 IETF Trust and the persons identified as the | |||
document authors. All rights reserved. | document authors. All rights reserved. | |||
This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
(https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
publication of this document. Please review these documents | publication of this document. Please review these documents | |||
carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
described in the Simplified BSD License. | described in the Simplified BSD License. | |||
Table of Contents | Table of Contents | |||
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 | |||
1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 | 1.1. Intentionally Strict Processing . . . . . . . . . . . . . 4 | |||
1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 | 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 5 | |||
2. Defining New Structured Fields . . . . . . . . . . . . . . . 5 | 2. Defining New Structured Fields . . . . . . . . . . . . . . . 5 | |||
3. Structured Data Types . . . . . . . . . . . . . . . . . . . . 8 | 3. Structured Data Types . . . . . . . . . . . . . . . . . . . . 8 | |||
3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 9 | 3.1. Lists . . . . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
3.1.1. Inner Lists . . . . . . . . . . . . . . . . . . . . . 9 | 3.1.1. Inner Lists . . . . . . . . . . . . . . . . . . . . . 9 | |||
3.1.2. Parameters . . . . . . . . . . . . . . . . . . . . . 10 | 3.1.2. Parameters . . . . . . . . . . . . . . . . . . . . . 10 | |||
3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 11 | 3.2. Dictionaries . . . . . . . . . . . . . . . . . . . . . . 11 | |||
3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 12 | 3.3. Items . . . . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
3.3.1. Integers . . . . . . . . . . . . . . . . . . . . . . 13 | 3.3.1. Integers . . . . . . . . . . . . . . . . . . . . . . 13 | |||
3.3.2. Decimals . . . . . . . . . . . . . . . . . . . . . . 13 | 3.3.2. Decimals . . . . . . . . . . . . . . . . . . . . . . 13 | |||
3.3.3. Strings . . . . . . . . . . . . . . . . . . . . . . . 14 | 3.3.3. Strings . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
3.3.4. Tokens . . . . . . . . . . . . . . . . . . . . . . . 15 | 3.3.4. Tokens . . . . . . . . . . . . . . . . . . . . . . . 14 | |||
3.3.5. Byte Sequences . . . . . . . . . . . . . . . . . . . 15 | 3.3.5. Byte Sequences . . . . . . . . . . . . . . . . . . . 15 | |||
3.3.6. Booleans . . . . . . . . . . . . . . . . . . . . . . 15 | 3.3.6. Booleans . . . . . . . . . . . . . . . . . . . . . . 15 | |||
4. Working With Structured Fields in HTTP . . . . . . . . . . . 16 | 4. Working with Structured Fields in HTTP . . . . . . . . . . . 16 | |||
4.1. Serializing Structured Fields . . . . . . . . . . . . . . 16 | 4.1. Serializing Structured Fields . . . . . . . . . . . . . . 16 | |||
4.1.1. Serializing a List . . . . . . . . . . . . . . . . . 16 | 4.1.1. Serializing a List . . . . . . . . . . . . . . . . . 16 | |||
4.1.2. Serializing a Dictionary . . . . . . . . . . . . . . 18 | 4.1.2. Serializing a Dictionary . . . . . . . . . . . . . . 18 | |||
4.1.3. Serializing an Item . . . . . . . . . . . . . . . . . 19 | 4.1.3. Serializing an Item . . . . . . . . . . . . . . . . . 19 | |||
4.1.4. Serializing an Integer . . . . . . . . . . . . . . . 20 | 4.1.4. Serializing an Integer . . . . . . . . . . . . . . . 20 | |||
4.1.5. Serializing a Decimal . . . . . . . . . . . . . . . . 20 | 4.1.5. Serializing a Decimal . . . . . . . . . . . . . . . . 20 | |||
4.1.6. Serializing a String . . . . . . . . . . . . . . . . 21 | 4.1.6. Serializing a String . . . . . . . . . . . . . . . . 21 | |||
4.1.7. Serializing a Token . . . . . . . . . . . . . . . . . 22 | 4.1.7. Serializing a Token . . . . . . . . . . . . . . . . . 21 | |||
4.1.8. Serializing a Byte Sequence . . . . . . . . . . . . . 22 | 4.1.8. Serializing a Byte Sequence . . . . . . . . . . . . . 22 | |||
4.1.9. Serializing a Boolean . . . . . . . . . . . . . . . . 22 | 4.1.9. Serializing a Boolean . . . . . . . . . . . . . . . . 22 | |||
4.2. Parsing Structured Fields . . . . . . . . . . . . . . . . 23 | 4.2. Parsing Structured Fields . . . . . . . . . . . . . . . . 23 | |||
4.2.1. Parsing a List . . . . . . . . . . . . . . . . . . . 24 | 4.2.1. Parsing a List . . . . . . . . . . . . . . . . . . . 24 | |||
4.2.2. Parsing a Dictionary . . . . . . . . . . . . . . . . 26 | 4.2.2. Parsing a Dictionary . . . . . . . . . . . . . . . . 26 | |||
4.2.3. Parsing an Item . . . . . . . . . . . . . . . . . . . 27 | 4.2.3. Parsing an Item . . . . . . . . . . . . . . . . . . . 27 | |||
4.2.4. Parsing an Integer or Decimal . . . . . . . . . . . . 29 | 4.2.4. Parsing an Integer or Decimal . . . . . . . . . . . . 29 | |||
4.2.5. Parsing a String . . . . . . . . . . . . . . . . . . 30 | 4.2.5. Parsing a String . . . . . . . . . . . . . . . . . . 30 | |||
4.2.6. Parsing a Token . . . . . . . . . . . . . . . . . . . 31 | 4.2.6. Parsing a Token . . . . . . . . . . . . . . . . . . . 31 | |||
4.2.7. Parsing a Byte Sequence . . . . . . . . . . . . . . . 32 | 4.2.7. Parsing a Byte Sequence . . . . . . . . . . . . . . . 32 | |||
4.2.8. Parsing a Boolean . . . . . . . . . . . . . . . . . . 33 | 4.2.8. Parsing a Boolean . . . . . . . . . . . . . . . . . . 33 | |||
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33 | 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33 | |||
6. Security Considerations . . . . . . . . . . . . . . . . . . . 33 | 6. Security Considerations . . . . . . . . . . . . . . . . . . . 33 | |||
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 33 | 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 33 | |||
7.1. Normative References . . . . . . . . . . . . . . . . . . 33 | 7.1. Normative References . . . . . . . . . . . . . . . . . . 33 | |||
7.2. Informative References . . . . . . . . . . . . . . . . . 34 | 7.2. Informative References . . . . . . . . . . . . . . . . . 34 | |||
7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 35 | 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 35 | |||
Appendix A. Frequently Asked Questions . . . . . . . . . . . . . 35 | Appendix A. Frequently Asked Questions . . . . . . . . . . . . . 35 | |||
A.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 35 | A.1. Why Not JSON? . . . . . . . . . . . . . . . . . . . . . . 35 | |||
Appendix B. Implementation Notes . . . . . . . . . . . . . . . . 36 | Appendix B. Implementation Notes . . . . . . . . . . . . . . . . 36 | |||
Appendix C. Changes . . . . . . . . . . . . . . . . . . . . . . 36 | Appendix C. Changes . . . . . . . . . . . . . . . . . . . . . . 36 | |||
C.1. Since draft-ietf-httpbis-header-structure-18 . . . . . . 37 | C.1. Since draft-ietf-httpbis-header-structure-18 . . . . . . 37 | |||
C.2. Since draft-ietf-httpbis-header-structure-17 . . . . . . 37 | C.2. Since draft-ietf-httpbis-header-structure-17 . . . . . . 37 | |||
C.3. Since draft-ietf-httpbis-header-structure-16 . . . . . . 37 | C.3. Since draft-ietf-httpbis-header-structure-16 . . . . . . 37 | |||
C.4. Since draft-ietf-httpbis-header-structure-15 . . . . . . 37 | C.4. Since draft-ietf-httpbis-header-structure-15 . . . . . . 37 | |||
C.5. Since draft-ietf-httpbis-header-structure-14 . . . . . . 38 | C.5. Since draft-ietf-httpbis-header-structure-14 . . . . . . 38 | |||
C.6. Since draft-ietf-httpbis-header-structure-13 . . . . . . 38 | C.6. Since draft-ietf-httpbis-header-structure-13 . . . . . . 38 | |||
C.7. Since draft-ietf-httpbis-header-structure-12 . . . . . . 39 | C.7. Since draft-ietf-httpbis-header-structure-12 . . . . . . 39 | |||
C.8. Since draft-ietf-httpbis-header-structure-11 . . . . . . 39 | C.8. Since draft-ietf-httpbis-header-structure-11 . . . . . . 39 | |||
skipping to change at page 4, line 9 ¶ | skipping to change at page 4, line 9 ¶ | |||
C.17. Since draft-ietf-httpbis-header-structure-02 . . . . . . 41 | C.17. Since draft-ietf-httpbis-header-structure-02 . . . . . . 41 | |||
C.18. Since draft-ietf-httpbis-header-structure-01 . . . . . . 42 | C.18. Since draft-ietf-httpbis-header-structure-01 . . . . . . 42 | |||
C.19. Since draft-ietf-httpbis-header-structure-00 . . . . . . 42 | C.19. Since draft-ietf-httpbis-header-structure-00 . . . . . . 42 | |||
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 42 | Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 42 | |||
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42 | Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42 | |||
1. Introduction | 1. Introduction | |||
Specifying the syntax of new HTTP header (and trailer) fields is an | Specifying the syntax of new HTTP header (and trailer) fields is an | |||
onerous task; even with the guidance in Section 8.3.1 of [RFC7231], | onerous task; even with the guidance in Section 8.3.1 of [RFC7231], | |||
there are many decisions - and pitfalls - for a prospective HTTP | there are many decisions -- and pitfalls -- for a prospective HTTP | |||
field author. | field author. | |||
Once a field is defined, bespoke parsers and serializers often need | Once a field is defined, bespoke parsers and serializers often need | |||
to be written, because each field value has slightly different | to be written, because each field value has a slightly different | |||
handling of what looks like common syntax. | handling of what looks like common syntax. | |||
This document introduces a set of common data structures for use in | This document introduces a set of common data structures for use in | |||
definitions of new HTTP 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 | particular, it defines a generic, abstract model for them, along with | |||
a concrete serialization for expressing that model in HTTP [RFC7230] | a concrete serialization for expressing that model in HTTP [RFC7230] | |||
header and trailer fields. | header and trailer fields. | |||
A HTTP field that is defined as a "Structured Header" or "Structured | An HTTP field that is defined as a "Structured Header" or "Structured | |||
Trailer" (if the field can be either, it is a "Structured Field") | Trailer" (if the field can be either, it is a "Structured Field") | |||
uses the types defined in this specification to define its syntax and | uses the types defined in this specification to define its syntax and | |||
basic handling rules, thereby simplifying both its definition by | basic handling rules, thereby simplifying both its definition by | |||
specification writers and handling by implementations. | specification writers and handling by implementations. | |||
Additionally, future versions of HTTP can define alternative | 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. | being redefined. | |||
skipping to change at page 4, line 51 ¶ | skipping to change at page 4, line 51 ¶ | |||
Those abstract types can be serialized into and parsed from HTTP | Those abstract types can be serialized into and parsed from HTTP | |||
field values using the algorithms described in Section 4. | field values using the algorithms described in Section 4. | |||
1.1. Intentionally Strict Processing | 1.1. Intentionally Strict Processing | |||
This specification intentionally defines strict parsing and | 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. | handling defined is to fail the operation altogether. | |||
It is designed to encourage faithful implementation and therefore | It is designed to encourage faithful implementation and good | |||
good interoperability. Therefore, an implementation that tried to be | 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. | implement similar (but likely subtly different) workarounds. | |||
In other words, strict processing is an intentional feature of this | 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. | security issues that might otherwise result. | |||
Note that as a result of this strictness, if a field is appended to | 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. | entire field value to fail parsing. | |||
1.2. Notational Conventions | 1.2. Notational Conventions | |||
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and | |||
"OPTIONAL" in this document are to be interpreted as described in BCP | "OPTIONAL" in this document are to be interpreted as described in BCP | |||
14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
capitals, as shown here. | capitals, as shown here. | |||
This document uses algorithms to specify parsing and serialization | This document uses algorithms to specify parsing and serialization | |||
behaviors, and the Augmented Backus-Naur Form (ABNF) notation of | behaviors and the Augmented Backus-Naur Form (ABNF) notation of | |||
[RFC5234] to illustrate expected syntax in HTTP header fields. In | [RFC5234] to illustrate expected syntax in HTTP header fields. In | |||
doing so, it uses the VCHAR, SP, DIGIT, ALPHA and DQUOTE rules from | doing so, it uses the VCHAR, SP, DIGIT, ALPHA, and DQUOTE rules from | |||
[RFC5234]. It also includes the tchar and OWS rules from [RFC7230]. | [RFC5234]. It also includes the tchar and OWS rules from [RFC7230]. | |||
When parsing from HTTP fields, implementations MUST have behavior | When parsing from HTTP fields, implementations MUST have 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. | algorithms take precedence. | |||
For serialization to HTTP fields, the ABNF illustrates their expected | For serialization to HTTP fields, the ABNF illustrates their expected | |||
wire representations, and the algorithms define the recommended way | wire representations, and the algorithms define the recommended way | |||
to produce them. Implementations MAY vary from the specified | to produce them. Implementations MAY vary from the specified | |||
behavior so long as the output is still correctly handled by the | behavior so long as the output is still correctly handled by the | |||
parsing algorithm. | parsing algorithm described in Section 4.2. | |||
2. Defining New Structured Fields | 2. Defining New Structured Fields | |||
To specify a HTTP field as a Structured Field, its authors needs to: | To specify an HTTP field as a Structured Field, its authors need to: | |||
o Normatively reference this specification. Recipients and | o 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. | document are in effect. | |||
o Identify whether the field is a Structured Header (i.e., it can | o Identify whether the field is a Structured Header (i.e., it can | |||
only be used in the header section - the common case), a | only be used in the header section -- the common case), a | |||
Structured Trailer (only in the trailer section), or a Structured | Structured Trailer (only in the trailer section), or a Structured | |||
Field (both). | Field (both). | |||
o Specify the type of the field value; either List (Section 3.1), | o Specify the type of the field value; either List (Section 3.1), | |||
Dictionary (Section 3.2), or Item (Section 3.3). | Dictionary (Section 3.2), or Item (Section 3.3). | |||
o Define the semantics of the field value. | o Define the semantics of the field value. | |||
o Specify any additional constraints upon the field value, as well | o Specify any additional constraints upon the field value, as well | |||
as the consequences when those constraints are violated. | as the consequences when those constraints are violated. | |||
Typically, this means that a field definition will specify the top- | Typically, this means that a field definition will specify the top- | |||
level type - List, Dictionary or Item - and then define its allowable | level type -- List, Dictionary, or Item -- and then define its | |||
types, and constraints upon them. For example, a header defined as a | allowable types and constraints upon them. For example, a header | |||
List might have all Integer members, or a mix of types; a header | defined as a List might have all Integer members, or a mix of types; | |||
defined as an Item might allow only Strings, and additionally only | a header defined as an Item might allow only Strings, and | |||
strings beginning with the letter "Q", or strings in lowercase. | additionally only strings beginning with the letter "Q", or strings | |||
Likewise, Inner Lists (Section 3.1.1) are only valid when a field | in lowercase. Likewise, Inner Lists (Section 3.1.1) are only valid | |||
definition explicitly allows them. | when a field definition explicitly allows them. | |||
When parsing fails, the entire field is ignored (see Section 4.2); in | When parsing fails, the entire field is ignored (see Section 4.2); in | |||
most situations, violating field-specific constraints should have the | most situations, violating field-specific constraints should have the | |||
same effect. Thus, if a header is defined as an Item and required to | same effect. Thus, if a header is defined as an Item and required to | |||
be an Integer, but a String is received, the field will by default be | be an Integer, but a String is received, the field will by default be | |||
ignored. If the field requires different error handling, this should | ignored. If the field requires different error handling, this should | |||
be explicitly specified. | be explicitly specified. | |||
Both Items and Inner Lists allow parameters as an extensibility | Both Items and Inner Lists allow parameters as an extensibility | |||
mechanism; this means that values can later be extended to | mechanism; this means that values can later be extended to | |||
accommodate more information, if need be. To preserve forward | accommodate more information, if need be. To preserve forward | |||
compatibility, field specifications are discouraged from defining the | compatibility, field specifications are discouraged from defining the | |||
presence of an unrecognized Parameter as an error condition. | presence of an unrecognized parameter as an error condition. | |||
To further assure that this extensibility is available in the future, | 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 | senders. A specification could stipulate that all parameters that | |||
fit a defined pattern are reserved for this use and then encourage | fit a defined pattern are reserved for this use and then encourage | |||
them to be sent on some portion of requests. This helps to | them to be sent on some portion of requests. This helps to | |||
discourage recipients from writing a parser that does not account for | discourage recipients from writing a parser that does not account for | |||
Parameters. | Parameters. | |||
Specifications that use Dictionaries can also allow for forward | Specifications that use Dictionaries can also allow for forward | |||
compatibility by requiring that the presence of - as well as value | compatibility by requiring that the presence of -- as well as value | |||
and type associated with - unknown members be ignored. Later | and type associated with -- unknown members be ignored. Subsequent | |||
specifications can then add additional members, specifying | specifications can then add additional members, specifying | |||
constraints on them as appropriate. | constraints on them as appropriate. | |||
An extension to a structured field can then require that an entire | An extension to a Structured Field can then require that an entire | |||
field value be ignored by a recipient that understands the extension | field value be ignored by a recipient that understands the extension | |||
if constraints on the value it defines are not met. | if constraints on the value it defines are not met. | |||
A field definition cannot relax the requirements of this | 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 | software; they can only add additional constraints (for example, on | |||
the numeric range of Integers and Decimals, the format of Strings and | the numeric range of Integers and Decimals, the format of Strings and | |||
Tokens, the types allowed in a Dictionary's values, or the number of | 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. | specification for the entire field value, not a portion thereof. | |||
This specification defines minimums for the length or number of | This specification defines minimums for the length or number of | |||
various structures supported by 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 | fields, the total number of fields, and/or the size of the entire | |||
header or trailer section. | header or trailer section. | |||
Specifications can refer to a field name as a "structured header | 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 | appropriate. Likewise, they can refer its field value as a | |||
"structured header value", "structured trailer value" or "structured | "structured header value", "structured trailer value", or "structured | |||
field value" as necessary. Field definitions are encouraged to use | field value" as necessary. Field definitions are encouraged to use | |||
the ABNF rules beginning with "sf-" defined in this specification; | the ABNF rules beginning with "sf-" defined in this specification; | |||
other rules in this specification are not intended for their use. | other rules in this specification are not intended to be used in | |||
field definitions. | ||||
For example, a fictitious Foo-Example header field might be specified | For example, a fictitious Foo-Example header field might be specified | |||
as: | as: | |||
--8<-- | 42. Foo-Example Header | |||
42. Foo-Example Header | ||||
The Foo-Example HTTP header field conveys information about how | The Foo-Example HTTP header field conveys information about how | |||
much Foo the message has. | much Foo the message has. | |||
Foo-Example is a Item Structured Header [RFCxxxx]. Its value MUST be | Foo-Example is an Item Structured Header [RFC8941]. Its value | |||
an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is: | MUST be an Integer (Section 3.3.1 of [RFC8941]). Its ABNF is: | |||
Foo-Example = sf-integer | Foo-Example = sf-integer | |||
Its value indicates the amount of Foo in the message, and it MUST | ||||
be between 0 and 10, inclusive; other values MUST cause the entire | ||||
header field to be ignored. | ||||
Its value indicates the amount of Foo in the message, and MUST | The following parameter is defined: | |||
be between 0 and 10, inclusive; other values MUST cause | ||||
the entire header field to be ignored. | ||||
The following parameters are defined: | * A parameter whose key 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 for the | |||
(Section Y.Y of [RFCxxxx]), conveying the Foo URL | message. See below for processing requirements. | |||
for the message. See below for processing requirements. | ||||
"foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | "foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If | |||
its value is not a valid URI-reference, the entire header field | its value is not a valid URI-reference, the entire header field | |||
MUST be ignored. If its value is a relative reference (Section 4.2 | MUST be ignored. If its value is a relative reference | |||
of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before | (Section 4.2 of [RFC3986]), it MUST be resolved (Section 5 of | |||
being used. | [RFC3986]) before being used. | |||
For example: | For example: | |||
Foo-Example: 2; foourl="https://foo.example.com/" | Foo-Example: 2; foourl="https://foo.example.com/" | |||
-->8-- | ||||
3. Structured Data Types | 3. Structured Data Types | |||
This section defines the abstract types for Structured Fields. The | This section defines the abstract types for Structured Fields. The | |||
ABNF provided represents the on-wire format in HTTP field values. | ABNF provided represents the on-wire format in HTTP field values. | |||
In summary: | In summary: | |||
o There are three top-level types that a HTTP field can be defined | o There are three top-level types that an HTTP field can be defined | |||
as: Lists, Dictionaries, and Items. | as: Lists, Dictionaries, and Items. | |||
o Lists and Dictionaries are containers; their members can be Items | o Lists and Dictionaries are containers; their members can be Items | |||
or Inner Lists (which are themselves arrays of Items). | or Inner Lists (which are themselves arrays of Items). | |||
o Both Items and Inner Lists can be parameterized with key/value | o Both Items and Inner Lists can be Parameterized with key/value | |||
pairs. | pairs. | |||
3.1. Lists | 3.1. Lists | |||
Lists are arrays of zero or more members, each of which can be an | Lists are arrays of zero or more members, each of which can be an | |||
Item (Section 3.3) or an Inner List (Section 3.1.1), both of which | Item (Section 3.3) or an Inner List (Section 3.1.1), both of which | |||
can be Parameterized (Section 3.1.2). | can be Parameterized (Section 3.1.2). | |||
The ABNF for Lists in HTTP fields is: | The ABNF for Lists in HTTP fields is: | |||
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 | |||
Each member is separated by a comma and optional whitespace. For | 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 Tokens could | |||
look like: | look like: | |||
Example-StrList: "foo", "bar", "It was the best of times." | Example-List: sugar, tea, rum | |||
An empty List is denoted by not serializing the field at all. This | An empty List is denoted by not serializing the field at all. This | |||
implies that fields defined as Lists have a default empty value. | implies that fields defined as Lists have a default empty value. | |||
Note that Lists can have their members split across multiple lines | Note that Lists can have their members split across multiple lines of | |||
inside a header or trailer section, as per Section 3.2.2 of | the same header or trailer section, as per Section 3.2.2 of | |||
[RFC7230]; for example, the following are equivalent: | [RFC7230]; for example, the following are equivalent: | |||
Example-Hdr: foo, bar | Example-List: sugar, tea, rum | |||
and | and | |||
Example-Hdr: foo | Example-List: sugar, tea | |||
Example-Hdr: bar | Example-List: rum | |||
However, individual members of a List cannot be safely split between | However, individual members of a List cannot be safely split between | |||
across lines; see Section 4.2 for details. | lines; see Section 4.2 for details. | |||
Parsers MUST support Lists containing at least 1024 members. Field | Parsers MUST support Lists containing at least 1024 members. Field | |||
specifications can constrain the types and cardinality of individual | specifications can constrain the types and cardinality of individual | |||
List values as they require. | List values as they require. | |||
3.1.1. Inner Lists | 3.1.1. Inner Lists | |||
An Inner List is an array of zero or more Items (Section 3.3). Both | An Inner List is an array of zero or more Items (Section 3.3). Both | |||
the individual Items and the Inner List itself can be Parameterized | the individual Items and the Inner List itself can be Parameterized | |||
(Section 3.1.2). | (Section 3.1.2). | |||
The ABNF for Inner Lists is: | The ABNF for Inner Lists is: | |||
inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" | |||
parameters | parameters | |||
Inner Lists are denoted by surrounding parenthesis, and have their | Inner Lists are denoted by surrounding parenthesis, and their values | |||
values delimited by one or more spaces. A field whose value is | are delimited by one or more spaces. A field whose value is defined | |||
defined as a List of Inner Lists of Strings could look like: | as a List of Inner Lists of Strings could look like: | |||
Example-StrListList: ("foo" "bar"), ("baz"), ("bat" "one"), () | Example-List: ("foo" "bar"), ("baz"), ("bat" "one"), () | |||
Note that the last member in this example is an empty Inner List. | Note that the last member in this example is an empty Inner List. | |||
A header field whose value is defined as a List of Inner Lists with | A header field whose value is defined as a List of Inner Lists with | |||
Parameters at both levels could look like: | Parameters at both levels could look like: | |||
Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | Example-List: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 | |||
Parsers MUST support Inner Lists containing at least 256 members. | Parsers MUST support Inner Lists containing at least 256 members. | |||
Field specifications can constrain the types and cardinality of | Field specifications can constrain the types and cardinality of | |||
individual Inner List members as they require. | individual Inner List members as they require. | |||
3.1.2. Parameters | 3.1.2. Parameters | |||
Parameters are an ordered map of key-value pairs that are associated | Parameters are an ordered map of key-value pairs that are associated | |||
with an Item (Section 3.3) or Inner List (Section 3.1.1). The keys | with an Item (Section 3.3) or Inner List (Section 3.1.1). The keys | |||
are unique within the scope the Parameters they occur within, and the | are unique within the scope of the Parameters they occur within, and | |||
values are bare items (i.e., they themselves cannot be parameterized; | the values are bare items (i.e., they themselves cannot be | |||
see Section 3.3). | parameterized; see Section 3.3). | |||
Implementations MUST provide access to Parameters both by index and | ||||
by key. Specifications MAY use either means of accessing them. | ||||
The ABNF for Parameters is: | The ABNF for Parameters is: | |||
parameters = *( ";" *SP parameter ) | parameters = *( ";" *SP parameter ) | |||
parameter = param-name [ "=" param-value ] | parameter = param-key [ "=" param-value ] | |||
param-name = key | param-key = key | |||
key = ( lcalpha / "*" ) | key = ( lcalpha / "*" ) | |||
*( lcalpha / DIGIT / "_" / "-" / "." / "*" ) | *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) | |||
lcalpha = %x61-7A ; a-z | lcalpha = %x61-7A ; a-z | |||
param-value = bare-item | param-value = bare-item | |||
Note that Parameters are ordered as serialized, and Parameter keys | Note that parameters are ordered as serialized, and parameter keys | |||
cannot contain uppercase letters. A parameter is separated from its | cannot contain uppercase letters. A parameter is separated from its | |||
Item or Inner List and other parameters by a semicolon. For example: | Item or Inner List and other parameters by a semicolon. For example: | |||
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 | |||
Parameters whose value is Boolean (see Section 3.3.6) true MUST omit | Parameters whose value is Boolean (see Section 3.3.6) true MUST omit | |||
that value when serialized. For example, the "a" parameter here is | that value when serialized. For example, the "a" parameter here is | |||
true, while the "b" parameter is false: | true, while the "b" parameter is false: | |||
Example-Int: 1; a; b=?0 | Example-Integer: 1; a; b=?0 | |||
Note that this requirement is only on serialization; parsers are | 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. | a parameter. | |||
Parsers MUST support at least 256 parameters on an Item or Inner | Parsers MUST support at least 256 parameters on an Item or Inner | |||
List, and support parameter keys with at least 64 characters. 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. | well as their values' types as required. | |||
3.2. Dictionaries | 3.2. Dictionaries | |||
Dictionaries are ordered maps of name-value pairs, where the names | Dictionaries are ordered maps of key-value pairs, where the keys are | |||
are short textual strings and the values are Items (Section 3.3) or | short textual strings and the values are Items (Section 3.3) or | |||
arrays of Items, both of which can be Parameterized (Section 3.1.2). | arrays of Items, both of which can be Parameterized (Section 3.1.2). | |||
There can be zero or more members, and their names are unique in the | There can be zero or more members, and their keys are unique in the | |||
scope of the Dictionary they occur within. | scope of the Dictionary they occur within. | |||
Implementations MUST provide access to Dictionaries both by index and | Implementations MUST provide access to Dictionaries both by index and | |||
by name. Specifications MAY use either means of accessing the | by key. Specifications MAY use either means of accessing the | |||
members. | members. | |||
The ABNF for Dictionaries is: | The ABNF for Dictionaries is: | |||
sf-dictionary = dict-member *( OWS "," OWS dict-member ) | sf-dictionary = dict-member *( OWS "," OWS dict-member ) | |||
dict-member = member-name [ "=" member-value ] | dict-member = member-key ( parameters / ( "=" member-value )) | |||
member-name = key | member-key = key | |||
member-value = sf-item / inner-list | member-value = sf-item / inner-list | |||
Members are ordered as serialized, and separated by a comma with | Members are ordered as serialized and separated by a comma with | |||
optional whitespace. Member names cannot contain uppercase | optional whitespace. Member keys cannot contain uppercase | |||
characters. Names and values are separated by "=" (without | characters. Keys and values are separated by "=" (without | |||
whitespace). For example: | whitespace). For example: | |||
Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=: | |||
Note that in this example, the final "=" is due to the inclusion of a | Note that in this example, the final "=" is due to the inclusion of a | |||
Byte Sequence; see Section 3.3.5. | Byte Sequence; see Section 3.3.5. | |||
Members whose value is Boolean (see Section 3.3.6) true MUST omit | Members whose value is Boolean (see Section 3.3.6) true MUST omit | |||
that value when serialized. For example, here both "b" and "c" are | that value when serialized. For example, here both "b" and "c" are | |||
true: | true: | |||
Example-Dict: a=?0, b, c; foo=bar | Example-Dict: a=?0, b, c; foo=bar | |||
Note that this requirement is only on serialization; parsers are | 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. | appears in Dictionary values. | |||
A Dictionary with a member whose value is an Inner List of Tokens: | A Dictionary with a member whose value is an Inner List of Tokens: | |||
Example-DictList: rating=1.5, feelings=(joy sadness) | Example-Dict: rating=1.5, feelings=(joy sadness) | |||
A Dictionary with a mix of Items and Inner Lists, some with | A Dictionary with a mix of Items and Inner Lists, some with | |||
Parameters: | parameters: | |||
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 | |||
As with lists, an empty Dictionary is represented by omitting the | As with Lists, an empty Dictionary is represented by omitting the | |||
entire field. This implies that fields defined as Dictionaries have | entire field. This implies that fields defined as Dictionaries have | |||
a default empty value. | a default empty value. | |||
Typically, a field specification will define the semantics of | 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 keys, as well as whether their presence is required or | |||
optional. Recipients MUST ignore names that are undefined or | optional. Recipients MUST ignore members whose keys that are | |||
unknown, unless the field's specification specifically disallows | undefined or unknown, unless the field's specification specifically | |||
them. | disallows them. | |||
Note that Dictionaries can have their members split across multiple | Note that Dictionaries can have their members split across multiple | |||
lines inside a header or trailer section; for example, the following | lines of the same header or trailer section; for example, the | |||
are equivalent: | following are equivalent: | |||
Example-Hdr: foo=1, bar=2 | Example-Dict: foo=1, bar=2 | |||
and | and | |||
Example-Hdr: foo=1 | Example-Dict: foo=1 | |||
Example-Hdr: bar=2 | Example-Dict: bar=2 | |||
However, individual members of a Dictionary cannot be safely split | However, individual members of a Dictionary cannot be safely split | |||
between lines; see Section 4.2 for details. | between lines; see Section 4.2 for details. | |||
Parsers MUST support Dictionaries containing at least 1024 name/value | Parsers MUST support Dictionaries containing at least 1024 key/value | |||
pairs, and names with at least 64 characters. Field specifications | pairs and keys with at least 64 characters. Field specifications can | |||
can constrain the order of individual Dictionary members, as well as | constrain the order of individual Dictionary members, as well as | |||
their values' types as required. | their values' types as required. | |||
3.3. Items | 3.3. Items | |||
An Item can be a Integer (Section 3.3.1), Decimal (Section 3.3.2), | An Item can be an Integer (Section 3.3.1), a Decimal (Section 3.3.2), | |||
String (Section 3.3.3), Token (Section 3.3.4), Byte Sequence | a String (Section 3.3.3), a Token (Section 3.3.4), a Byte Sequence | |||
(Section 3.3.5), or Boolean (Section 3.3.6). It can have associated | (Section 3.3.5), or a Boolean (Section 3.3.6). It can have | |||
Parameters (Section 3.1.2). | associated parameters (Section 3.1.2). | |||
The ABNF for Items is: | The ABNF for Items is: | |||
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 | |||
For example, a header field that is defined to be an Item that is an | For example, a header field that is defined to be an Item that is an | |||
Integer might look like: | Integer might look like: | |||
Example-IntItemHeader: 5 | Example-Integer: 5 | |||
or with Parameters: | or with parameters: | |||
Example-IntItem: 5; foo=bar | Example-Integer: 5; foo=bar | |||
3.3.1. Integers | 3.3.1. Integers | |||
Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 | Integers have a range of -999,999,999,999,999 to 999,999,999,999,999 | |||
inclusive (i.e., up to fifteen digits, signed), for IEEE 754 | inclusive (i.e., up to fifteen digits, signed), for IEEE 754 | |||
compatibility ([IEEE754]). | compatibility [IEEE754]. | |||
The ABNF for Integers is: | The ABNF for Integers is: | |||
sf-integer = ["-"] 1*15DIGIT | sf-integer = ["-"] 1*15DIGIT | |||
For example: | For example: | |||
Example-Integer: 42 | Example-Integer: 42 | |||
Integers larger than 15 digits can be supported in a variety of ways; | Integers larger than 15 digits can be supported in a variety of ways; | |||
for example, by using a String (Section 3.3.3), Byte Sequence | for example, by using a String (Section 3.3.3), a Byte Sequence | |||
(Section 3.3.5), or a parameter on an Integer that acts as a scaling | (Section 3.3.5), or a parameter on an Integer that acts as a scaling | |||
factor. | factor. | |||
While it is possible to serialise Integers with leading zeros (e.g., | While it is possible to serialize Integers with leading zeros (e.g., | |||
"0002", "-01") and signed zero ("-0"), these distinctions may not be | "0002", "-01") and signed zero ("-0"), these distinctions may not be | |||
preserved by implementations. | preserved by implementations. | |||
Note that commas in Integers are used in this section's prose only | Note that commas in Integers are used in this section's prose only | |||
for readability; they are not valid in the wire format. | for readability; they are not valid in the wire format. | |||
3.3.2. Decimals | 3.3.2. Decimals | |||
Decimals are numbers with an integer and a fractional component. The | Decimals are numbers with an integer and a fractional component. The | |||
integer component has at most 12 digits; the fractional component has | integer component has at most 12 digits; the fractional component has | |||
skipping to change at page 14, line 4 ¶ | skipping to change at page 13, line 46 ¶ | |||
3.3.2. Decimals | 3.3.2. Decimals | |||
Decimals are numbers with an integer and a fractional component. The | Decimals are numbers with an integer and a fractional component. The | |||
integer component has at most 12 digits; the fractional component has | integer component has at most 12 digits; the fractional component has | |||
at most three digits. | at most three digits. | |||
The ABNF for decimals is: | The ABNF for decimals is: | |||
sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT | |||
For example, a header whose value is defined as a Decimal could look | For example, a header whose value is defined as a Decimal could look | |||
like: | like: | |||
Example-Decimal: 4.5 | Example-Decimal: 4.5 | |||
While it is possible to serialize Decimals with leading zeros (e.g., | ||||
While it is possible to serialise Decimals with leading zeros (e.g., | ||||
"0002.5", "-01.334"), trailing zeros (e.g., "5.230", "-0.40"), and | "0002.5", "-01.334"), trailing zeros (e.g., "5.230", "-0.40"), and | |||
signed zero (e.g., "-0.0"), these distinctions may not be preserved | signed zero (e.g., "-0.0"), these distinctions may not be preserved | |||
by implementations. | by implementations. | |||
Note that the serialisation algorithm (Section 4.1.5) rounds input | Note that the serialization algorithm (Section 4.1.5) rounds input | |||
with more than three digits of precision in the fractional component. | with more than three digits of precision in the fractional component. | |||
If an alternative rounding strategy is desired, this should be | If an alternative rounding strategy is desired, this should be | |||
specified by the header definition to occur before serialisation. | specified by the header definition to occur before serialization. | |||
3.3.3. Strings | 3.3.3. Strings | |||
Strings are zero or more printable ASCII [RFC0020] characters (i.e., | Strings are zero or more printable ASCII [RFC0020] characters (i.e., | |||
the range %x20 to %x7E). Note that this excludes tabs, newlines, | the range %x20 to %x7E). Note that this excludes tabs, newlines, | |||
carriage returns, etc. | carriage returns, etc. | |||
The ABNF for Strings is: | The ABNF for Strings is: | |||
sf-string = DQUOTE *chr DQUOTE | sf-string = DQUOTE *chr DQUOTE | |||
skipping to change at page 14, line 42 ¶ | skipping to change at page 14, line 37 ¶ | |||
Strings are delimited with double quotes, using a backslash ("\") to | Strings are delimited with double quotes, using a backslash ("\") to | |||
escape double quotes and backslashes. For example: | escape double quotes and backslashes. For example: | |||
Example-String: "hello world" | Example-String: "hello world" | |||
Note that Strings only use DQUOTE as a delimiter; single quotes do | Note that Strings only use DQUOTE as a delimiter; single quotes do | |||
not delimit Strings. Furthermore, only DQUOTE and "\" can be | not delimit Strings. Furthermore, only DQUOTE and "\" can be | |||
escaped; other characters after "\" MUST cause parsing to fail. | escaped; other characters after "\" MUST cause parsing to fail. | |||
Unicode is not directly supported in Strings, because it causes a | 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 -- | |||
values do not require it. | field values do not require it. | |||
When it is necessary for a field value to convey non-ASCII content, a | When it is necessary for a field value to convey non-ASCII content, a | |||
Byte Sequence (Section 3.3.5) can be specified, along with a | Byte Sequence (Section 3.3.5) can be specified, along with a | |||
character encoding (preferably [UTF-8]). | character encoding (preferably UTF-8 [STD63]). | |||
Parsers MUST support Strings (after any decoding) with at least 1024 | Parsers MUST support Strings (after any decoding) with at least 1024 | |||
characters. | characters. | |||
3.3.4. Tokens | 3.3.4. Tokens | |||
Tokens are short textual words; their abstract model is identical to | Tokens are short textual words; their abstract model is identical to | |||
their expression in the HTTP field value serialization. | their expression in the HTTP field value serialization. | |||
The ABNF for Tokens is: | The ABNF for Tokens is: | |||
skipping to change at page 15, line 37 ¶ | skipping to change at page 15, line 32 ¶ | |||
Byte Sequences can be conveyed in Structured Fields. | Byte Sequences can be conveyed in Structured Fields. | |||
The ABNF for a Byte Sequence is: | The ABNF for a Byte Sequence is: | |||
sf-binary = ":" *(base64) ":" | sf-binary = ":" *(base64) ":" | |||
base64 = ALPHA / DIGIT / "+" / "/" / "=" | base64 = ALPHA / DIGIT / "+" / "/" / "=" | |||
A Byte Sequence is delimited with colons and encoded using base64 | A Byte Sequence is delimited with colons and encoded using base64 | |||
([RFC4648], Section 4). For example: | ([RFC4648], Section 4). For example: | |||
Example-Binary: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | Example-ByteSequence: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: | |||
Parsers MUST support Byte Sequences with at least 16384 octets after | Parsers MUST support Byte Sequences with at least 16384 octets after | |||
decoding. | decoding. | |||
3.3.6. Booleans | 3.3.6. Booleans | |||
Boolean values can be conveyed in Structured Fields. | Boolean values can be conveyed in Structured Fields. | |||
The ABNF for a Boolean is: | The ABNF for a Boolean is: | |||
sf-boolean = "?" boolean | sf-boolean = "?" boolean | |||
boolean = "0" / "1" | boolean = "0" / "1" | |||
A Boolean is indicated with a leading "?" character followed by a "1" | A Boolean is indicated with a leading "?" character followed by a "1" | |||
for a true value or "0" for false. For example: | for a true value or "0" for false. For example: | |||
Example-Bool: ?1 | Example-Boolean: ?1 | |||
Note that in Dictionary (Section 3.2) and Parameter (Section 3.1.2) | Note that in Dictionary (Section 3.2) and Parameter (Section 3.1.2) | |||
values, Boolean true is indicated by omitting the value. | values, Boolean true is indicated by omitting the value. | |||
4. Working With Structured Fields in HTTP | 4. Working with Structured Fields in HTTP | |||
This section defines how to serialize and parse Structured Fields in | 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 [RFC7540] before compression with HPACK [RFC7541]). | (e.g., in HTTP/2 [RFC7540] before compression with HPACK [RFC7541]). | |||
4.1. Serializing Structured Fields | 4.1. Serializing Structured Fields | |||
Given a structure defined in this specification, return an ASCII | Given a structure defined in this specification, return an ASCII | |||
string suitable for use in a HTTP field value. | string suitable for use in an HTTP field value. | |||
1. If the structure is a Dictionary or List and its value is empty | 1. If the structure is a Dictionary or List and its value is empty | |||
(i.e., it has no members), do not serialize the field at all | (i.e., it has no members), do not serialize the field at all | |||
(i.e., omit both the field-name and field-value). | (i.e., omit both the field-name and field-value). | |||
2. If the structure is a List, let output_string be the result of | 2. If the structure is a List, let output_string be the result of | |||
running Serializing a List (Section 4.1.1) with the structure. | running Serializing a List (Section 4.1.1) with the structure. | |||
3. Else if the structure is a Dictionary, let output_string be the | 3. Else, if the structure is a Dictionary, let output_string be the | |||
result of running Serializing a Dictionary (Section 4.1.2) with | result of running Serializing a Dictionary (Section 4.1.2) with | |||
the structure. | the structure. | |||
4. Else if the structure is an Item, let output_string be the result | 4. Else, if the structure is an Item, let output_string be the | |||
of running Serializing an Item (Section 4.1.3) with the | result of running Serializing an Item (Section 4.1.3) with the | |||
structure. | structure. | |||
5. Else, fail serialization. | 5. Else, fail serialization. | |||
6. Return output_string converted into an array of bytes, using | 6. Return output_string converted into an array of bytes, using | |||
ASCII encoding [RFC0020]. | ASCII encoding [RFC0020]. | |||
4.1.1. Serializing a List | 4.1.1. Serializing a List | |||
Given an array of (member_value, parameters) tuples as input_list, | Given an array of (member_value, parameters) tuples as input_list, | |||
return an ASCII string suitable for use in a HTTP field value. | return an ASCII string suitable for use in an HTTP field value. | |||
1. Let output be an empty string. | 1. Let output be an empty string. | |||
2. For each (member_value, parameters) of input_list: | 2. For each (member_value, parameters) of input_list: | |||
1. If member_value is an array, append the result of running | 1. If member_value is an array, append the result of running | |||
Serializing an Inner List (Section 4.1.1.1) with | Serializing an Inner List (Section 4.1.1.1) with | |||
(member_value, parameters) to output. | (member_value, parameters) to output. | |||
2. Otherwise, append the result of running Serializing an Item | 2. Otherwise, append the result of running Serializing an Item | |||
skipping to change at page 17, line 20 ¶ | skipping to change at page 17, line 15 ¶ | |||
1. Append "," to output. | 1. Append "," to output. | |||
2. Append a single SP to output. | 2. Append a single SP to output. | |||
3. Return output. | 3. Return output. | |||
4.1.1.1. Serializing an Inner List | 4.1.1.1. Serializing an Inner List | |||
Given an array of (member_value, parameters) tuples as inner_list, | Given an array of (member_value, parameters) tuples as inner_list, | |||
and parameters as list_parameters, return an ASCII string suitable | and parameters as list_parameters, return an ASCII string suitable | |||
for use in a HTTP field value. | for use in an HTTP field value. | |||
1. Let output be the string "(". | 1. Let output be the string "(". | |||
2. For each (member_value, parameters) of inner_list: | 2. For each (member_value, parameters) of inner_list: | |||
1. Append the result of running Serializing an Item | 1. Append the result of running Serializing an Item | |||
(Section 4.1.3) with (member_value, parameters) to output. | (Section 4.1.3) with (member_value, parameters) to output. | |||
2. If more values remain in inner_list, append a single SP to | 2. If more values remain in inner_list, append a single SP to | |||
output. | output. | |||
skipping to change at page 17, line 42 ¶ | skipping to change at page 17, line 37 ¶ | |||
3. Append ")" to output. | 3. Append ")" to output. | |||
4. Append the result of running Serializing Parameters | 4. Append the result of running Serializing Parameters | |||
(Section 4.1.1.2) with list_parameters to output. | (Section 4.1.1.2) with list_parameters to output. | |||
5. Return output. | 5. Return output. | |||
4.1.1.2. Serializing Parameters | 4.1.1.2. Serializing Parameters | |||
Given an ordered Dictionary as input_parameters (each member having a | Given an ordered Dictionary as input_parameters (each member having a | |||
param_name and a param_value), return an ASCII string suitable for | param_key and a param_value), return an ASCII string suitable for use | |||
use in a HTTP field value. | in an HTTP field value. | |||
1. Let output be an empty string. | 1. Let output be an empty string. | |||
2. For each param_name with a value of param_value in | 2. For each param_key with a value of param_value in | |||
input_parameters: | input_parameters: | |||
1. Append ";" to output. | 1. Append ";" to output. | |||
2. Append the result of running Serializing a Key | 2. Append the result of running Serializing a Key | |||
(Section 4.1.1.3) with param_name to output. | (Section 4.1.1.3) with param_key to output. | |||
3. If param_value is not Boolean true: | 3. If param_value is not Boolean true: | |||
1. Append "=" to output. | 1. Append "=" to output. | |||
2. Append the result of running Serializing a bare Item | 2. Append the result of running Serializing a bare Item | |||
(Section 4.1.3.1) with param_value to output. | (Section 4.1.3.1) with param_value to output. | |||
3. Return output. | 3. Return output. | |||
4.1.1.3. Serializing a Key | 4.1.1.3. Serializing a Key | |||
Given a key as input_key, return an ASCII string suitable for use in | Given a key as input_key, return an ASCII string suitable for use in | |||
a HTTP field value. | an HTTP field value. | |||
1. Convert input_key into a sequence of ASCII characters; if | 1. Convert input_key into a sequence of ASCII characters; if | |||
conversion fails, fail serialization. | conversion fails, fail serialization. | |||
2. If input_key contains characters not in lcalpha, DIGIT, "_", "-", | 2. If input_key contains characters not in lcalpha, DIGIT, "_", "-", | |||
".", or "*" fail serialization. | ".", or "*", fail serialization. | |||
3. If the first character of input_key is not lcalpha or "*", fail | 3. If the first character of input_key is not lcalpha or "*", fail | |||
serialization. | serialization. | |||
4. Let output be an empty string. | 4. Let output be an empty string. | |||
5. Append input_key to output. | 5. Append input_key to output. | |||
6. Return output. | 6. Return output. | |||
4.1.2. Serializing a Dictionary | 4.1.2. Serializing a Dictionary | |||
Given an ordered Dictionary as input_dictionary (each member having a | Given an ordered Dictionary as input_dictionary (each member having a | |||
member_name and a tuple value of (member_value, parameters)), return | member_key and a tuple value of (member_value, parameters)), return | |||
an ASCII string suitable for use in a HTTP field value. | an ASCII string suitable for use in an HTTP field value. | |||
1. Let output be an empty string. | 1. Let output be an empty string. | |||
2. For each member_name with a value of (member_value, parameters) | 2. For each member_key with a value of (member_value, parameters) in | |||
in input_dictionary: | input_dictionary: | |||
1. Append the result of running Serializing a Key | 1. Append the result of running Serializing a Key | |||
(Section 4.1.1.3) with member's member_name to output. | (Section 4.1.1.3) with member's member_key to output. | |||
2. If member_value is Boolean true: | 2. If member_value is Boolean true: | |||
1. Append the result of running Serializing Parameters | 1. Append the result of running Serializing Parameters | |||
(Section 4.1.1.2) with parameters to output. | (Section 4.1.1.2) with parameters to output. | |||
3. Otherwise: | 3. Otherwise: | |||
1. Append "=" to output. | 1. Append "=" to output. | |||
skipping to change at page 19, line 31 ¶ | skipping to change at page 19, line 24 ¶ | |||
1. Append "," to output. | 1. Append "," to output. | |||
2. Append a single SP to output. | 2. Append a single SP to output. | |||
3. Return output. | 3. Return output. | |||
4.1.3. Serializing an Item | 4.1.3. Serializing an Item | |||
Given an Item as bare_item and Parameters as item_parameters, return | Given an Item as bare_item and Parameters as item_parameters, return | |||
an ASCII string suitable for use in a HTTP field value. | an ASCII string suitable for use in an HTTP field value. | |||
1. Let output be an empty string. | 1. Let output be an empty string. | |||
2. Append the result of running Serializing a Bare Item | 2. Append the result of running Serializing a Bare Item | |||
Section 4.1.3.1 with bare_item to output. | (Section 4.1.3.1) with bare_item to output. | |||
3. Append the result of running Serializing Parameters | 3. Append the result of running Serializing Parameters | |||
Section 4.1.1.2 with item_parameters to output. | (Section 4.1.1.2) with item_parameters to output. | |||
4. Return output. | 4. Return output. | |||
4.1.3.1. Serializing a Bare Item | 4.1.3.1. Serializing a Bare Item | |||
Given an Item as input_item, return an ASCII string suitable for use | Given an Item as input_item, return an ASCII string suitable for use | |||
in a HTTP field value. | in an HTTP field value. | |||
1. If input_item is an Integer, return the result of running | 1. If input_item is an Integer, return the result of running | |||
Serializing an Integer (Section 4.1.4) with input_item. | Serializing an Integer (Section 4.1.4) with input_item. | |||
2. If input_item is a Decimal, return the result of running | 2. If input_item is a Decimal, return the result of running | |||
Serializing a Decimal (Section 4.1.5) with input_item. | Serializing a Decimal (Section 4.1.5) with input_item. | |||
3. If input_item is a String, return the result of running | 3. If input_item is a String, return the result of running | |||
Serializing a String (Section 4.1.6) with input_item. | Serializing a String (Section 4.1.6) with input_item. | |||
4. If input_item is a Token, return the result of running | 4. If input_item is a Token, return the result of running | |||
Serializing a Token (Section 4.1.7) with input_item. | Serializing a Token (Section 4.1.7) with input_item. | |||
5. If input_item is a Boolean, return the result of running | 5. If input_item is a Byte Sequence, 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. | 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. | ||||
7. Otherwise, fail serialization. | 7. Otherwise, fail serialization. | |||
4.1.4. Serializing an Integer | 4.1.4. Serializing an Integer | |||
Given an Integer as input_integer, return an ASCII string suitable | Given an Integer as input_integer, return an ASCII string suitable | |||
for use in a HTTP field value. | for use in an HTTP field value. | |||
1. If input_integer is not an integer in the range of | 1. If input_integer is not an integer in the range of | |||
-999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail | |||
serialization. | serialization. | |||
2. Let output be an empty string. | 2. Let output be an empty string. | |||
3. If input_integer is less than (but not equal to) 0, append "-" to | 3. If input_integer is less than (but not equal to) 0, append "-" to | |||
output. | output. | |||
4. Append input_integer's numeric value represented in base 10 using | 4. Append input_integer's numeric value represented in base 10 using | |||
only decimal digits to output. | only decimal digits to output. | |||
5. Return output. | 5. Return output. | |||
4.1.5. Serializing a Decimal | 4.1.5. Serializing a Decimal | |||
Given a decimal number as input_decimal, return an ASCII string | Given a decimal number as input_decimal, return an ASCII string | |||
suitable for use in a HTTP field value. | suitable for use in an HTTP field value. | |||
1. If input_decimal is not a decimal number, fail serialization. | 1. If input_decimal is not a decimal number, fail serialization. | |||
2. If input_decimal has more than three significant digits to the | 2. 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. | value if it is equidistant. | |||
3. If input_decimal has more than 12 significant digits to the left | 3. If input_decimal has more than 12 significant digits to the left | |||
of the decimal point after rounding, fail serialization. | of the decimal point after rounding, fail serialization. | |||
skipping to change at page 21, line 28 ¶ | skipping to change at page 21, line 23 ¶ | |||
9. Otherwise, append the significant digits of input_decimal's | 9. 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. | digits) to output. | |||
10. Return output. | 10. Return output. | |||
4.1.6. Serializing a String | 4.1.6. Serializing a String | |||
Given a String as input_string, return an ASCII string suitable for | Given a String as input_string, return an ASCII string suitable for | |||
use in a HTTP field value. | use in an HTTP field value. | |||
1. Convert input_string into a sequence of ASCII characters; if | 1. Convert input_string into a sequence of ASCII characters; if | |||
conversion fails, fail serialization. | conversion fails, fail serialization. | |||
2. If input_string contains characters in the range %x00-1f or %x7f | 2. If input_string contains characters in the range %x00-1f or %x7f- | |||
(i.e., not in VCHAR or SP), fail serialization. | ff (i.e., not in VCHAR or SP), fail serialization. | |||
3. Let output be the string DQUOTE. | 3. Let output be the string DQUOTE. | |||
4. For each character char in input_string: | 4. For each character char in input_string: | |||
1. If char is "\" or DQUOTE: | 1. If char is "\" or DQUOTE: | |||
1. Append "\" to output. | 1. Append "\" to output. | |||
2. Append char to output. | 2. Append char to output. | |||
5. Append DQUOTE to output. | 5. Append DQUOTE to output. | |||
6. Return output. | 6. Return output. | |||
4.1.7. Serializing a Token | 4.1.7. Serializing a Token | |||
Given a Token as input_token, return an ASCII string suitable for use | Given a Token as input_token, return an ASCII string suitable for use | |||
in a HTTP field value. | in an HTTP field value. | |||
1. Convert input_token into a sequence of ASCII characters; if | 1. Convert input_token into a sequence of ASCII characters; if | |||
conversion fails, fail serialization. | conversion fails, fail serialization. | |||
2. If the first character of input_token is not ALPHA or "*", or the | 2. If the first character of input_token is not ALPHA or "*", or the | |||
remaining portion contains a character not in tchar, ":" or "/", | remaining portion contains a character not in tchar, ":", or "/", | |||
fail serialization. | fail serialization. | |||
3. Let output be an empty string. | 3. Let output be an empty string. | |||
4. Append input_token to output. | 4. Append input_token to output. | |||
5. Return output. | 5. Return output. | |||
4.1.8. Serializing a Byte Sequence | 4.1.8. Serializing a Byte Sequence | |||
Given a Byte Sequence as input_bytes, return an ASCII string suitable | Given a Byte Sequence as input_bytes, return an ASCII string suitable | |||
for use in a HTTP field value. | for use in an HTTP field value. | |||
1. If input_bytes is not a sequence of bytes, fail serialization. | 1. If input_bytes is not a sequence of bytes, fail serialization. | |||
2. Let output be an empty string. | 2. Let output be an empty string. | |||
3. Append ":" to output. | 3. Append ":" to output. | |||
4. Append the result of base64-encoding input_bytes as per | 4. Append the result of base64-encoding input_bytes as per | |||
[RFC4648], Section 4, taking account of the requirements below. | [RFC4648], Section 4, taking account of the requirements below. | |||
skipping to change at page 22, line 51 ¶ | skipping to change at page 22, line 43 ¶ | |||
The encoded data is required to be padded with "=", as per [RFC4648], | The encoded data is required to be padded with "=", as per [RFC4648], | |||
Section 3.2. | Section 3.2. | |||
Likewise, encoded data SHOULD have pad bits set to zero, as per | Likewise, encoded data SHOULD have pad bits set to zero, as per | |||
[RFC4648], Section 3.5, unless it is not possible to do so due to | [RFC4648], Section 3.5, unless it is not possible to do so due to | |||
implementation constraints. | implementation constraints. | |||
4.1.9. Serializing a Boolean | 4.1.9. Serializing a Boolean | |||
Given a Boolean as input_boolean, return an ASCII string suitable for | Given a Boolean as input_boolean, return an ASCII string suitable for | |||
use in a HTTP field value. | use in an HTTP field value. | |||
1. If input_boolean is not a boolean, fail serialization. | 1. If input_boolean is not a boolean, fail serialization. | |||
2. Let output be an empty string. | 2. Let output be an empty string. | |||
3. Append "?" to output. | 3. Append "?" to output. | |||
4. If input_boolean is true, append "1" to output. | 4. If input_boolean is true, append "1" to output. | |||
5. If input_boolean is false, append "0" to output. | 5. If input_boolean is false, append "0" to output. | |||
skipping to change at page 23, line 25 ¶ | skipping to change at page 23, line 17 ¶ | |||
6. Return output. | 6. Return output. | |||
4.2. Parsing Structured Fields | 4.2. Parsing Structured Fields | |||
When a receiving implementation parses HTTP fields that are known to | When a receiving implementation parses HTTP fields that are known to | |||
be Structured Fields, it is important that care be taken, as there | 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. | so. | |||
Given an array of bytes input_bytes that represents the chosen | 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), | field's field-value (which is empty if that field is not present) and | |||
and field_type (one of "dictionary", "list", or "item"), return the | field_type (one of "dictionary", "list", or "item"), return the | |||
parsed header value. | parsed header value. | |||
1. Convert input_bytes into an ASCII string input_string; if | 1. Convert input_bytes into an ASCII string input_string; if | |||
conversion fails, fail parsing. | conversion fails, fail parsing. | |||
2. Discard any leading SP characters from input_string. | 2. Discard any leading SP characters from input_string. | |||
3. If field_type is "list", let output be the result of running | 3. If field_type is "list", let output be the result of running | |||
Parsing a List (Section 4.2.1) with input_string. | Parsing a List (Section 4.2.1) with input_string. | |||
skipping to change at page 24, line 4 ¶ | skipping to change at page 23, line 45 ¶ | |||
6. Discard any leading SP characters from input_string. | 6. Discard any leading SP characters from input_string. | |||
7. If input_string is not empty, fail parsing. | 7. If input_string is not empty, fail parsing. | |||
8. Otherwise, return output. | 8. Otherwise, return output. | |||
When generating input_bytes, parsers MUST combine all field lines in | When generating input_bytes, parsers MUST combine all field lines in | |||
the same section (header or trailer) that case-insensitively match | the same section (header or trailer) that case-insensitively match | |||
the field name into one comma-separated field-value, as per | the field name into one comma-separated field-value, as per | |||
[RFC7230], Section 3.2.2; this assures that the entire field value is | [RFC7230], Section 3.2.2; this assures that the entire field value is | |||
processed correctly. | processed correctly. | |||
For Lists and Dictionaries, this has the effect of correctly | 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 | instances. The parsing algorithms for both types allow tab | |||
characters, since these might be used to combine field lines by some | characters, since these might be used to combine field lines by some | |||
implementations. | implementations. | |||
Strings split across multiple field lines will have unpredictable | Strings split across multiple field lines will have unpredictable | |||
results, because comma(s) and whitespace inserted upon combination | results, because one or more commas (with optional whitespace) will | |||
will become part of the string output by the parser. Since | become part of the string output by the parser. Since concatenation | |||
concatenation might be done by an upstream intermediary, the results | might be done by an upstream intermediary, the results are not under | |||
are not under the control of the serializer or the parser, even when | the control of the serializer or the parser, even when they are both | |||
they are both under the control of the same party. | under the control of the same party. | |||
Tokens, Integers, Decimals and Byte Sequences cannot be split across | Tokens, Integers, Decimals, and Byte Sequences cannot be split across | |||
multiple field lines because the inserted commas will cause parsing | multiple field lines because the inserted commas will cause parsing | |||
to fail. | to fail. | |||
Parsers MAY fail when processing a field value spread across multiple | Parsers MAY fail when processing a field value spread across multiple | |||
field lines, when one of those lines does not parse as that field. | field lines, when one of those lines does not parse as that field. | |||
For example, a parsing handling an Example-String field that's | For example, a parsing handling an Example-String field that's | |||
defined as a sf-string is allowed to fail when processing this field | defined as an sf-string is allowed to fail when processing this field | |||
section: | section: | |||
Example-String: "foo | Example-String: "foo | |||
Example-String: bar" | Example-String: bar" | |||
If parsing fails - including when calling another algorithm - the | If parsing fails -- including when calling another algorithm -- the | |||
entire field value MUST be ignored (i.e., treated as if the field | entire field value MUST be ignored (i.e., treated as if the field | |||
were not present in the section). This is intentionally strict, to | were not present in the section). This is intentionally strict, to | |||
improve interoperability and safety, and specifications referencing | improve interoperability and safety, and specifications referencing | |||
this document are not allowed to loosen this requirement. | this document are not allowed to loosen this requirement. | |||
Note that this requirement does not apply to an implementation that | Note that this requirement does not apply to an implementation that | |||
is not parsing the field; for example, an intermediary is not | is not parsing the field; for example, an intermediary is not | |||
required to strip a failing field from a message before forwarding | required to strip a failing field from a message before forwarding | |||
it. | it. | |||
skipping to change at page 25, line 29 ¶ | skipping to change at page 25, line 22 ¶ | |||
6. If input_string is empty, there is a trailing comma; fail | 6. If input_string is empty, there is a trailing comma; fail | |||
parsing. | parsing. | |||
3. No structured data has been found; return members (which is | 3. No structured data has been found; return members (which is | |||
empty). | empty). | |||
4.2.1.1. Parsing an Item or Inner List | 4.2.1.1. Parsing an Item or Inner List | |||
Given an ASCII string as input_string, return the tuple | Given an ASCII string as input_string, return the tuple | |||
(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. | tuples. input_string is modified to remove the parsed value. | |||
1. If the first character of input_string is "(", return the result | 1. If the first character of input_string is "(", return the result | |||
of running Parsing an Inner List (Section 4.2.1.2) with | of running Parsing an Inner List (Section 4.2.1.2) with | |||
input_string. | input_string. | |||
2. Return the result of running Parsing an Item (Section 4.2.3) with | 2. Return the result of running Parsing an Item (Section 4.2.3) with | |||
input_string. | input_string. | |||
4.2.1.2. Parsing an Inner List | 4.2.1.2. Parsing an Inner List | |||
skipping to change at page 26, line 22 ¶ | skipping to change at page 26, line 15 ¶ | |||
3. Return the tuple (inner_list, parameters). | 3. Return the tuple (inner_list, parameters). | |||
3. Let item be the result of running Parsing an Item | 3. Let item be the result of running Parsing an Item | |||
(Section 4.2.3) with input_string. | (Section 4.2.3) with input_string. | |||
4. Append item to inner_list. | 4. Append item to inner_list. | |||
5. If the first character of input_string is not SP or ")", fail | 5. If the first character of input_string is not SP or ")", fail | |||
parsing. | parsing. | |||
4. The end of the inner list was not found; fail parsing. | 4. The end of the Inner List was not found; fail parsing. | |||
4.2.2. Parsing a Dictionary | 4.2.2. Parsing a Dictionary | |||
Given an ASCII string as input_string, return an ordered map whose | Given an ASCII string as input_string, return an ordered map whose | |||
values are (item_or_inner_list, parameters) tuples. input_string is | values are (item_or_inner_list, parameters) tuples. input_string is | |||
modified to remove the parsed value. | modified to remove the parsed value. | |||
1. Let dictionary be an empty, ordered map. | 1. Let dictionary be an empty, ordered map. | |||
2. While input_string is not empty: | 2. While input_string is not empty: | |||
1. Let this_key be the result of running Parsing a Key | 1. Let this_key be the result of running Parsing a Key | |||
(Section 4.2.3.3) with input_string. | (Section 4.2.3.3) with input_string. | |||
2. If the first character of input_string is "=": | 2. If the first character of input_string is "=": | |||
1. Consume the first character of input_string. | 1. Consume the first character of input_string. | |||
2. Let member be the result of running Parsing an Item or | 2. Let member be the result of running Parsing an Item or | |||
Inner List (Section 4.2.1.1) with input_string. | Inner List (Section 4.2.1.1) with input_string. | |||
3. Otherwise: | 3. Otherwise: | |||
1. Let value be Boolean true. | 1. Let value be Boolean true. | |||
2. Let parameters be the result of running Parsing | 2. Let parameters be the result of running Parsing | |||
Parameters Section 4.2.3.2 with input_string. | Parameters (Section 4.2.3.2) with input_string. | |||
3. Let member be the tuple (value, parameters). | 3. Let member be the tuple (value, parameters). | |||
4. Add name this_key with value member to dictionary. If | 4. If dictionary already contains a key this_key (comparing | |||
dictionary already contains a name this_key (comparing | character for character), overwrite its value with member. | |||
character-for-character), overwrite its value. | ||||
5. Discard any leading OWS characters from input_string. | 5. Otherwise, append key this_key with value member to | |||
dictionary. | ||||
6. If input_string is empty, return dictionary. | 6. Discard any leading OWS characters from input_string. | |||
7. Consume the first character of input_string; if it is not | 7. If input_string is empty, return dictionary. | |||
",", fail parsing. | ||||
8. Discard any leading OWS characters from input_string. | 8. Consume the first character of input_string; if it is not | |||
",", fail parsing. | ||||
9. If input_string is empty, there is a trailing comma; fail | 9. Discard any leading OWS characters from input_string. | |||
parsing. | ||||
10. If input_string is empty, there is a trailing comma; fail | ||||
parsing. | ||||
3. No structured data has been found; return dictionary (which is | 3. No structured data has been found; return dictionary (which is | |||
empty). | empty). | |||
Note that when duplicate Dictionary keys are encountered, this has | Note that when duplicate Dictionary keys are encountered, all but the | |||
the effect of ignoring all but the last instance. | last instance are ignored. | |||
4.2.3. Parsing an Item | 4.2.3. Parsing an Item | |||
Given an ASCII string as input_string, return a (bare_item, | Given an ASCII string as input_string, return a (bare_item, | |||
parameters) tuple. input_string is modified to remove the parsed | parameters) tuple. input_string is modified to remove the parsed | |||
value. | value. | |||
1. Let bare_item be the result of running Parsing a Bare Item | 1. Let bare_item be the result of running Parsing a Bare Item | |||
(Section 4.2.3.1) with input_string. | (Section 4.2.3.1) with input_string. | |||
skipping to change at page 28, line 5 ¶ | skipping to change at page 27, line 48 ¶ | |||
input_string is modified to remove the parsed value. | input_string is modified to remove the parsed value. | |||
1. If the first character of input_string is a "-" or a DIGIT, | 1. If the first character of input_string is a "-" or a DIGIT, | |||
return the result of running Parsing an Integer or Decimal | return the result of running Parsing an Integer or Decimal | |||
(Section 4.2.4) with input_string. | (Section 4.2.4) with input_string. | |||
2. If the first character of input_string is a DQUOTE, return the | 2. If the first character of input_string is a DQUOTE, return the | |||
result of running Parsing a String (Section 4.2.5) with | result of running Parsing a String (Section 4.2.5) with | |||
input_string. | input_string. | |||
3. If the first character of input_string is ":", return the result | 3. If the first character of input_string is 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 | of running Parsing a Byte Sequence (Section 4.2.7) with | |||
input_string. | input_string. | |||
4. If the first character of input_string is "?", return the result | 5. If the first character of input_string is "?", return the result | |||
of running Parsing a Boolean (Section 4.2.8) with input_string. | of running Parsing a Boolean (Section 4.2.8) with input_string. | |||
5. If the first character of input_string is an ALPHA or "*", return | ||||
the result of running Parsing a Token (Section 4.2.6) with | ||||
input_string. | ||||
6. Otherwise, the item type is unrecognized; fail parsing. | 6. Otherwise, the item type is unrecognized; fail parsing. | |||
4.2.3.2. Parsing Parameters | 4.2.3.2. Parsing Parameters | |||
Given an ASCII string as input_string, return an ordered map whose | Given an ASCII string as input_string, return an ordered map whose | |||
values are bare Items. input_string is modified to remove the parsed | values are bare Items. input_string is modified to remove the parsed | |||
value. | value. | |||
1. Let parameters be an empty, ordered map. | 1. Let parameters be an empty, ordered map. | |||
2. While input_string is not empty: | 2. While input_string is not empty: | |||
1. If the first character of input_string is not ";", exit the | 1. If the first character of input_string is not ";", exit the | |||
loop. | loop. | |||
2. Consume a ";" character from the beginning of input_string. | 2. Consume the ";" character from the beginning of input_string. | |||
3. Discard any leading SP characters from input_string. | 3. Discard any leading SP characters from input_string. | |||
4. let param_name be the result of running Parsing a Key | 4. Let param_key be the result of running Parsing a Key | |||
(Section 4.2.3.3) with input_string. | (Section 4.2.3.3) with input_string. | |||
5. Let param_value be Boolean true. | 5. Let param_value be Boolean true. | |||
6. If the first character of input_string is "=": | 6. If the first character of input_string is "=": | |||
1. Consume the "=" character at the beginning of | 1. Consume the "=" character at the beginning of | |||
input_string. | input_string. | |||
2. Let param_value be the result of running Parsing a Bare | 2. Let param_value be the result of running Parsing a Bare | |||
Item (Section 4.2.3.1) with input_string. | Item (Section 4.2.3.1) with input_string. | |||
7. Append key param_name with value param_value to parameters. | 7. If parameters already contains a key param_key (comparing | |||
If parameters already contains a name param_name (comparing | character for character), overwrite its value with | |||
character-for-character), overwrite its value. | param_value. | |||
8. Otherwise, append key param_key with value param_value to | ||||
parameters. | ||||
3. Return parameters. | 3. Return parameters. | |||
Note that when duplicate Parameter keys are encountered, this has the | Note that when duplicate parameter keys are encountered, all but the | |||
effect of ignoring all but the last instance. | last instance are ignored. | |||
4.2.3.3. Parsing a Key | 4.2.3.3. Parsing a Key | |||
Given an ASCII string as input_string, return a key. input_string is | Given an ASCII string as input_string, return a key. input_string is | |||
modified to remove the parsed value. | modified to remove the parsed value. | |||
1. If the first character of input_string is not lcalpha or "*", | 1. If the first character of input_string is not lcalpha or "*", | |||
fail parsing. | fail parsing. | |||
2. Let output_string be an empty string. | 2. Let output_string be an empty string. | |||
skipping to change at page 30, line 33 ¶ | skipping to change at page 30, line 33 ¶ | |||
characters, fail parsing. | characters, fail parsing. | |||
6. If type is "decimal" and input_number contains more than 16 | 6. If type is "decimal" and input_number contains more than 16 | |||
characters, fail parsing. | characters, fail parsing. | |||
8. If type is "integer": | 8. If type is "integer": | |||
1. Parse input_number as an integer and let output_number be | 1. Parse input_number as an integer and let output_number be | |||
the product of the result and sign. | the product of the result and sign. | |||
2. If output_number is outside the range -999,999,999,999,999 | ||||
to 999,999,999,999,999 inclusive, fail parsing. | ||||
9. Otherwise: | 9. Otherwise: | |||
1. If the final character of input_number is ".", fail parsing. | 1. If the final character of input_number is ".", fail parsing. | |||
2. If the number of characters after "." in input_number is | 2. If the number of characters after "." in input_number is | |||
greater than three, fail parsing. | greater than three, fail parsing. | |||
3. Parse input_number as a decimal number and let output_number | 3. Parse input_number as a decimal number and let output_number | |||
be the product of the result and sign. | be the product of the result and sign. | |||
skipping to change at page 31, line 30 ¶ | skipping to change at page 31, line 28 ¶ | |||
2. Let next_char be the result of consuming the first | 2. Let next_char be the result of consuming the first | |||
character of input_string. | character of input_string. | |||
3. If next_char is not DQUOTE or "\", fail parsing. | 3. If next_char is not DQUOTE or "\", fail parsing. | |||
4. Append next_char to output_string. | 4. Append next_char to output_string. | |||
3. Else, if char is DQUOTE, return output_string. | 3. Else, if char is DQUOTE, return output_string. | |||
4. Else, if char is in the range %x00-1f or %x7f (i.e., is not | 4. Else, if char is in the range %x00-1f or %x7f-ff (i.e., it is | |||
in VCHAR or SP), fail parsing. | not in VCHAR or SP), fail parsing. | |||
5. Else, append char to output_string. | 5. Else, append char to output_string. | |||
5. Reached the end of input_string without finding a closing DQUOTE; | 5. Reached the end of input_string without finding a closing DQUOTE; | |||
fail parsing. | fail parsing. | |||
4.2.6. Parsing a Token | 4.2.6. Parsing a Token | |||
Given an ASCII string as input_string, return a Token. input_string | Given an ASCII string as input_string, return a Token. input_string | |||
is modified to remove the parsed value. | is modified to remove the parsed value. | |||
1. If the first character of input_string is not ALPHA or "*", fail | 1. If the first character of input_string is not ALPHA or "*", fail | |||
parsing. | parsing. | |||
2. Let output_string be an empty string. | 2. Let output_string be an empty string. | |||
3. While input_string is not empty: | 3. While input_string is not empty: | |||
1. If the first character of input_string is not in tchar, ":" | 1. If the first character of input_string is not in tchar, ":", | |||
or "/", return output_string. | or "/", return output_string. | |||
2. Let char be the result of consuming the first character of | 2. Let char be the result of consuming the first character of | |||
input_string. | input_string. | |||
3. Append char to output_string. | 3. Append char to output_string. | |||
4. Return output_string. | 4. Return output_string. | |||
4.2.7. Parsing a Byte Sequence | 4.2.7. Parsing a Byte Sequence | |||
skipping to change at page 32, line 31 ¶ | skipping to change at page 32, line 28 ¶ | |||
3. If there is not a ":" character before the end of input_string, | 3. If there is not a ":" character before the end of input_string, | |||
fail parsing. | fail parsing. | |||
4. Let b64_content be the result of consuming content of | 4. Let b64_content be the result of consuming content of | |||
input_string up to but not including the first instance of the | input_string up to but not including the first instance of the | |||
character ":". | character ":". | |||
5. Consume the ":" character at the beginning of input_string. | 5. Consume the ":" character at the beginning of input_string. | |||
6. If b64_content contains a character not included in ALPHA, DIGIT, | 6. If b64_content contains a character not included in ALPHA, DIGIT, | |||
"+", "/" and "=", fail parsing. | "+", "/", and "=", fail parsing. | |||
7. Let binary_content be the result of Base 64 Decoding [RFC4648] | 7. Let binary_content be the result of base64-decoding [RFC4648] | |||
b64_content, synthesizing padding if necessary (note the | b64_content, synthesizing padding if necessary (note the | |||
requirements about recipient behavior below). | requirements about recipient behavior below). If base64 decoding | |||
fails, parsing fails. | ||||
8. Return binary_content. | 8. Return binary_content. | |||
Because some implementations of base64 do not allow rejection of | Because some implementations of base64 do not allow rejection of | |||
encoded data that is not properly "=" padded (see [RFC4648], | encoded data that is not properly "=" padded (see [RFC4648], | |||
Section 3.2), parsers SHOULD NOT fail when "=" padding is not | Section 3.2, parsers SHOULD NOT fail when "=" padding is not present, | |||
present, unless they cannot be configured to do so. | unless they cannot be configured to do so. | |||
Because some implementations of base64 do not allow rejection of | Because some implementations of base64 do not allow rejection of | |||
encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), | encoded data that has non-zero pad bits (see [RFC4648], Section 3.5), | |||
parsers SHOULD NOT fail when non-zero pad bits are present, unless | parsers SHOULD NOT fail when non-zero pad bits are present, unless | |||
they cannot be configured to do so. | they cannot be configured to do so. | |||
This specification does not relax the requirements in [RFC4648], | This specification does not relax the requirements in Sections 3.1 | |||
Section 3.1 and 3.3; therefore, parsers MUST fail on characters | and 3.3 of [RFC4648]; therefore, parsers MUST fail on characters | |||
outside the base64 alphabet, and on line feeds in encoded data. | outside the base64 alphabet and on line feeds in encoded data. | |||
4.2.8. Parsing a Boolean | 4.2.8. Parsing a Boolean | |||
Given an ASCII string as input_string, return a Boolean. input_string | Given an ASCII string as input_string, return a Boolean. input_string | |||
is modified to remove the parsed value. | is modified to remove the parsed value. | |||
1. If the first character of input_string is not "?", fail parsing. | 1. If the first character of input_string is not "?", fail parsing. | |||
2. Discard the first character of input_string. | 2. Discard the first character of input_string. | |||
3. If the first character of input_string matches "1", discard the | 3. If the first character of input_string matches "1", discard the | |||
first character, and return true. | first character, and return true. | |||
4. If the first character of input_string matches "0", discard the | 4. If the first character of input_string matches "0", discard the | |||
first character, and return false. | first character, and return false. | |||
5. No value has matched; fail parsing. | 5. No value has matched; fail parsing. | |||
5. IANA Considerations | 5. IANA Considerations | |||
This document has no actions for IANA. | This document has no IANA actions. | |||
6. Security Considerations | 6. Security Considerations | |||
The size of most types defined by Structured Fields is not limited; | 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., | as a result, extremely large fields could be an attack vector (e.g., | |||
for resource consumption). Most HTTP implementations limit the sizes | for resource consumption). Most HTTP implementations limit the sizes | |||
of individual fields as well as the overall header or trailer section | of individual fields as well as the overall header or trailer section | |||
size to mitigate such attacks. | size to mitigate such attacks. | |||
It is possible for parties with the ability to inject new HTTP fields | It is possible for parties with the ability to inject new HTTP fields | |||
skipping to change at page 35, line 5 ¶ | skipping to change at page 35, line 5 ¶ | |||
[RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | [RFC7541] Peon, R. and H. Ruellan, "HPACK: Header Compression for | |||
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015, | |||
<https://www.rfc-editor.org/info/rfc7541>. | <https://www.rfc-editor.org/info/rfc7541>. | |||
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data | [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data | |||
Interchange Format", STD 90, RFC 8259, | Interchange Format", STD 90, RFC 8259, | |||
DOI 10.17487/RFC8259, December 2017, | DOI 10.17487/RFC8259, December 2017, | |||
<https://www.rfc-editor.org/info/rfc8259>. | <https://www.rfc-editor.org/info/rfc8259>. | |||
[UTF-8] Yergeau, F., "UTF-8, a transformation format of ISO | [STD63] Yergeau, F., "UTF-8, a transformation format of ISO | |||
10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November | 10646", STD 63, RFC 3629, DOI 10.17487/RFC3629, November | |||
2003, <http://www.rfc-editor.org/info/std63>. | 2003, <http://www.rfc-editor.org/info/std63>. | |||
7.3. URIs | 7.3. URIs | |||
[1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
[2] https://httpwg.github.io/ | [2] https://httpwg.github.io/ | |||
[3] https://github.com/httpwg/http-extensions/labels/header-structure | [3] https://github.com/httpwg/http-extensions/labels/header-structure | |||
[4] https://github.com/httpwg/structured-field-tests | [4] https://github.com/httpwg/structured-field-tests | |||
[5] https://github.com/httpwg/wiki/wiki/Structured-Headers | [5] https://github.com/httpwg/wiki/wiki/Structured-Headers | |||
[6] https://github.com/httpwg/structured-field-tests | [6] https://github.com/httpwg/structured-field-tests | |||
Appendix A. Frequently Asked Questions | Appendix A. Frequently Asked Questions | |||
A.1. Why not JSON? | A.1. Why Not JSON? | |||
Earlier proposals for Structured Fields were based upon JSON | Earlier proposals for Structured Fields were based upon JSON | |||
[RFC8259]. However, constraining its use to make it suitable for | [RFC8259]. However, constraining its use to make it suitable for | |||
HTTP header fields required senders and recipients to implement | HTTP header fields required senders and recipients to implement | |||
specific additional handling. | specific additional handling. | |||
For example, JSON has specification issues around large numbers and | 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., [RFC7493]), it cannot be relied upon. | issues is available (e.g., [RFC7493]), it cannot be relied upon. | |||
skipping to change at page 36, line 5 ¶ | skipping to change at page 36, line 5 ¶ | |||
(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 | implementations have no such limits, and even if a limit is | |||
specified, it's likely that some field definition will find a need to | specified, it's likely that some field definition will find a need to | |||
violate it. | violate it. | |||
Because of JSON's broad adoption and implementation, it is difficult | Because of JSON's broad adoption and implementation, it is difficult | |||
to impose such additional constraints across all implementations; | to impose such additional constraints across all implementations; | |||
some deployments would fail to enforce them, thereby harming | some deployments would fail to enforce them, thereby harming | |||
interoperability. In short, if it looks like JSON, people will be | interoperability. In short, if it looks like JSON, people will be | |||
tempted to use a JSON parser / serializer on field values. | tempted to use a JSON parser/serializer on field values. | |||
Since a major goal for Structured Fields is to improve | 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. | format that requires a dedicated parser and serializer. | |||
Additionally, there were widely shared feelings that JSON doesn't | Additionally, there were widely shared feelings that JSON doesn't | |||
"look right" in HTTP fields. | "look right" in HTTP fields. | |||
Appendix B. Implementation Notes | Appendix B. Implementation Notes | |||
skipping to change at page 36, line 28 ¶ | skipping to change at page 36, line 28 ¶ | |||
They need not be functions; for example, it could be implemented as | They need not be functions; for example, it could be implemented as | |||
an object, with methods for each of the different top-level types. | an object, with methods for each of the different top-level types. | |||
For interoperability, it's important that generic implementations be | For interoperability, it's important that generic implementations be | |||
complete and follow the algorithms closely; see Section 1.1. To aid | complete and follow the algorithms closely; see Section 1.1. To aid | |||
this, a common test suite is being maintained by the community at | this, a common test suite is being maintained by the community at | |||
https://github.com/httpwg/structured-field-tests [6]. | https://github.com/httpwg/structured-field-tests [6]. | |||
Implementers should note that Dictionaries and Parameters are order- | Implementers should note that Dictionaries and Parameters are order- | |||
preserving maps. Some fields may not convey meaning in the ordering | preserving maps. Some fields may not convey meaning in the ordering | |||
of these data types, but it should still be exposed so that | of these data types, but it should still be exposed so that it will | |||
applications which need to use it will have it available. | be available to applications that need to use it. | |||
Likewise, implementations should note that it's important to preserve | Likewise, implementations should note that it's important to preserve | |||
the distinction between Tokens and Strings. While most programming | the distinction between Tokens and Strings. While most programming | |||
languages have native types that map to the other types well, it may | languages have native types that map to the other types well, it may | |||
be necessary to create a wrapper "token" object or use a parameter on | be necessary to create a wrapper "token" object or use a parameter on | |||
functions to assure that these types remain separate. | functions to assure that these types remain separate. | |||
The serialization algorithm is defined in a way that it is not | The serialization algorithm is defined in a way that it is not | |||
strictly limited to the data types defined in Section 3 in every | strictly limited to the data types defined in Section 3 in every | |||
case. For example, Decimals are designed to take broader input and | case. For example, Decimals are designed to take broader input and | |||
round to allowed values. | round to allowed values. | |||
Implementations are allowed to limit the allowed size of different | Implementations are allowed to limit the 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 | structure exceeds an implementation limit, that structure fails | |||
parsing or serialisation. | parsing or serialization. | |||
Appendix C. Changes | Appendix C. Changes | |||
_RFC Editor: Please remove this section before publication._ | _RFC Editor: Please remove this section before publication._ | |||
C.1. Since draft-ietf-httpbis-header-structure-18 | C.1. Since draft-ietf-httpbis-header-structure-18 | |||
o Use "sf-" prefix for ABNF, not "sh-". | o Use "sf-" prefix for ABNF, not "sh-". | |||
o Fix indentation in Dictionary serialisation (#1164). | o Fix indentation in Dictionary serialisation (#1164). | |||
skipping to change at page 42, line 33 ¶ | skipping to change at page 42, line 33 ¶ | |||
consideration during the development of this specification. | consideration during the development of this specification. | |||
Thanks also to Ian Clelland, Roy Fielding, Anne van Kesteren, Kazuho | Thanks also to Ian Clelland, Roy Fielding, Anne van Kesteren, Kazuho | |||
Oku, Evert Pot, Julian Reschke, Martin Thomson, Mike West, and | Oku, Evert Pot, Julian Reschke, Martin Thomson, Mike West, and | |||
Jeffrey Yasskin for their contributions. | Jeffrey Yasskin for their contributions. | |||
Authors' Addresses | Authors' Addresses | |||
Mark Nottingham | Mark Nottingham | |||
Fastly | Fastly | |||
Prahran, VIC | ||||
Australia | ||||
Email: mnot@mnot.net | Email: mnot@mnot.net | |||
URI: https://www.mnot.net/ | URI: https://www.mnot.net/ | |||
Poul-Henning Kamp | Poul-Henning Kamp | |||
The Varnish Cache Project | The Varnish Cache Project | |||
Email: phk@varnish-cache.org | Email: phk@varnish-cache.org | |||
End of changes. 157 change blocks. | ||||
234 lines changed or deleted | 241 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/ |