draft-ietf-httpbis-header-structure-18.txt   draft-ietf-httpbis-header-structure-19.txt 
HTTP M. Nottingham HTTP M. Nottingham
Internet-Draft Fastly Internet-Draft Fastly
Intended status: Standards Track P-H. Kamp Intended status: Standards Track P-H. Kamp
Expires: October 21, 2020 The Varnish Cache Project Expires: December 5, 2020 The Varnish Cache Project
April 19, 2020 June 3, 2020
Structured Field Values for HTTP Structured Field Values for HTTP
draft-ietf-httpbis-header-structure-18 draft-ietf-httpbis-header-structure-19
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 1, line 35 skipping to change at page 1, line 35
Discussion of this draft takes place on the HTTP working group Discussion of this draft takes place on the HTTP working group
mailing list (ietf-http-wg@w3.org), which is archived at mailing list (ietf-http-wg@w3.org), which is archived at
https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. https://lists.w3.org/Archives/Public/ietf-http-wg/ [1].
Working Group information can be found at https://httpwg.github.io/ Working Group information can be found at https://httpwg.github.io/
[2]; source code and issues list for this draft can be found at [2]; source code and issues list for this draft can be found at
https://github.com/httpwg/http-extensions/labels/header-structure https://github.com/httpwg/http-extensions/labels/header-structure
[3]. [3].
Tests for implementations are collected at https://github.com/httpwg/ Tests for implementations are collected at https://github.com/httpwg/
structured-header-tests [4]. structured-field-tests [4].
Implementations are tracked at https://github.com/httpwg/wiki/wiki/ Implementations are tracked at https://github.com/httpwg/wiki/wiki/
Structured-Headers [5]. Structured-Headers [5].
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on October 21, 2020. This Internet-Draft will expire on December 5, 2020.
Copyright Notice Copyright Notice
Copyright (c) 2020 IETF Trust and the persons identified as the Copyright (c) 2020 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . . . . . . . . . 9
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 . . . . . . . . . . . . . . . . . . . . . . . 13 3.3.3. Strings . . . . . . . . . . . . . . . . . . . . . . . 14
3.3.4. Tokens . . . . . . . . . . . . . . . . . . . . . . . 14 3.3.4. Tokens . . . . . . . . . . . . . . . . . . . . . . . 15
3.3.5. Byte Sequences . . . . . . . . . . . . . . . . . . . 14 3.3.5. Byte Sequences . . . . . . . . . . . . . . . . . . . 15
3.3.6. Booleans . . . . . . . . . . . . . . . . . . . . . . 15 3.3.6. Booleans . . . . . . . . . . . . . . . . . . . . . . 15
4. Working With Structured Fields in HTTP . . . . . . . . . . . 15 4. Working With Structured Fields in HTTP . . . . . . . . . . . 16
4.1. Serializing Structured Fields . . . . . . . . . . . . . . 15 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 . . . . . . . . . . . . . . . . . 18 4.1.3. Serializing an Item . . . . . . . . . . . . . . . . . 19
4.1.4. Serializing an Integer . . . . . . . . . . . . . . . 19 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 . . . . . . . . . . . . . . . . 20 4.1.6. Serializing a String . . . . . . . . . . . . . . . . 21
4.1.7. Serializing a Token . . . . . . . . . . . . . . . . . 21 4.1.7. Serializing a Token . . . . . . . . . . . . . . . . . 22
4.1.8. Serializing a Byte Sequence . . . . . . . . . . . . . 21 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 . . . . . . . . . . . . . . . . 22 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 . . . . . . . . . . . . . . . . 25 4.2.2. Parsing a Dictionary . . . . . . . . . . . . . . . . 26
4.2.3. Parsing an Item . . . . . . . . . . . . . . . . . . . 26 4.2.3. Parsing an Item . . . . . . . . . . . . . . . . . . . 27
4.2.4. Parsing an Integer or Decimal . . . . . . . . . . . . 28 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 . . . . . . . . . . . . . . . . . . . 30 4.2.6. Parsing a Token . . . . . . . . . . . . . . . . . . . 31
4.2.7. Parsing a Byte Sequence . . . . . . . . . . . . . . . 31 4.2.7. Parsing a Byte Sequence . . . . . . . . . . . . . . . 32
4.2.8. Parsing a Boolean . . . . . . . . . . . . . . . . . . 32 4.2.8. Parsing a Boolean . . . . . . . . . . . . . . . . . . 33
5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 32 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 33
6. Security Considerations . . . . . . . . . . . . . . . . . . . 32 6. Security Considerations . . . . . . . . . . . . . . . . . . . 33
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 32 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 33
7.1. Normative References . . . . . . . . . . . . . . . . . . 32 7.1. Normative References . . . . . . . . . . . . . . . . . . 33
7.2. Informative References . . . . . . . . . . . . . . . . . 33 7.2. Informative References . . . . . . . . . . . . . . . . . 34
7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 34 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Appendix A. Frequently Asked Questions . . . . . . . . . . . . . 34 Appendix A. Frequently Asked Questions . . . . . . . . . . . . . 35
A.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 34 A.1. Why not JSON? . . . . . . . . . . . . . . . . . . . . . . 35
Appendix B. Implementation Notes . . . . . . . . . . . . . . . . 35 Appendix B. Implementation Notes . . . . . . . . . . . . . . . . 36
Appendix C. Changes . . . . . . . . . . . . . . . . . . . . . . 35 Appendix C. Changes . . . . . . . . . . . . . . . . . . . . . . 36
C.1. Since draft-ietf-httpbis-header-structure-17 . . . . . . 36 C.1. Since draft-ietf-httpbis-header-structure-18 . . . . . . 37
C.2. Since draft-ietf-httpbis-header-structure-16 . . . . . . 36 C.2. Since draft-ietf-httpbis-header-structure-17 . . . . . . 37
C.3. Since draft-ietf-httpbis-header-structure-15 . . . . . . 36 C.3. Since draft-ietf-httpbis-header-structure-16 . . . . . . 37
C.4. Since draft-ietf-httpbis-header-structure-14 . . . . . . 36 C.4. Since draft-ietf-httpbis-header-structure-15 . . . . . . 37
C.5. Since draft-ietf-httpbis-header-structure-13 . . . . . . 37 C.5. Since draft-ietf-httpbis-header-structure-14 . . . . . . 38
C.6. Since draft-ietf-httpbis-header-structure-12 . . . . . . 37 C.6. Since draft-ietf-httpbis-header-structure-13 . . . . . . 38
C.7. Since draft-ietf-httpbis-header-structure-11 . . . . . . 37 C.7. Since draft-ietf-httpbis-header-structure-12 . . . . . . 39
C.8. Since draft-ietf-httpbis-header-structure-10 . . . . . . 37 C.8. Since draft-ietf-httpbis-header-structure-11 . . . . . . 39
C.9. Since draft-ietf-httpbis-header-structure-09 . . . . . . 38 C.9. Since draft-ietf-httpbis-header-structure-10 . . . . . . 39
C.10. Since draft-ietf-httpbis-header-structure-08 . . . . . . 38 C.10. Since draft-ietf-httpbis-header-structure-09 . . . . . . 39
C.11. Since draft-ietf-httpbis-header-structure-07 . . . . . . 39 C.11. Since draft-ietf-httpbis-header-structure-08 . . . . . . 40
C.12. Since draft-ietf-httpbis-header-structure-06 . . . . . . 39 C.12. Since draft-ietf-httpbis-header-structure-07 . . . . . . 40
C.13. Since draft-ietf-httpbis-header-structure-05 . . . . . . 39 C.13. Since draft-ietf-httpbis-header-structure-06 . . . . . . 41
C.14. Since draft-ietf-httpbis-header-structure-04 . . . . . . 39 C.14. Since draft-ietf-httpbis-header-structure-05 . . . . . . 41
C.15. Since draft-ietf-httpbis-header-structure-03 . . . . . . 40 C.15. Since draft-ietf-httpbis-header-structure-04 . . . . . . 41
C.16. Since draft-ietf-httpbis-header-structure-02 . . . . . . 40 C.16. Since draft-ietf-httpbis-header-structure-03 . . . . . . 41
C.17. Since draft-ietf-httpbis-header-structure-01 . . . . . . 40 C.17. Since draft-ietf-httpbis-header-structure-02 . . . . . . 41
C.18. Since draft-ietf-httpbis-header-structure-00 . . . . . . 40 C.18. Since draft-ietf-httpbis-header-structure-01 . . . . . . 42
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 40 C.19. Since draft-ietf-httpbis-header-structure-00 . . . . . . 42
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 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 slightly different
skipping to change at page 4, line 30 skipping to change at page 4, line 35
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.
Note that it is not a goal of this document to redefine the syntax of Note that it is not a goal of this document to redefine the syntax of
existing HTTP fields; the mechanisms described herein are only existing HTTP fields; the mechanisms described herein are only
intended to be used with those that explicitly opt into them. intended to be used with fields that explicitly opt into them.
Section 2 describes how to specify a Structured Field. Section 2 describes how to specify a Structured Field.
Section 3 defines a number of abstract data types that can be used in Section 3 defines a number of abstract data types that can be used in
Structured Fields. Structured Fields.
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 therefore
good interoperability. Therefore, an implementation that tried to be good interoperability. Therefore, an implementation that tried to be
"helpful" by being more tolerant of input would make interoperability helpful by being more tolerant of input would make interoperability
worse, since that would create pressure on other implementations to worse, since that would create pressure on other implementations to
implement similar (but likely subtly different) workarounds. 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
skipping to change at page 5, line 27 skipping to change at page 5, line 30
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 rule from [RFC7230]. [RFC5234]. It also includes the tchar and OWS rules from [RFC7230].
When parsing from HTTP fields, implementations MUST follow the When parsing from HTTP fields, implementations MUST have behavior
algorithms, but MAY vary in implementation so as the behaviors are that is indistinguishable from following the algorithms. If there is
indistinguishable from specified behavior. If there is disagreement disagreement between the parsing algorithms and ABNF, the specified
between the parsing algorithms and ABNF, the specified algorithms algorithms take precedence.
take precedence. In some places, the algorithms are "greedy" with
whitespace, but this should not affect conformance.
For serialization to HTTP fields, the ABNF illustrates the range of For serialization to HTTP fields, the ABNF illustrates their expected
acceptable wire representations with as much fidelity as possible, wire representations, and the algorithms define the recommended way
and the algorithms define the recommended way to produce them. to produce them. Implementations MAY vary from the specified
Implementations MAY vary from the specified behavior so long as the behavior so long as the output is still correctly handled by the
output still matches the ABNF. parsing algorithm.
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 a HTTP field as a Structured Field, its authors needs to:
o Reference this specification. Recipients and generators of the o Normatively reference this specification. Recipients and
field need to know that the requirements of this document are in generators of the field need to know that the requirements of this
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 those structures. o Define the semantics of the field value.
o Specify any additional constraints upon the structures used, as o Specify any additional constraints upon the field value, as well
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 allowable
types, and constraints upon them. For example, a header defined as a types, and constraints upon them. For example, a header defined as a
List might have all Integer members, or a mix of types; a header List might have all Integer members, or a mix of types; a header
defined as an Item might allow only Strings, and additionally only defined as an Item might allow only Strings, and additionally only
strings beginning with the letter "Q". Likewise, Inner Lists are strings beginning with the letter "Q", or strings in lowercase.
only valid when a field definition explicitly allows them. Likewise, Inner Lists (Section 3.1.1) are only valid 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
skipping to change at page 7, line 29 skipping to change at page 7, line 31
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 "sh-" 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 for their use.
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<-- --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 a Item Structured Header [RFCxxxx]. Its value MUST be
an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is: an Integer (Section Y.Y of [RFCxxxx]). Its ABNF is:
Foo-Example = sh-integer Foo-Example = sf-integer
Its value indicates the amount of Foo in the message, and MUST Its value indicates the amount of Foo in the message, and MUST
be between 0 and 10, inclusive; other values MUST cause be between 0 and 10, inclusive; other values MUST cause
the entire header field to be ignored. the entire header field to be ignored.
The following parameters are defined: The following parameters are defined:
* A Parameter whose name is "foourl", and whose value is a String * A Parameter whose name is "foourl", and whose value is a String
(Section Y.Y of [RFCxxxx]), conveying the Foo URL (Section Y.Y of [RFCxxxx]), conveying the Foo URL
for the message. See below for processing requirements. for the message. See below for processing requirements.
skipping to change at page 8, line 38 skipping to change at page 8, line 38
of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before
being used. being used.
For example: For example:
Foo-Example: 2; foourl="https://foo.example.com/" Foo-Example: 2; foourl="https://foo.example.com/"
-->8-- -->8--
3. Structured Data Types 3. Structured Data Types
This section defines the abstract value types that can be composed This section defines the abstract types for Structured Fields. The
into Structured Fields. The ABNF provided represents the on-wire ABNF provided represents the on-wire format in HTTP field values.
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 a 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:
sh-list = list-member *( *SP "," *SP list-member ) sf-list = list-member *( OWS "," OWS list-member )
list-member = sh-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 Strings could
look like: look like:
Example-StrListHeader: "foo", "bar", "It was the best of times." Example-StrList: "foo", "bar", "It was the best of times."
An empty List is denoted by not serializing the field at all. An empty List is denoted by not serializing the field at all. This
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
inside a header or trailer section, as per Section 3.2.2 of inside a 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-Hdr: foo, bar
and and
Example-Hdr: foo Example-Hdr: foo
skipping to change at page 9, line 50 skipping to change at page 9, line 51
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 [ sh-item *( 1*SP sh-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 have their
values delimited by a single space. A field whose value is defined values delimited by one or more spaces. A field whose value is
as a List of Inner Lists of Strings could look like: defined as a List of Inner Lists of Strings could look like:
Example-StrListListHeader: ("foo" "bar"), ("baz"), ("bat" "one"), () Example-StrListList: ("foo" "bar"), ("baz"), ("bat" "one"), ()
Note that the last member in this example is an empty Inner List. Note that the last member in this example is an empty Inner List.
A header field whose value is defined as a List of Inner Lists with A header field whose value is defined as a List of Inner Lists with
Parameters at both levels could look like: Parameters at both levels could look like:
Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1 Example-ListListParam: ("foo"; a=1;b=2);lvl=5, ("bar" "baz");lvl=1
Parsers MUST support Inner Lists containing at least 256 members. Parsers MUST support Inner Lists containing at least 256 members.
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-values 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 the Parameters they occur within, and the
values are bare items (i.e., they themselves cannot be parameterized; values are bare items (i.e., they themselves cannot be parameterized;
see Section 3.3). see Section 3.3).
The ABNF for Parameters is: The ABNF for Parameters is:
parameters = *( ";" *SP parameter ) parameters = *( ";" *SP parameter )
parameter = param-name [ "=" param-value ] parameter = param-name [ "=" param-value ]
param-name = key param-name = key
key = ( lcalpha / "*" ) key = ( lcalpha / "*" )
*( lcalpha / DIGIT / "_" / "-" / "." / "*" ) *( lcalpha / DIGIT / "_" / "-" / "." / "*" )
lcalpha = %x61-7A ; a-z lcalpha = %x61-7A ; a-z
param-value = bare-item param-value = bare-item
A parameter is separated from its Item or Inner List and other Note that Parameters are ordered as serialized, and Parameter keys
parameters by a semicolon. For example: cannot contain uppercase letters. A parameter is separated from its
Item or Inner List and other parameters by a semicolon. For example:
Example-ParamListHeader: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w
Parameters whose value is Boolean true MUST omit that value when Example-ParamList: abc;a=1;b=2; cde_456, (ghi;jk=4 l);q="9";r=w
serialized. For example:
Example-IntHeader: 1; a; b=?0 Parameters whose value is Boolean (see Section 3.3.6) true MUST omit
that value when serialized. For example, the "a" parameter here is
true, while the "b" parameter is false:
Example-Int: 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 types and cardinality of individual specifications can constrain the order of individual Parameters, as
parameter names and values as they require. 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 name-value pairs, where the names
are short, textual strings and the values are items (Section 3.3) or are short textual strings and the values are Items (Section 3.3) or
arrays of items, both of which can be 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 names 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 name. Specifications MAY use either means of accessing the
members. members.
The ABNF for Dictionaries is: The ABNF for Dictionaries is:
sh-dictionary = dict-member *( *SP "," *SP dict-member ) sf-dictionary = dict-member *( OWS "," OWS dict-member )
dict-member = member-name [ "=" member-value ] dict-member = member-name [ "=" member-value ]
member-name = key member-name = key
member-value = sh-item / inner-list member-value = sf-item / inner-list
Members are separated by a comma with optional whitespace, while Members are ordered as serialized, and separated by a comma with
names and values are separated by "=" (without whitespace). For optional whitespace. Member names cannot contain uppercase
example: characters. Names and values are separated by "=" (without
whitespace). For example:
Example-DictHeader: en="Applepie", da=:w4ZibGV0w6ZydGU=: Example-Dict: en="Applepie", da=:w4ZibGV0w6ZydGU=:
Members whose value is Boolean true MUST omit that value when Note that in this example, the final "=" is due to the inclusion of a
serialized. For example, here both "b" and "c" are true: Byte Sequence; see Section 3.3.5.
Example-DictHeader: a=?0, b, c; foo=bar 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
true:
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-DictListHeader: rating=1.5, feelings=(joy sadness) Example-DictList: rating=1.5, feelings=(joy sadness)
A Dictionary with a mix of singular and list values, 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-MixDict: 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. entire field. This implies that fields defined as Dictionaries have
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 member Dictionaries by specifying the allowed type(s) for individual members
names, as well as whether their presence is required or optional. by their names, as well as whether their presence is required or
Recipients MUST ignore names that are undefined or unknown, unless optional. Recipients MUST ignore names that are undefined or
the field's specification specifically disallows them. unknown, unless the field's specification specifically 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 inside a header or trailer section; for example, the following
are equivalent: are equivalent:
Example-Hdr: foo=1, bar=2 Example-Hdr: foo=1, bar=2
and and
Example-Hdr: foo=1 Example-Hdr: foo=1
Example-Hdr: bar=2 Example-Hdr: 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 name/value
pairs, and names with at least 64 characters. pairs, and names with at least 64 characters. Field specifications
can constrain the order of individual Dictionary members, as well as
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 a Integer (Section 3.3.1), Decimal (Section 3.3.2),
String (Section 3.3.3), Token (Section 3.3.4), Byte Sequence String (Section 3.3.3), Token (Section 3.3.4), Byte Sequence
(Section 3.3.5), or Boolean (Section 3.3.6). It can have associated (Section 3.3.5), or Boolean (Section 3.3.6). It can have associated
Parameters (Section 3.1.2). Parameters (Section 3.1.2).
The ABNF for Items is: The ABNF for Items is:
sh-item = bare-item parameters sf-item = bare-item parameters
bare-item = sh-integer / sh-decimal / sh-string / sh-token bare-item = sf-integer / sf-decimal / sf-string / sf-token
/ sh-binary / sh-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-IntItemHeader: 5
or with Parameters: or with Parameters:
Example-IntItemHeader: 5; foo=bar Example-IntItem: 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:
sh-integer = ["-"] 1*15DIGIT sf-integer = ["-"] 1*15DIGIT
For example: For example:
Example-IntegerHeader: 42 Example-Integer: 42
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
(Section 3.3.5), or a parameter on an Integer that acts as a scaling
factor.
While it is possible to serialise Integers with leading zeros (e.g.,
"0002", "-01") and signed zero ("-0"), these distinctions may not be
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
at most three digits. at most three digits.
The ABNF for decimals is: The ABNF for decimals is:
sh-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-DecimalHeader: 4.5 Example-Decimal: 4.5
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
signed zero (e.g., "-0.0"), these distinctions may not be preserved
by implementations.
Note that the serialisation algorithm (Section 4.1.5) rounds input Note that the serialisation 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 serialisation.
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:
sh-string = DQUOTE *(chr) DQUOTE sf-string = DQUOTE *chr DQUOTE
chr = unescaped / escaped chr = unescaped / escaped
unescaped = %x20-21 / %x23-5B / %x5D-7E unescaped = %x20-21 / %x23-5B / %x5D-7E
escaped = "\" ( DQUOTE / "\" ) escaped = "\" ( DQUOTE / "\" )
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-StringHeader: "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 - field
values do not require it. 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
skipping to change at page 14, line 37 skipping to change at page 15, line 12
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:
sh-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" )
For example:
Example-Token: foo123/456
Parsers MUST support Tokens with at least 512 characters. Parsers MUST support Tokens with at least 512 characters.
Note that Token allows the same characters as the "token" ABNF rule Note that Token allows the same characters as the "token" ABNF rule
defined in [RFC7230], with the exceptions that the first character is defined in [RFC7230], with the exceptions that the first character is
required to be either ALPHA or "*", and ":" and "/" are also allowed required to be either ALPHA or "*", and ":" and "/" are also allowed
in subsequent characters. in subsequent characters.
3.3.5. Byte Sequences 3.3.5. Byte Sequences
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:
sh-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-BinaryHdr: :cHJldGVuZCB0aGlzIGlzIGJpbmFyeSBjb250ZW50Lg==: Example-Binary: :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:
sh-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-BoolHdr: ?1 Example-Bool: ?1
Note that in Dictionary (Section 3.2) and Parameter (Section 3.1.2)
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
field values, and protocols compatible with them (e.g., in HTTP/2 textual HTTP field values and other encodings compatible with them
[RFC7540] before HPACK [RFC7541] is applied). (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 a 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).
skipping to change at page 18, line 23 skipping to change at page 18, line 51
an ASCII string suitable for use in a HTTP field value. an ASCII string suitable for use in a 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_name with a value of (member_value, parameters)
in input_dictionary: in input_dictionary:
1. Append the result of running Serializing a Key 1. Append the result of running Serializing a Key
(Section 4.1.1.3) with member's member_name to output. (Section 4.1.1.3) with member's member_name to output.
3. 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.
4. Otherwise: 3. Otherwise:
1. Append "=" to output. 1. Append "=" to output.
2. If member_value is an array, append the result of running 2. 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.
3. Otherwise, append the result of running Serializing an Item 3. Otherwise, append the result of running Serializing an
(Section 4.1.3) with (member_value, parameters) to output. Item (Section 4.1.3) with (member_value, parameters) to
output.
5. If more members remain in input_dictionary: 4. If more members remain in input_dictionary:
1. Append "," to output. 1. Append "," to output.
2. Append a single SP to output. 2. Append a single SP to output.
6. 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 a 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.
skipping to change at page 21, line 8 skipping to change at page 21, line 36
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 a 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. (i.e., not in VCHAR or SP), fail serialization.
3. Let output be an empty string. 3. Let output be the string DQUOTE.
4. Append DQUOTE to output.
5. 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.
6. Append DQUOTE to output. 5. Append DQUOTE to output.
7. 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 a 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
skipping to change at page 23, line 20 skipping to change at page 23, line 50
5. If field_type is "item", let output be the result of running 5. If field_type is "item", let output be the result of running
Parsing an Item (Section 4.2.3) with input_string. Parsing an Item (Section 4.2.3) with input_string.
6. Discard any leading 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 lines in the When generating input_bytes, parsers MUST combine all field lines in
same section (header or trailer) that case-insensitively match the the same section (header or trailer) that case-insensitively match
field name into one comma-separated field-value, as per [RFC7230], the field name into one comma-separated field-value, as per
Section 3.2.2; this assures that the entire field value is processed
correctly. [RFC7230], Section 3.2.2; this assures that the entire field value is
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. instances. The parsing algorithms for both types allow tab
characters, since these might be used to combine field lines by some
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 comma(s) and whitespace inserted upon combination
will become part of the string output by the parser. Since will become part of the string output by the parser. Since
concatenation might be done by an upstream intermediary, the results concatenation might be done by an upstream intermediary, the results
are not under the control of the serializer or the parser. are not under the control of the serializer or the parser, even when
they are both 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
field lines, when one of those lines does not parse as that field.
For example, a parsing handling an Example-String field that's
defined as a sf-string is allowed to fail when processing this field
section:
Example-String: "foo
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 header field from a message before required to strip a failing field from a message before forwarding
forwarding it. it.
4.2.1. Parsing a List 4.2.1. Parsing a List
Given an ASCII string as input_string, return an array of Given an ASCII string as input_string, return an array of
(item_or_inner_list, parameters) tuples. input_string is modified to (item_or_inner_list, parameters) tuples. input_string is modified to
remove the parsed value. remove the parsed value.
1. Let members be an empty array. 1. Let members be an empty array.
2. While input_string is not empty: 2. While input_string is not empty:
1. Append the result of running Parsing an Item or Inner List 1. Append the result of running Parsing an Item or Inner List
(Section 4.2.1.1) with input_string to members. (Section 4.2.1.1) with input_string to members.
2. Discard any leading SP characters from input_string. 2. Discard any leading OWS characters from input_string.
3. If input_string is empty, return members. 3. If input_string is empty, return members.
4. Consume the first character of input_string; if it is not 4. Consume the first character of input_string; if it is not
",", fail parsing. ",", fail parsing.
5. Discard any leading SP characters from input_string. 5. Discard any leading OWS characters from input_string.
6. If input_string is empty, there is a trailing comma; fail 6. If input_string is empty, there is a trailing comma; fail
parsing. parsing.
3. No structured data has been found; return members (which is 3. No structured data has been found; return members (which is
empty). empty).
4.2.1.1. Parsing an Item or Inner List 4.2.1.1. Parsing an Item or Inner List
Given an ASCII string as input_string, return the tuple Given an ASCII string as input_string, return the tuple
skipping to change at page 26, line 18 skipping to change at page 27, line 9
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. Add name this_key with value member to dictionary. If
dictionary already contains a name this_key (comparing dictionary already contains a name this_key (comparing
character-for-character), overwrite its value. character-for-character), overwrite its value.
5. Discard any leading SP characters from input_string. 5. Discard any leading OWS characters from input_string.
6. If input_string is empty, return dictionary. 6. If input_string is empty, return dictionary.
7. Consume the first character of input_string; if it is not 7. Consume the first character of input_string; if it is not
",", fail parsing. ",", fail parsing.
8. Discard any leading SP characters from input_string. 8. Discard any leading OWS characters from input_string.
9. If input_string is empty, there is a trailing comma; fail 9. If input_string is empty, there is a trailing comma; fail
parsing. 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
the effect of ignoring all but the last instance.
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.
2. Let parameters be the result of running Parsing Parameters 2. Let parameters be the result of running Parsing Parameters
skipping to change at page 28, line 14 skipping to change at page 29, line 5
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. Append key param_name with value param_value to parameters.
If parameters already contains a name param_name (comparing If parameters already contains a name param_name (comparing
character-for-character), overwrite its value. character-for-character), overwrite its value.
3. Return parameters. 3. Return parameters.
Note that when duplicate Parameter keys are encountered, this has the
effect of ignoring all but the last instance.
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 31, line 44 skipping to change at page 32, line 39
6. If b64_content contains a character not included in ALPHA, DIGIT, 6. If b64_content contains a character not included in ALPHA, DIGIT,
"+", "/" and "=", fail parsing. "+", "/" and "=", fail parsing.
7. Let binary_content be the result of Base 64 Decoding [RFC4648] 7. Let binary_content be the result of Base 64 Decoding [RFC4648]
b64_content, synthesizing padding if necessary (note the b64_content, synthesizing padding if necessary (note the
requirements about recipient behavior below). requirements about recipient behavior below).
8. Return binary_content. 8. Return binary_content.
Because some implementations of base64 do not allow reject of encoded Because some implementations of base64 do not allow rejection of
data that is not properly "=" padded (see [RFC4648], Section 3.2), encoded data that is not properly "=" padded (see [RFC4648],
parsers SHOULD NOT fail when it is not present, unless they cannot be Section 3.2), parsers SHOULD NOT fail when "=" padding is not
configured to do so. present, 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 it is present, unless they cannot be parsers SHOULD NOT fail when non-zero pad bits are present, unless
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 [RFC4648],
Section 3.1 and 3.3; therefore, parsers MUST fail on characters Section 3.1 and 3.3; therefore, parsers MUST fail on characters
outside the base64 alphabet, and on line feeds in encoded data. outside the base64 alphabet, and on line feeds in encoded data.
4.2.8. Parsing a Boolean 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.
skipping to change at page 34, line 22 skipping to change at page 35, line 17
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-header-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-header-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.
skipping to change at page 35, line 28 skipping to change at page 36, line 24
Appendix B. Implementation Notes Appendix B. Implementation Notes
A generic implementation of this specification should expose the top- A generic implementation of this specification should expose the top-
level serialize (Section 4.1) and parse (Section 4.2) functions. level serialize (Section 4.1) and parse (Section 4.2) functions.
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-header-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
applications which need to use it will have it available. applications which need to use it will have it available.
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
structures, subject to the minimums defined for each type. When a
structure exceeds an implementation limit, that structure fails
parsing or serialisation.
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-17 C.1. Since draft-ietf-httpbis-header-structure-18
o Use "sf-" prefix for ABNF, not "sh-".
o Fix indentation in Dictionary serialisation (#1164).
o Add example for Token; tweak example field names (#1147).
o Editorial improvements. o Editorial improvements.
C.2. Since draft-ietf-httpbis-header-structure-16 o Note that exceeding implementation limits implies failure.
o Talk about specifying order of Dictionary members and Parameters,
not cardinality.
o Allow (but don't require) parsers to fail when a single field line
isn't valid.
o Note that some aspects of Integers and Decimals are not
necessarily preserved.
o Allow Lists and Dictionaries to be delimited by OWS, rather than
*SP, to make parsing more robust.
C.2. Since draft-ietf-httpbis-header-structure-17
o Editorial improvements.
C.3. Since draft-ietf-httpbis-header-structure-16
o Editorial improvements. o Editorial improvements.
o Discussion on forwards compatibility. o Discussion on forwards compatibility.
C.3. Since draft-ietf-httpbis-header-structure-15 C.4. Since draft-ietf-httpbis-header-structure-15
o Editorial improvements. o Editorial improvements.
o Use HTTP field terminology more consistently, in line with recent o Use HTTP field terminology more consistently, in line with recent
changes to HTTP-core. changes to HTTP-core.
o String length requirements apply to decoded strings (#1051). o String length requirements apply to decoded strings (#1051).
o Correctly round decimals in serialisation (#1043). o Correctly round decimals in serialisation (#1043).
o Clarify input to serialisation algorithms (#1055). o Clarify input to serialisation algorithms (#1055).
o Omitted True dictionary value can have parameters (#1083). o Omitted True dictionary value can have parameters (#1083).
o Keys can now start with '*' (#1068). o Keys can now start with '*' (#1068).
C.4. Since draft-ietf-httpbis-header-structure-14 C.5. Since draft-ietf-httpbis-header-structure-14
o Editorial improvements. o Editorial improvements.
o Allow empty dictionary values (#992). o Allow empty dictionary values (#992).
o Change value of omitted parameter value to True (#995). o Change value of omitted parameter value to True (#995).
o Explain more about splitting dictionaries and lists across header o Explain more about splitting dictionaries and lists across header
instances (#997). instances (#997).
skipping to change at page 37, line 14 skipping to change at page 38, line 38
o Handle duplicate dictionary and parameter keys by overwriting o Handle duplicate dictionary and parameter keys by overwriting
their values, rather than failing (#997). their values, rather than failing (#997).
o Allow "." in key (#1027). o Allow "." in key (#1027).
o Check first character of key in serialisation (#1037). o Check first character of key in serialisation (#1037).
o Talk about greasing headers (#1015). o Talk about greasing headers (#1015).
C.5. Since draft-ietf-httpbis-header-structure-13 C.6. Since draft-ietf-httpbis-header-structure-13
o Editorial improvements. o Editorial improvements.
o Define "structured header name" and "structured header value" o Define "structured header name" and "structured header value"
terms (#908). terms (#908).
o Corrected text about valid characters in strings (#931). o Corrected text about valid characters in strings (#931).
o Removed most instances of the word "textual", as it was redundant o Removed most instances of the word "textual", as it was redundant
(#915). (#915).
o Allowed parameters on Items and Inner Lists (#907). o Allowed parameters on Items and Inner Lists (#907).
o Expand the range of characters in token (#961). o Expand the range of characters in token (#961).
o Disallow OWS before ";" delimiter in parameters (#961). o Disallow OWS before ";" delimiter in parameters (#961).
C.6. Since draft-ietf-httpbis-header-structure-12 C.7. Since draft-ietf-httpbis-header-structure-12
o Editorial improvements. o Editorial improvements.
o Reworked float serialisation (#896). o Reworked float serialisation (#896).
o Don't add a trailing space in inner-list (#904). o Don't add a trailing space in inner-list (#904).
C.7. Since draft-ietf-httpbis-header-structure-11 C.8. Since draft-ietf-httpbis-header-structure-11
o Allow * in key (#844). o Allow * in key (#844).
o Constrain floats to six digits of precision (#848). o Constrain floats to six digits of precision (#848).
o Allow dictionary members to have parameters (#842). o Allow dictionary members to have parameters (#842).
C.8. Since draft-ietf-httpbis-header-structure-10 C.9. Since draft-ietf-httpbis-header-structure-10
o Update abstract (#799). o Update abstract (#799).
o Input and output are now arrays of bytes (#662). o Input and output are now arrays of bytes (#662).
o Implementations need to preserve difference between token and o Implementations need to preserve difference between token and
string (#790). string (#790).
o Allow empty dictionaries and lists (#781). o Allow empty dictionaries and lists (#781).
o Change parameterized lists to have primary items (#797). o Change parameterized lists to have primary items (#797).
o Allow inner lists in both dictionaries and lists; removes lists of o Allow inner lists in both dictionaries and lists; removes lists of
lists (#816). lists (#816).
o Subsume Parameterised Lists into Lists (#839). o Subsume Parameterised Lists into Lists (#839).
C.9. Since draft-ietf-httpbis-header-structure-09 C.10. Since draft-ietf-httpbis-header-structure-09
o Changed Boolean from T/F to 1/0 (#784). o Changed Boolean from T/F to 1/0 (#784).
o Parameters are now ordered maps (#765). o Parameters are now ordered maps (#765).
o Clamp integers to 15 digits (#737). o Clamp integers to 15 digits (#737).
C.10. Since draft-ietf-httpbis-header-structure-08 C.11. Since draft-ietf-httpbis-header-structure-08
o Disallow whitespace before items properly (#703). o Disallow whitespace before items properly (#703).
o Created "key" for use in dictionaries and parameters, rather than o Created "key" for use in dictionaries and parameters, rather than
relying on identifier (#702). Identifiers have a separate minimum relying on identifier (#702). Identifiers have a separate minimum
supported size. supported size.
o Expanded the range of special characters allowed in identifier to o Expanded the range of special characters allowed in identifier to
include all of ALPHA, ".", ":", and "%" (#702). include all of ALPHA, ".", ":", and "%" (#702).
skipping to change at page 39, line 5 skipping to change at page 40, line 29
o Gave better names for referring specs to use in Parameterised o Gave better names for referring specs to use in Parameterised
Lists (#720). Lists (#720).
o Added Lists of Lists (#721). o Added Lists of Lists (#721).
o Rename Identifier to Token (#725). o Rename Identifier to Token (#725).
o Add implementation guidance (#727). o Add implementation guidance (#727).
C.11. Since draft-ietf-httpbis-header-structure-07 C.12. Since draft-ietf-httpbis-header-structure-07
o Make Dictionaries ordered mappings (#659). o Make Dictionaries ordered mappings (#659).
o Changed "binary content" to "byte sequence" to align with Infra o Changed "binary content" to "byte sequence" to align with Infra
specification (#671). specification (#671).
o Changed "mapping" to "map" for #671. o Changed "mapping" to "map" for #671.
o Don't fail if byte sequences aren't "=" padded (#658). o Don't fail if byte sequences aren't "=" padded (#658).
o Add Booleans (#683). o Add Booleans (#683).
o Allow identifiers in items again (#629). o Allow identifiers in items again (#629).
o Disallowed whitespace before items (#703). o Disallowed whitespace before items (#703).
o Explain the consequences of splitting a string across multiple o Explain the consequences of splitting a string across multiple
headers (#686). headers (#686).
C.12. Since draft-ietf-httpbis-header-structure-06 C.13. Since draft-ietf-httpbis-header-structure-06
o Add a FAQ. o Add a FAQ.
o Allow non-zero pad bits. o Allow non-zero pad bits.
o Explicitly check for integers that violate constraints. o Explicitly check for integers that violate constraints.
C.13. Since draft-ietf-httpbis-header-structure-05 C.14. Since draft-ietf-httpbis-header-structure-05
o Reorganise specification to separate parsing out. o Reorganise specification to separate parsing out.
o Allow referencing specs to use ABNF. o Allow referencing specs to use ABNF.
o Define serialisation algorithms. o Define serialisation algorithms.
o Refine relationship between ABNF, parsing and serialisation o Refine relationship between ABNF, parsing and serialisation
algorithms. algorithms.
C.14. Since draft-ietf-httpbis-header-structure-04 C.15. Since draft-ietf-httpbis-header-structure-04
o Remove identifiers from item. o Remove identifiers from item.
o Remove most limits on sizes. o Remove most limits on sizes.
o Refine number parsing. o Refine number parsing.
C.15. Since draft-ietf-httpbis-header-structure-03 C.16. Since draft-ietf-httpbis-header-structure-03
o Strengthen language around failure handling. o Strengthen language around failure handling.
C.16. Since draft-ietf-httpbis-header-structure-02 C.17. Since draft-ietf-httpbis-header-structure-02
o Split Numbers into Integers and Floats. o Split Numbers into Integers and Floats.
o Define number parsing. o Define number parsing.
o Tighten up binary parsing and give it an explicit end delimiter. o Tighten up binary parsing and give it an explicit end delimiter.
o Clarify that mappings are unordered. o Clarify that mappings are unordered.
o Allow zero-length strings. o Allow zero-length strings.
o Improve string parsing algorithm. o Improve string parsing algorithm.
o Improve limits in algorithms. o Improve limits in algorithms.
o Require parsers to combine header fields before processing. o Require parsers to combine header fields before processing.
o Throw an error on trailing garbage. o Throw an error on trailing garbage.
C.17. Since draft-ietf-httpbis-header-structure-01 C.18. Since draft-ietf-httpbis-header-structure-01
o Replaced with draft-nottingham-structured-headers. o Replaced with draft-nottingham-structured-headers.
C.18. Since draft-ietf-httpbis-header-structure-00 C.19. Since draft-ietf-httpbis-header-structure-00
o Added signed 64bit integer type. o Added signed 64bit integer type.
o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1- o Drop UTF8, and settle on BCP137 ::EmbeddedUnicodeChar for h1-
unicode-string. unicode-string.
o Change h1_blob delimiter to ":" since "'" is valid t_char o Change h1_blob delimiter to ":" since "'" is valid t_char
Acknowledgements Acknowledgements
 End of changes. 114 change blocks. 
197 lines changed or deleted 275 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/