diff --git a/draft-ietf-httpbis-rfc6265bis-19/draft-ietf-httpbis-cache-groups.html b/draft-ietf-httpbis-rfc6265bis-19/draft-ietf-httpbis-cache-groups.html new file mode 100644 index 000000000..f38c98b9d --- /dev/null +++ b/draft-ietf-httpbis-rfc6265bis-19/draft-ietf-httpbis-cache-groups.html @@ -0,0 +1,1441 @@ + + +
+ + + +Internet-Draft | +HTTP Cache Groups | +January 2025 | +
Nottingham | +Expires 11 July 2025 | +[Page] | +
This specification introduces a means of describing the relationships between stored responses in HTTP caches, "grouping" them by associating a stored response with one or more opaque strings.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-cache-groups/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/cache-groups.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+HTTP caching [HTTP-CACHING] operates at the granularity of a single resource; the freshness of one stored response does not affect that of others. This granularity can make caching more efficient -- for example, when a page is composed of many assets that have different requirements for caching.¶
+However, there are also cases where the relationship between stored responses could be used to improve cache efficiency.¶
+For example, it is often necessary to invalidate a set of related resources. This might be because a state-changing request has side effects on other resources, or it might be purely for administrative convenience (e.g., "invalidate this part of the site"). Grouping responses together provides a dedicated way to express these relationships, instead of relying on things like URL structure.¶
+In addition to sharing invalidation events, the relationships indicated by grouping can also be used by caches to optimise their operation; for example, it could be used to inform the operation of cache eviction algorithms.¶
+Section 2 introduces a means of describing the relationships between a set of stored responses in HTTP caches by associating them with one or more opaque strings. It also describes how caches can use that information to apply invalidation events to members of a group.¶
+Section 3 introduces one new source of such events: a HTTP response header that allows a state-changing response to trigger a group invalidation.¶
+These mechanisms operate within a single cache, across the stored responses associated with a single origin server. They do not address this issues of synchronising state between multiple caches (e.g., in a hierarchy or mesh), nor do they facilitate association of stored responses from disparate origins.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+This specification uses the following terminology from [STRUCTURED-FIELDS]: List, String, Parameter.¶
+The Cache-Groups HTTP Response Header is a List of Strings [STRUCTURED-FIELDS]. Each member of the list is an opaque value that identifies a group that the response belongs to.¶
+ +The ordering of members is not significant. Unrecognised Parameters MUST be ignored.¶
+Implementations MUST support at least 128 groups in a field value, with up to at least 128 characters in each member. Note that generic limitations on HTTP field lengths may constrain the size of this field value in practice.¶
+Two responses stored in the same cache are considered to have the same group when all of the following conditions are met:¶
+They both contain a Cache-Groups response header field that contains the same String (in any position in the List), when compared character-by-character.¶
+The both share the same URI origin (per Section 4.3.1 of [HTTP]).¶
+A cache that invalidates a stored response MAY invalidate any stored responses that share groups (per Section 2.1) with that response.¶
+Cache extensions can explicitly strengthen the requirement above. For example, a targeted cache control header field [TARGETED] might specify that caches processing it are required to invalidate such responses.¶
+The Cache-Group-Invalidation response header field is a List of Strings [STRUCTURED-FIELDS]. Each member of the list is an opaque value that identifies a group that the response invalidates, per Section 2.2.1.¶
+For example, a POST request that has side effects on two cache groups could indicate that stored responses associated with either or both of those groups should be invalidated with:¶
+ +The Cache-Group-Invalidation header field MUST be ignored on responses to requests that have a safe method (e.g., GET; see Section 9.2.1 of [HTTP]).¶
+A cache that receives a Cache-Group-Invalidation header field on a response to an unsafe request MAY invalidate any stored responses that share groups (per Section 2.1) with any of the listed groups.¶
+Cache extensions can explicitly strengthen the requirement above. For example, a targeted cache control header field [TARGETED] might specify that caches processing it are required to respect the Cache-Group-Invalidation signal.¶
+The ordering of members is not significant. Unrecognised Parameters MUST be ignored.¶
+Implementations MUST support at least 128 groups in a field value, with up to at least 128 characters in each member. Note that generic limitations on HTTP field lengths may constrain the size of this field value in practice.¶
+IANA should perform the following tasks:¶
+Enter the following into the Hypertext Transfer Protocol (HTTP) Field Name Registry:¶
+ +This mechanism allows resources that share an origin to invalidate each other. Because of this, +origins that represent multiple parties (sometimes referred to as "shared hosting") might allow +one party to group its resources with those of others, or to send signals which have side effects upon them.¶
+Shared hosts that wish to mitigate these risks can control access to the header fields defined in this specification.¶
+Thanks to Stephen Ludin for his review and suggestions.¶
+Internet-Draft | +Compression Dictionary Transport | +January 2025 | +
Meenan & Weiss | +Expires 11 July 2025 | +[Page] | +
This document specifies a mechanism for dictionary-based compression in the +Hypertext Transfer Protocol (HTTP). By utilizing this technique, clients and +servers can reduce the size of transmitted data, leading to improved performance +and reduced bandwidth consumption. This document extends existing HTTP compression +methods and provides guidelines for the delivery and use of compression +dictionaries within the HTTP protocol.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-compression-dictionary/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/compression-dictionary.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+This specification defines a mechanism for using designated [HTTP] responses +as an external dictionary for future HTTP responses for compression schemes +that support using external dictionaries (e.g., Brotli [RFC7932] and +Zstandard [RFC8878]).¶
+This document describes the HTTP headers used for negotiating dictionary usage +and registers content encoding values for compressing with Brotli and Zstandard +using a negotiated dictionary.¶
+The negotiation of dictionary usage leverages HTTP's content negotiation +(see Section 12 of [HTTP]) and is usable with all versions of HTTP.¶
+Any HTTP response can be specified to be used as a compression dictionary for +future HTTP requests which provides a lot of flexibility. There are two common +use cases that are seen frequently:¶
+Using a previous version of a resource as a dictionary for a newer version +enables delivery of a delta-compressed version of the changes, usually +resulting in significantly smaller responses than can be achieved by +compression alone.¶
+For example:¶
+ +If several resources share common patterns in their responses then it can be +useful to reference an external dictionary that contains those common patterns, +effectively compressing them out of the responses. Some examples of this are +common template HTML for similar pages across a site and common keys and values +in API calls.¶
+For example:¶
+ +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+This document uses the following terminology from Section 3 of +[STRUCTURED-FIELDS] to specify syntax and parsing: Dictionary, String, +Inner List, Token, and Byte Sequence.¶
+This document uses the line folding strategies described in [FOLDING].¶
+This document also uses terminology from [HTTP] and [HTTP-CACHING].¶
+When responding to a HTTP Request, a server can advertise that the response can +be used as a dictionary for future requests for URLs that match the rules +specified in the Use-As-Dictionary response header.¶
+The Use-As-Dictionary response header is a Structured Field +[STRUCTURED-FIELDS] Dictionary with values for "match", "match-dest", "id", +and "type".¶
+The "match" value of the Use-As-Dictionary header is a String value that +provides the URL Pattern to use for request matching (see [URLPATTERN]).¶
+The URL Pattern used for matching does not support using regular expressions.¶
+The following algorithm is used to validate that a given String value is a +valid URL Pattern that does not use regular expressions and is for the same +Origin (Section 4.3.1 of [HTTP]) as the dictionary. It will return TRUE +for a valid match pattern and FALSE for an invalid pattern that MUST NOT be +used:¶
+Let MATCH be the value of "match" for the given dictionary.¶
+Let URL be the URL of the dictionary request.¶
+Let PATTERN be a URL pattern created by running the steps to create a +URL pattern by setting input=MATCH, and baseURL=URL (see +Part "create" of [URLPATTERN]).¶
+If the result of running the "has regexp groups" steps for PATTERN returns +TRUE then return FALSE (see Part "has regexp groups" of [URLPATTERN]).¶
+Return TRUE.¶
+The "match" value is required and MUST be included in the +Use-As-Dictionary response header for the dictionary to be considered valid.¶
+Operating at the HTTP-level, the specified match patterns will operate on the +percent-encoded version of the URL path (see Section 2 of [URL]).¶
+For example the URL "http://www.example.com/düsseldorf" would be encoded as +"http://www.example.com/d%C3%BCsseldorf" and a relevant match pattern would be:¶
+ +The "match-dest" value of the Use-As-Dictionary header is an Inner List of +String values that provides a list of Fetch request destinations for the +dictionary to match (see Part "destination" of [FETCH]).¶
+An empty list for "match-dest" MUST match all destinations.¶
+For clients that do not support request destinations, the client MUST treat it +as an empty list and match all destinations.¶
+The "match-dest" value is optional and defaults to an empty list.¶
+The "id" value of the Use-As-Dictionary header is a String value that specifies +a server identifier for the dictionary. If an "id" value is present and has a +string length longer than zero then it MUST be sent to the server in a +"Dictionary-ID" request header when the client sends an "Available-Dictionary" +request header for the same dictionary (see Section 2.2).¶
+The server identifier MUST be treated as an opaque string by the client.¶
+The server identifier MUST NOT be relied upon by the server to guarantee the +contents of the dictionary. The dictionary hash MUST be validated before use.¶
+The "id" value string length (after any decoding) supports up to 1024 +characters.¶
+The "id" value is optional and defaults to the empty string.¶
+The "type" value of the Use-As-Dictionary header is a Token value that +describes the file format of the supplied dictionary.¶
+"raw" is defined as a dictionary format which represents an unformatted blob of +bytes suitable for any compression scheme to use.¶
+If a client receives a dictionary with a type that it does not understand, it +MUST NOT use the dictionary.¶
+The "type" value is optional and defaults to "raw".¶
+A response that contained a response header:¶
+ +Would specify matching any document request for a URL with a path prefix of +/product/ on the same Origin (Section 4.3.1 of [HTTP]) as the original +request.¶
+A response that contained a response header:¶
+ +Would match any path that starts with "/app/" and ends with "/main.js".¶
+When a HTTP client makes a request for a resource for which it has an +appropriate dictionary, it can add a "Available-Dictionary" request header +to the request to indicate to the server that it has a dictionary available to +use for compression.¶
+The "Available-Dictionary" request header is a Structured Field +[STRUCTURED-FIELDS] Byte Sequence containing the [SHA-256] hash of the +contents of a single available dictionary.¶
+The client MUST only send a single "Available-Dictionary" request header +with a single hash value for the best available match that it has available.¶
+For example:¶
+ +To be considered as a match, the dictionary resource MUST be either fresh +[HTTP-CACHING] or allowed to be served stale (see eg [RFC5861]).¶
+When a dictionary is stored as a result of a "Use-As-Dictionary" directive, it +includes a "match" string and optional "match-dest" string that are used to +match an outgoing request from a client to the available dictionaries.¶
+To see if an outbound request matches a given dictionary, the following +algorithm will return TRUE for a successful match and FALSE for no-match:¶
+If the current client supports request destinations and a "match-dest" +string was provided with the dictionary:¶
+ +Let BASEURL be the URL of the dictionary request.¶
+Let URL represent the URL of the outbound request being checked.¶
+If the Origin of BASEURL and the Origin of URL are not the same, return +FALSE (see Section 4.3.1 of [HTTP]).¶
+Let MATCH be the value of "match" for the given dictionary.¶
+Let PATTERN be a URL pattern created by running the steps to create a +URL pattern by setting input=MATCH, and baseURL=URL (see +Part "create" of [URLPATTERN]).¶
+Return the result of running the "match" steps on PATTERN with input=URL +which will check for a match between the request URL and the supplied "match" +string (see Part "match" of [URLPATTERN]).¶
+When there are multiple dictionaries that match a given request URL, the client +MUST pick a single dictionary using the following rules:¶
+For clients that support request destinations, a dictionary that specifies +and matches a "match-dest" takes precedence over a match that does not use a +destination.¶
+Given equivalent destination precedence, the dictionary with the longest +"match" takes precedence.¶
+Given equivalent destination and match length precedence, the most recently +fetched dictionary takes precedence.¶
+When a HTTP client makes a request for a resource for which it has an +appropriate dictionary and the dictionary was stored with a server-provided +"id" in the Use-As-Dictionary response then the client MUST echo the stored +"id" in a "Dictionary-ID" request header.¶
+The "Dictionary-ID" request header is a Structured Field [STRUCTURED-FIELDS] +String of up to 1024 characters (after any decoding) and MUST be identical to +the server-provided "id".¶
+For example, given a HTTP response that set a dictionary ID:¶
+ +A future request that matches the given dictionary will include both the hash +and the ID:¶
+ +This specification defines the 'compression-dictionary' link relation type +[WEB-LINKING] that provides a mechanism for a HTTP response to provide a URL +for a compression dictionary that is related to, but not directly used by the +current HTTP response.¶
+The 'compression-dictionary' link relation type indicates that fetching and +caching the specified resource is likely to be beneficial for future requests. +The response to some of those future requests are likely to be able to use +the indicated resource as a compression dictionary.¶
+Clients can fetch the provided resource at a time that they determine would +be appropriate.¶
+The response to the fetch for the compression dictionary needs to include a +"Use-As-Dictionary" and caching response headers for it to be usable as a +compression dictionary. The link relation only provides the mechanism for +triggering the fetch of the dictionary.¶
+The following example shows a link to a resource at +https://example.org/dict.dat that is expected to produce a compression +dictionary:¶
+ +The "dcb" content encoding identifies a resource that is a +"Dictionary-Compressed Brotli" stream.¶
+A "Dictionary-Compressed Brotli" stream has a fixed header that is followed by +a Shared Brotli [SHARED-BROTLI] stream. The header consists of a fixed 4-byte +sequence and a 32-byte hash of the external dictionary that was used. The +Shared Brotli stream is created using the referenced external dictionary and a +compression window that is at most 16 MB in size.¶
+The dictionary used for the "dcb" content encoding is a "raw" dictionary type +as defined in Section 2.1.4 and is treated as a prefix dictionary as defined in +section 9.2 of the Shared Brotli Compressed Data Format draft. +[SHARED-BROTLI]¶
+The 36-byte fixed header is as follows:¶
+4 fixed bytes: 0xff, 0x44, 0x43, 0x42.¶
+Clients that announce support for dcb content encoding MUST be able to +decompress resources that were compressed with a window size of up to 16 MB.¶
+With Brotli compression, the full dictionary is available during compression +and decompression independent of the compression window, allowing for +delta-compression of resources larger than the compression window.¶
+The "dcz" content encoding identifies a resource that is a +"Dictionary-Compressed Zstandard" stream.¶
+A "Dictionary-Compressed Zstandard" stream is a binary stream that starts with +a 40-byte fixed header and is followed by a Zstandard [RFC8878] stream of the +response that has been compressed with an external dictionary.¶
+The dictionary used for the "dcz" content encoding is a "raw" dictionary type +as defined in Section 2.1.4 and is treated as a raw dictionary as per section 5 of +RFC 8878.¶
+The 40-byte header consists of a fixed 8-byte sequence followed by the +32-byte SHA-256 hash of the external dictionary that was used to compress the +resource:¶
+8 fixed bytes: 0x5e, 0x2a, 0x4d, 0x18, 0x20, 0x00, 0x00, 0x00.¶
+The 40-byte header is a Zstandard skippable frame (little-endian 0x184D2A5E) +with a 32-byte length (little-endian 0x00000020) that is compatible with +existing Zstandard decoders.¶
+Clients that announce support for dcz content encoding MUST be able to +decompress resources that were compressed with a window size of at least 8 MB +or 1.25 times the size of the dictionary, which ever is greater, up to a +maximum of 128 MB.¶
+The window size used will be encoded in the content (currently, this can be +expressed in powers of two only) and it MUST be lower than this limit. An +implementation MAY treat a window size that exceeds the limit as a decoding +error.¶
+With Zstandard compression, the full dictionary is available during compression +and decompression until the size of the input exceeds the compression window. +Beyond that point the dictionary becomes unavailable. Using a compression +window that is 1.25 times the size of the dictionary allows for full delta +compression of resources that have grown by 25% between releases while still +giving the client control over the memory it will need to allocate for a given +response.¶
+When a compression dictionary is available for use compressing the response to +a given request, the encoding to be used is negotiated through the regular +mechanism for negotiating content encoding in HTTP through the "Accept-Encoding" +request header and "Content-Encoding" response header.¶
+The dictionary to use is negotiated separately and advertised in the +"Available-Dictionary" request header.¶
+When a dictionary is available for use on a given request, and the client +chooses to make dictionary-based content-encoding available, the client adds +the dictionary-aware content encodings that it supports to the +"Accept-Encoding" request header. e.g.:¶
+ +When a client does not have a stored dictionary that matches the request, or +chooses not to use one for the request, the client MUST NOT send its +dictionary-aware content-encodings in the "Accept-Encoding" request header.¶
+If a server supports one of the dictionary encodings advertised by the client +and chooses to compress the content of the response using the dictionary that +the client has advertised then it sets the "Content-Encoding" response header +to the appropriate value for the algorithm selected. e.g.:¶
+ +If the response is cacheable, it MUST include a "Vary" header to prevent caches +serving dictionary-compressed resources to clients that don't support them or +serving the response compressed with the wrong dictionary:¶
+ +IANA is asked to enter the following into the "HTTP Content Coding Registry" +registry maintained at +<https://www.iana.org/assignments/http-parameters/http-parameters.xhtml>:¶
+Name: dcb¶
+Description: "Dictionary-Compressed Brotli" data format.¶
+Reference: This document¶
+IANA is asked to enter the following into the "HTTP Content Coding Registry" +registry maintained at +<https://www.iana.org/assignments/http-parameters/http-parameters.xhtml>:¶
+ +IANA is asked to update the +"Hypertext Transfer Protocol (HTTP) Field Name Registry" registry maintained at +<https://www.iana.org/assignments/http-fields/http-fields.xhtml> according +to the table below:¶
+Field Name | +Status | +Reference | +
---|---|---|
Use-As-Dictionary | +permanent | ++ Section 2.1 of this document | +
Available-Dictionary | +permanent | ++ Section 2.2 of this document | +
Dictionary-ID | +permanent | ++ Section 2.3 of this document | +
IANA is asked to update the "Link Relation Types" registry maintained at +<https://www.iana.org/assignments/link-relations/link-relations.xhtml>:¶
+ +It is not unusual for there to be devices on the network path that intercept, +inspect and process HTTP requests (web proxies, firewalls, intrusion detection +systems, etc). To minimize the risk of these devices incorrectly processing +dictionary-compressed responses, compression dictionary transport MUST only be +used in secure contexts (HTTPS).¶
+The security considerations for Brotli [RFC7932], Shared Brotli +[SHARED-BROTLI] and Zstandard [RFC8878] apply to the +dictionary-based versions of the respective algorithms.¶
+The dictionary must be treated with the same security precautions as +the content, because a change to the dictionary can result in a +change to the decompressed content.¶
+The dictionary is validated using a SHA-256 hash of the content to make sure +that the client and server are both using the same dictionary. The strength +of the SHA-256 hash algorithm isn't explicitly needed to counter attacks +since the dictionary is being served from the same origin as the content. That +said, if a weakness is discovered in SHA-256 and it is determined that the +dictionary negotiation should use a different hash algorithm, the +"Use-As-Dictionary" response header can be extended to specify a different +algorithm and the server would just ignore any "Available-Dictionary" requests +that do not use the updated hash.¶
+The compression attacks in Section 2.6 of [RFC7457] show that it's a bad idea +to compress data from mixed (e.g. public and private) sources -- the data +sources include not only the compressed data but also the dictionaries. For +example, if you compress secret cookies using a public-data-only dictionary, +you still leak information about the cookies.¶
+Not only can the dictionary reveal information about the compressed +data, but vice versa, data compressed with the dictionary can reveal +the contents of the dictionary when an adversary can control parts of +data to compress and see the compressed size. On the other hand, if +the adversary can control the dictionary, the adversary can learn +information about the compressed data.¶
+If any of the mitigations do not pass, the client MUST drop the response and +return an error.¶
+To make sure that a dictionary can only impact content from the same origin +where the dictionary was served, the URL Pattern used for matching a dictionary +to requests (Section 2.1.1) is guaranteed to be for the same origin that the +dictionary is served from.¶
+For clients, like web browsers, that provide additional protection against the +readability of the payload of a response and against user tracking, additional +protections MUST be taken to make sure that the use of dictionary-based +compression does not reveal information that would not otherwise be available.¶
+In these cases, dictionary compression MUST only be used when both the +dictionary and the compressed response are fully readable by the client.¶
+In browser terms, that means that both are either same-origin to the context +they are being fetched from or that the response is cross-origin and passes +the CORS check (see Part "CORS check" of [FETCH]).¶
+As with any usage of compressed content in a secure context, a potential +timing attack exists if the attacker can control any part of the dictionary, +or if it can read the dictionary and control any part of the content being +compressed, while performing multiple requests that vary the dictionary or +injected content. Under such an attack, the changing size or processing time +of the response reveals information about the content, which might be +sufficient to read the supposedly secure response.¶
+In general, a server can mitigate such attacks by preventing variations per +request, as in preventing active use of multiple dictionaries for the same +content, disabling compression when any portion of the content comes from +uncontrolled sources, and securing access and control over the dictionary +content in the same way as the response content. In addition, the following +requirements on a server are intended to disable dictionary-aware compression +when the client provides CORS request header fields that indicate a +cross-origin request context.¶
+The following algorithm will return FALSE for cross-origin requests where +precautions such as not using dictionary-based compression should be +considered:¶
+If there is no "Sec-Fetch-Site" request header then return TRUE.¶
+if the value of the "Sec-Fetch-Site" request header is "same-origin" then +return TRUE.¶
+If there is no "Sec-Fetch-Mode" request header then return TRUE.¶
+If the value of the "Sec-Fetch-Mode" request header is "navigate" or +"same-origin" then return TRUE.¶
+If the value of the "Sec-Fetch-Mode" request header is "cors":¶
+If the response does not include an "Access-Control-Allow-Origin" response header then return FALSE.¶
+If the request does not include an "Origin" request header then return FALSE.¶
+If the value of the "Access-Control-Allow-Origin" response header is "*" then return TRUE.¶
+If the value of the "Access-Control-Allow-Origin" response header matches the value of the "Origin" request header then return TRUE.¶
+return FALSE.¶
+Since dictionaries are advertised in future requests using the hash of the +content of the dictionary, it is possible to abuse the dictionary to turn it +into a tracking cookie.¶
+To mitigate any additional tracking concerns, clients MUST treat dictionaries +in the same way that they treat cookies [RFC6265]. This includes partitioning +the storage as cookies are partitioned as well as clearing the dictionaries +whenever cookies are cleared.¶
+Internet-Draft | +Templated CONNECT-TCP | +January 2025 | +
Schwartz | +Expires 11 July 2025 | +[Page] | +
TCP proxying using HTTP CONNECT has long been part of the core HTTP specification. However, this proxying functionality has several important deficiencies in modern HTTP environments. This specification defines an alternative HTTP proxy service configuration for TCP connections. This configuration is described by a URI Template, similar to the CONNECT-UDP and CONNECT-IP protocols.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+HTTP has used the CONNECT method for proxying TCP connections since HTTP/1.1. When using CONNECT, the request target specifies a host and port number, and the proxy forwards TCP payloads between the client and this destination ([RFC9110], Section 9.3.6). To date, this is the only mechanism defined for proxying TCP over HTTP. In this specification, this is referred to as a "classic HTTP CONNECT proxy".¶
+HTTP/3 uses a UDP transport, so it cannot be forwarded using the pre-existing CONNECT mechanism. To enable forward proxying of HTTP/3, the MASQUE effort has defined proxy mechanisms that are capable of proxying UDP datagrams [CONNECT-UDP], and more generally IP datagrams [CONNECT-IP]. The destination host and port number (if applicable) are encoded into the HTTP resource path, and end-to-end datagrams are wrapped into HTTP Datagrams [RFC9297] on the client-proxy path.¶
+HTTP clients can be configured to use proxies by selecting a proxy hostname, a port, and whether to use a security protocol. However, Classic HTTP CONNECT requests using the proxy do not carry this configuration information. Instead, they only indicate the hostname and port of the target. This prevents any HTTP server from hosting multiple distinct proxy services, as the server cannot distinguish them by path (as with distinct resources) or by origin (as in "virtual hosting").¶
+The absence of an explicit origin for the proxy also rules out the usual defenses against server port misdirection attacks (see Section 7.4 of [RFC9110]) and creates ambiguity about the use of origin-scoped response header fields (e.g., "Alt-Svc" [RFC7838], "Strict-Transport-Security" [RFC6797]).¶
+Classic HTTP CONNECT requests cannot carry in-stream metadata. For example, the WRAP_UP capsule [I-D.schinazi-httpbis-wrap-up] cannot be used with Classic HTTP CONNECT.¶
+This specification describes an alternative mechanism for proxying TCP in HTTP. Like [CONNECT-UDP] and [CONNECT-IP], the proxy service is identified by a URI Template. Proxy interactions reuse standard HTTP components and semantics, avoiding changes to the core HTTP protocol.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+A template-driven TCP transport proxy for HTTP is identified by a URI Template [RFC6570] containing variables named "target_host" and "target_port". This URI Template and its variable values MUST meet all the same requirements as for UDP proxying ([RFC9298], Section 2), and are subject to the same validation rules. The client MUST substitute the destination host and port number into this template to produce the request URI. The derived URI serves as the destination of a Capsule Protocol connection using the Upgrade Token "connect-tcp" (see registration in Section 8.1).¶
+When using "connect-tcp", TCP payload data is sent in the payload of a new Capsule Type named DATA (see registration in Section 8.3). The ordered concatenation of DATA capsule payloads represents the TCP payload data.¶
+An intermediary MAY merge and split successive DATA capsules, subject to the following requirements:¶
+There are no intervening capsules of other types.¶
+The order of payload content is preserved.¶
+In HTTP/1.1, the client uses the proxy by issuing a request as follows:¶
+The method SHALL be "GET".¶
+The request's target SHALL correspond to the URI derived from expansion of the proxy's URI Template.¶
+The request SHALL include a single "Host" header field containing the origin of the proxy.¶
+The request SHALL include a "Connection" header field with the value "Upgrade". (Note that this requirement is case-insensitive as per Section 7.6.1 of [RFC9110].)¶
+The request SHALL include an "Upgrade" header field with the value "connect-tcp".¶
+The request SHOULD include a "Capsule-Protocol: ?1" header.¶
+If the request is well-formed and permissible, the proxy MUST attempt to establish the TCP connection before sending any response status code other than "100 (Continue)" (see Section 4.2). If the TCP connection is successful, the response SHALL be as follows:¶
+The HTTP status code SHALL be "101 (Switching Protocols)".¶
+The response SHALL include a "Connection" header field with the value "Upgrade".¶
+The response SHALL include a single "Upgrade" header field with the value "connect-tcp".¶
+The response SHOULD include a "Capsule-Protocol: ?1" header.¶
+If the request is malformed or impermissible, the proxy MUST return a 4XX error code. If a TCP connection was not established, the proxy MUST NOT switch protocols to "connect-tcp", and the client MAY reuse this connection for additional HTTP requests.¶
+ +In HTTP/2 and HTTP/3, the proxy MUST include SETTINGS_ENABLE_CONNECT_PROTOCOL in its SETTINGS frame [RFC8441][RFC9220]. The client uses the proxy by issuing an "extended CONNECT" request as follows:¶
+The :method pseudo-header field SHALL be "CONNECT".¶
+The :protocol pseudo-header field SHALL be "connect-tcp".¶
+The :authority pseudo-header field SHALL contain the authority of the proxy.¶
+The :path and :scheme pseudo-header fields SHALL contain the path and scheme of the request URI derived from the proxy's URI Template.¶
+A templated TCP proxying request that does not conform to all of these requirements represents a client error (see [RFC9110], Section 15.5) and may be malformed (see Section 8.1.1 of [RFC9113] and Section 4.1.2 of [RFC9114]).¶
+ +Ordinary HTTP headers apply only to the single resource identified in the request or response. An origin-scoped HTTP header is a special response header that is intended to change the client's behavior for subsequent requests to any resource on this origin.¶
+Unlike classic HTTP CONNECT proxies, a templated TCP proxy has an unambiguous origin of its own. Origin-scoped headers apply to this origin when they are associated with a templated TCP proxy response. Here are some origin-scoped headers that could potentially be sent by a templated TCP proxy:¶
+ +Authentication to a templated TCP proxy normally uses ordinary HTTP authentication via the "401 (Unauthorized)" response code, the "WWW-Authenticate" response header field, and the "Authorization" request header field ([RFC9110], Section 11.6). A templated TCP proxy does not use the "407 (Proxy Authentication Required)" response code and related header fields ([RFC9110], Section 11.7) because they do not traverse HTTP gateways (see Section 7).¶
+Clients SHOULD assume that all proxy resources generated by a single template share a protection space (i.e., a realm) ([RFC9110], Section 11.5). For many authentication schemes, this will allow the client to avoid waiting for a "401 (Unauthorized)" response before each new connection through the proxy.¶
+In each HTTP version, any requirements related to closing connections in Classic HTTP CONNECT also apply to "connect-tcp", with the following modifications:¶
+In HTTP/1.1, endpoints SHOULD close the connection in an error state to indicate receipt of a TCP connection error (e.g., a TCP RST or timeout). Acceptable error states include sending an incomplete DATA capsule (as defined in Section 3.3 of [RFC9297]), a TLS Error Alert ([RFC8446], Section 6.2), or a TCP RST (if TLS is not in use). When a connection is terminated in an error state, the receiving endpoint SHOULD send a TCP RST if the underlying TCP implementation permits it.¶
+In HTTP/2 and HTTP/3, senders MAY use an incomplete DATA capsule to indicate a TCP connection error, instead of (or in addition to) the signals defined for TCP connection errors in Classic HTTP CONNECT. Recipients MUST recognize any incomplete capsule as a TCP connection error.¶
+Intermediaries MUST propagate connection shutdown errors, including when translating between different HTTP versions.¶
+This section discusses some behaviors that are permitted or recommended in order to enhance the performance or functionality of connection setup.¶
+When using this specification in HTTP/2 or HTTP/3, clients MAY start sending TCP stream content optimistically, subject to flow control limits (Section 5.2 of [RFC9113] or Section 4.1 of [RFC9000]). Proxies MUST buffer this "optimistic" content until the TCP stream becomes writable, and discard it if the TCP connection fails. (Clients MUST NOT use "optimistic" behavior in HTTP/1.1, as this would interfere with reuse of the connection after an error response such as "401 (Unauthorized)".)¶
+Servers that host a proxy under this specification MAY offer support for TLS early data in accordance with [RFC8470]. Clients MAY send "connect-tcp" requests in early data, and MAY include "optimistic" TCP content in early data (in HTTP/2 and HTTP/3). At the TLS layer, proxies MAY ignore, reject, or accept the early_data
extension ([RFC8446], Section 4.2.10). At the HTTP layer, proxies MAY process the request immediately, return a "425 (Too Early)" response ([RFC8470], Section 5.2), or delay some or all processing of the request until the handshake completes. For example, a proxy with limited anti-replay defenses might choose to perform DNS resolution of the target_host
when a request arrives in early data, but delay the TCP connection until the TLS handshake completes.¶
This specification supports the "Expect: 100-continue" request header ([RFC9110], Section 10.1.1) in any HTTP version. The "100 (Continue)" status code confirms receipt of a request at the proxy without waiting for the proxy-destination TCP handshake to succeed or fail. This might be particularly helpful when the destination host is not responding, as TCP handshakes can hang for several minutes before failing. Clients MAY send "Expect: 100-continue", and proxies MUST respect it by returning "100 (Continue)" if the request is not immediately rejected.¶
+Proxies implementing this specification SHOULD include a "Proxy-Status" response header [RFC9209] in any success or failure response (i.e., status codes 101, 2XX, 4XX, or 5XX) to support advanced client behaviors and diagnostics. In HTTP/2 or HTTP/3, proxies MAY additionally send a "Proxy-Status" trailer in the event of an unclean shutdown.¶
+For server operators, template-driven TCP proxies are particularly valuable in situations where virtual-hosting is needed, or where multiple proxies must share an origin. For example, the proxy might benefit from sharing an HTTP gateway that provides DDoS defense, performs request sanitization, or enforces user authorization.¶
+The URI template can also be structured to generate high-entropy Capability URLs [CAPABILITY], so that only authorized users can discover the proxy service.¶
+Clients that support both classic HTTP CONNECT proxies and template-driven TCP proxies MAY accept both types via a single configuration string. If the configuration string can be parsed as a URI Template containing the required variables, it is a template-driven TCP proxy. Otherwise, it is presumed to represent a classic HTTP CONNECT proxy.¶
+In some cases, it is valuable to allow "connect-tcp" clients to reach "connect-tcp"-only proxies when using a legacy configuration method that cannot convey a URI Template. To support this arrangement, clients SHOULD treat certain errors during classic HTTP CONNECT as indications that the proxy might only support "connect-tcp":¶
+In HTTP/1.1: the response status code is "426 (Upgrade Required)", with an "Upgrade: connect-tcp" response header.¶
+In any HTTP version: the response status code is "501 (Not Implemented)".¶
+Requires SETTINGS_ENABLE_CONNECT_PROTOCOL to have been negotiated in HTTP/2 or HTTP/3.¶
+If the client infers that classic HTTP CONNECT is not supported, it SHOULD retry the request using the registered default template for "connect-tcp":¶
+ +If this request succeeds, the client SHOULD record a preference for "connect-tcp" to avoid further retry delays.¶
+Template-driven TCP proxying is largely subject to the same security risks as classic HTTP CONNECT. For example, any restrictions on authorized use of the proxy (see [RFC9110], Section 9.3.6) apply equally to both.¶
+A small additional risk is posed by the use of a URI Template parser on the client side. The template input string could be crafted to exploit any vulnerabilities in the parser implementation. Client implementers should apply their usual precautions for code that processes untrusted inputs.¶
+Templated TCP proxies can make use of standard HTTP gateways and path-routing to ease implementation and allow use of shared infrastructure. However, current gateways might need modifications to support TCP proxy services. To be compatible, a gateway must:¶
+support Extended CONNECT (if acting as an HTTP/2 or HTTP/3 server).¶
+support HTTP/1.1 Upgrade to "connect-tcp" (if acting as an HTTP/1.1 server)¶
+only after forwarding the upgrade request to the origin and observing a success response.¶
+forward the "connect-tcp" protocol to the origin.¶
+convert "connect-tcp" requests between all supported HTTP server and client versions.¶
+allow any "Proxy-Status" headers to traverse the gateway.¶
+IF APPROVED, IANA is requested to add the following entry to the HTTP Upgrade Token Registry:¶
+Value | +Description | +Reference | +
---|---|---|
"connect-tcp" | +Proxying of TCP payloads | +(This document) | +
For interoperability testing of this draft version, implementations SHALL use the value "connect-tcp-07".¶
+IF APPROVED, IANA is requested to add the following entry to the "MASQUE URI Suffixes" registry:¶
+Path Segment | +Description | +Reference | +
---|---|---|
tcp | +TCP Proxying | +(This document) | +
IF APPROVED, IANA is requested to add the following entry to the "HTTP Capsule Types" registry:¶
+Value | +Capsule Type | +Status | +Reference | +Change Controller | +Contact | +
---|---|---|---|---|---|
(TBD) | +DATA | +permanent | +(This document), Section 3 + | +IETF | +HTTPBIS | +
For this draft version of the protocol, the Capsule Type value 0x2028d7ee
shall be used provisionally for testing, under the name "DATA-07".¶
Thanks to Amos Jeffries, Tommy Pauly, Kyle Nekritz, David Schinazi, and Kazuho Oku for close review and suggested changes.¶
+Internet-Draft | +No-Vary-Search | +January 2025 | +
Denicola & Roman | +Expires 11 July 2025 | +[Page] | +
A proposed HTTP header field for changing how URL search parameters impact caching.¶
+This note is to be removed before publishing as an RFC.¶
++ The latest revision of this draft can be found at https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html. + Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-no-vary-search/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/no-vary-search.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+This document also adopts some conventions and notation typical in WHATWG and W3C usage, especially as it relates to algorithms. See [WHATWG-INFRA].¶
+The No-Vary-Search
HTTP header field is a structured field [STRUCTURED-FIELDS] whose value must be a dictionary (Section 3.2 of [STRUCTURED-FIELDS]).¶
It has the following authoring conformance requirements:¶
+If present, the key-order
entry's value must be a boolean (Section 3.3.6 of [STRUCTURED-FIELDS]).¶
If present, the params
entry's value must be either a boolean (Section 3.3.6 of [STRUCTURED-FIELDS]) or an inner list (Section 3.1.1 of [STRUCTURED-FIELDS]).¶
If present, the except
entry's value must be an inner list (Section 3.1.1 of [STRUCTURED-FIELDS]).¶
The except
entry must only be present if the params
entry is also present, and the params
entry's value is the boolean value true.¶
The dictionary may contain entries whose keys are not one of key-order
, params
, and except
, but their meaning is not defined by this specification. Implementations of this specification will ignore such entries (but future documents may assign meaning to such entries).¶
A URL search variance consists of the following:¶
+either the special value wildcard or a list of strings¶
+either the special value wildcard or a list of strings¶
+a boolean¶
++The default URL search variance is a URL search variance whose no-vary params is an empty list, vary params is wildcard, and vary on key order is true.¶
+The obtain a URL search variance algorithm (Section 4.2) ensures that all URL search variances obey the following constraints:¶
+ ++To parse a URL search variance given value:¶
+If value is null, then return the default URL search variance.¶
+Let result be a new URL search variance.¶
+Set result's vary on key order to true.¶
+If value["key-order
"] exists:¶
If value["params
"] exists:¶
If value["params
"] is a boolean:¶
Otherwise, if value["params
"] is an array:¶
If any item in value["params
"] is not a string, then return the default URL search variance.¶
Set result's no-vary params to the result of applying parse a key (Section 4.3) to each item in value["params
"].¶
Set result's vary params to wildcard.¶
+Otherwise, return the default URL search variance.¶
+If value["except
"] exists:¶
If value["params
"] is not true, then return the default URL search variance.¶
If value["except
"] is not an array, then return the default URL search variance.¶
If any item in value["except
"] is not a string, then return the default URL search variance.¶
Set result's vary params to the result of applying parse a key (Section 4.3) to each item in value["except
"].¶
Return result.¶
++To obtain a URL search variance given a response response:¶
+Let fieldValue be the result of getting a structured field value [FETCH] given `No-Vary-Search
` and "dictionary
" from response's header list.¶
Return the result of parsing a URL search variance (Section 4.1) given fieldValue. ¶
+The following illustrates how various inputs are parsed, in terms of their impacting on the resulting no-vary params and vary params:¶
+Input | +Result | +
---|---|
+ No-Vary-Search: params
+ |
+ no-vary params: wildcard vary params: (empty list) |
+
+ No-Vary-Search: params=("a")
+ |
+ no-vary params: « "a " »vary params: wildcard + |
+
+ No-Vary-Search: params, except=("x")
+ |
+ no-vary params: wildcard vary params: « " x " » |
+
The following inputs are all invalid and will cause the default URL search variance to be returned:¶
+No-Vary-Search: unknown-key
¶
No-Vary-Search: key-order="not a boolean"
¶
No-Vary-Search: params="not a boolean or inner list"
¶
No-Vary-Search: params=(not-a-string)
¶
No-Vary-Search: params=("a"), except=("x")
¶
No-Vary-Search: params=(), except=()
¶
No-Vary-Search: params=?0, except=("x")
¶
No-Vary-Search: params, except=(not-a-string)
¶
No-Vary-Search: params, except="not an inner list"
¶
No-Vary-Search: params, except=?1
¶
No-Vary-Search: except=("x")
¶
No-Vary-Search: except=()
¶
The following inputs are valid, but somewhat unconventional. They are shown alongside their more conventional form.¶
+Input | +Conventional form | +
---|---|
+ No-Vary-Search: params=?1
+ |
+
+ No-Vary-Search: params
+ |
+
+ No-Vary-Search: key-order=?1
+ |
+
+ No-Vary-Search: key-order
+ |
+
+ No-Vary-Search: params, key-order, except=("x")
+ |
+
+ No-Vary-Search: key-order, params, except=("x")
+ |
+
+ No-Vary-Search: params=?0
+ |
+ (omit the header) | +
+ No-Vary-Search: params=()
+ |
+ (omit the header) | +
+ No-Vary-Search: key-order=?0
+ |
+ (omit the header) | +
+To parse a key given an ASCII string keyString:¶
+Let keyBytes be the isomorphic encoding [WHATWG-INFRA] of keyString.¶
+Replace any 0x2B (+) in keyBytes with 0x20 (SP).¶
+Let keyBytesDecoded be the percent-decoding [WHATWG-URL] of keyBytes.¶
+Let keyStringDecoded be the UTF-8 decoding without BOM [WHATWG-ENCODING] of keyBytesDecoded.¶
+Return keyStringDecoded.¶
+The parse a key algorithm allows encoding non-ASCII key strings in the ASCII structured header format, similar to how the application/x-www-form-urlencoded format [WHATWG-URL] allows encoding an entire entry list of keys and values in ASCII URL format. For example,¶
+ +will result in a URL search variance whose vary params are « "é 気
" ». As explained in a later example, the canonicalization process during equivalence testing means this will treat as equivalent URL strings such as:¶
https://example.com/?é 気=1
¶
https://example.com/?é+気=2
¶
https://example.com/?%C3%A9%20気=3
¶
https://example.com/?%C3%A9+%E6%B0%97=4
¶
and so on, since they all are parsed [WHATWG-URL] to having the same key "é 気
".¶
+Two URLs [WHATWG-URL] urlA and urlB are equivalent modulo search variance given a URL search variance searchVariance if the following algorithm returns true:¶
+If the scheme, username, password, host, port, or path of urlA and urlB differ, then return false.¶
+If searchVariance is equivalent to the default URL search variance, then:¶
+ +
+In this case, even URL pairs that might appear the same after running the application/x-www-form-urlencoded parser [WHATWG-URL] on their queries, such as https://example.com/a
and https://example.com/a?
, or https://example.com/foo?a=b&&&c
and https://example.com/foo?a=b&c=
, will be treated as inequivalent.¶
Let searchParamsA and searchParamsB be empty lists.¶
+If wrlA's query is not null, then set searchParamsA to the result of running the application/x-www-form-urlencoded parser [WHATWG-URL] given the isomorphic encoding [WHATWG-INFRA] of urlA's query.¶
+If wrlB's query is not null, then set searchParamsB to the result of running the application/x-www-form-urlencoded parser [WHATWG-URL] given the isomorphic encoding [WHATWG-INFRA] of urlB's query.¶
+If searchVariance's no-vary params is a list, then:¶
+ +Otherwise, if searchVariance's vary params is a list, then:¶
+ +If searchVariance's vary on key order is false, then:¶
+Let keyLessThan be an algorithm taking as inputs two pairs (keyA, valueA) and (keyB, valueB), which returns whether keyA is code unit less than [WHATWG-INFRA] keyB.¶
+Set searchParamsA to the result of sorting searchParamsA in ascending order with keyLessThan.¶
+Set searchParamsB to the result of sorting searchParamsB in ascending order with keyLessThan.¶
+If searchParamsA's size is not equal to searchParamsB's size, then return false.¶
+Let i be 0.¶
+While i < searchParamsA's size:¶
+ +Return true.¶
+Due to how the application/x-www-form-urlencoded parser canonicalizes query strings, there are some cases where query strings which do not appear obviously equivalent, will end up being treated as equivalent after parsing.¶
+So, for example, given any non-default value for No-Vary-Search
, such as No-Vary-Search: key-order
, we will have the following equivalences:¶
https://example.com
+ https://example.com/?
+ https://example.com/?a=x
+ https://example.com/?%61=%78
+ https://example.com/?a=é
+ https://example.com/?a=%C3%A9
+ https://example.com/?a=%f6
+ https://example.com/?a=%ef%bf%bd
+ https://example.com/?a=x&&&&
+ https://example.com/?a=x
+ &
+ and discards empty strings¶
+https://example.com/?a=
+ https://example.com/?a
+ a
¶
+https://example.com/?a=%20
+ https://example.com/?a=+
+ https://example.com/?a= &
+ +
+ and %20
+ are both parsed as U+0020 SPACE¶
+If a cache [HTTP-CACHING] implements this specification, the presented target URI requirement in Section 4 of [HTTP-CACHING] is replaced with:¶
+one of the following:¶
+the presented target URI (Section 7.1 of [HTTP]) and that of the stored response match, or¶
+the presented target URI and that of the stored response are equivalent modulo search variance (Section 5), given the variance obtained (Section 4.2) from the stored response.¶
+Servers SHOULD send no more than one distinct non-empty value for the No-Vary-Search
field in response to requests for a given pathname.¶
Cache implementations MAY fail to reuse a stored response whose target URI matches only modulo URL search variance, if the cache has more recently stored a response which:¶
+ + +The main risk to be aware of is the impact of mismatched URLs. In particular, this could cause the user to see a response that was originally fetched from a URL different from the one displayed when they hovered a link, or the URL displayed in the URL bar.¶
+However, since the impact is limited to query parameters, this does not cross the relevant security boundary, which is the origin [HTML]. (Or perhaps just the host, from the perspective of web browser security UI. [WHATWG-URL]) Indeed, we have already given origins complete control over how they present the (URL, reponse body) pair, including on the client side via technology such as history.replaceState() or service workers.¶
+This proposal is adjacent to the highly-privacy-relevant space of navigational tracking, which often uses query parameters to pass along user identifiers. However, we believe this proposal itself does not have privacy impacts. It does not interfere with existing navigational tracking mitigations, or any known future ones being contemplated. Indeed, if a page were to encode user identifiers in its URL, the only ability this proposal gives is to reduce such user tracking by preventing server processing of such user IDs (since the server is bypassed in favor of the cache). [NAV-TRACKING-MITIGATIONS]¶
+IANA should do the following:¶
+ +TODO acknowledge.¶
++ Section 3, Paragraph 3; +Section 4.1, Paragraph 2.1.1; +Section 4.1, Paragraph 2.4.2.1.1; +Section 4.1, Paragraph 2.5.2.2.2.1.1; +Section 4.1, Paragraph 2.5.2.3.1; +Section 4.1, Paragraph 2.6.2.1.1; +Section 4.1, Paragraph 2.6.2.2.1; +Section 4.1, Paragraph 2.6.2.3.1; +Section 4.1, Paragraph 3.1; +Section 4.2.1, Paragraph 3; +Section 5, Paragraph 2.2.1¶
++ Section 2, Paragraph 5.1; +Section 3, Paragraph 4; +Section 4.2, Paragraph 1¶
++ Section 4.1, Paragraph 2.5.2.2.2.2.1; +Section 4.1, Paragraph 2.6.2.4.1; +Section 4.3, Paragraph 1; +Section 4.3.1, Paragraph 1¶
+Internet-Draft | +Optimistic HTTP Upgrade Security | +January 2025 | +
Schwartz | +Expires 11 July 2025 | +[Page] | +
In HTTP/1.1, the client can request a change to a new protocol on the existing connection. This document discusses the security considerations that apply to data sent by the client before this request is confirmed, and updates RFC 9298 to avoid related security issues.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-optimistic-upgrade/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+In HTTP/1.1, a single connection is often used for many requests, one after another. After each request, the connection is returned to its initial state, ready to send more HTTP requests. However, HTTP/1.1 also contains two mechanisms that allow the client to change the protocol used for the remainder of the connection.¶
+One such mechanism is the "Upgrade" request header field ([RFC9110], Section 7.8), which indicates that the client would like to use this connection for a protocol other than HTTP/1.1. The server replies with a "101 (Switching Protocols)" status code if it accepts the protocol change.¶
+The other mechanism is the HTTP "CONNECT" method. This method indicates that the client wishes to establish a TCP connection to the specified host and port. The server replies with a 2xx (Successful) response to indicate that the request was accepted and a TCP connection was established. After this point, the TCP connection is acting as a TCP tunnel, not an HTTP/1.1 connection.¶
+Both of these mechanisms also permit the server to reject the request. For example, [RFC9110] says:¶
+A server MAY ignore a received Upgrade header field if it wishes to continue using the current protocol on that connection.¶
+and¶
+A server MUST reject a CONNECT request that targets an empty or invalid port number, typically by responding with a 400 (Bad Request) status code.¶
+Rejections are common, and can happen for a variety of reasons. An "upgrade" request might be rejected if:¶
+The server does not support any of the client's indicated Upgrade Tokens (i.e., the client's proposed new protocols), so it continues to use HTTP/1.1.¶
+The server knows that an upgrade to the offered protocol will not provide any improvement over HTTP/1.1 for this request to this resource, so it chooses to respond in HTTP/1.1.¶
+The server requires the client to authenticate before upgrading the protocol, so it replies with the status code "401 (Authentication Required)" and provides a challenge in an "Authorization" response header ([RFC9110], Section 11.6.2).¶
+The resource has moved, so the server replies with a 3XX redirect status code ([RFC9110], Section 3.4).¶
+Similarly, a CONNECT request might be rejected if:¶
+The server does not support HTTP CONNECT.¶
+The specified destination is not allowed under server policy.¶
+The destination cannot be resolved, is unreachable, or does not accept the connection.¶
+The proxy requires the client to authenticate before proceeding.¶
+After rejecting a request, the server will continue to interpret subsequent bytes on that connection in accordance with HTTP/1.1.¶
+ +A client cannot begin using an upgraded protocol on the connection until it has completely sent the request message (i.e., the client can't change the protocol it is sending in the middle of a message).¶
+However, because of the possibility of rejection, the converse is not true: a client cannot necessarily begin using a new protocol merely because it has finished sending the corresponding request message.¶
+In some cases, the client might expect that the protocol transition will succeed. If this expectation is correct, the client might be able to reduce delay by immediately sending the first bytes of the new protocol "optimistically", without waiting for the server's response. This document explores the security implications of this "optimistic" behavior.¶
+When there are only two distinct parties involved in an HTTP/1.1 connection (i.e., the client and the server), protocol transitions introduce no new security issues: each party must already be prepared for the other to send arbitrary data on the connection at any time. However, HTTP connections often involve more than two parties, if the requests or responses include third-party data. For example, a browser (party 1) might send an HTTP request to an origin (party 2) with path, headers, or body controlled by a website from a different origin (party 3). Post-transition protocols such as WebSocket similarly are often used to convey data chosen by a third party.¶
+If the third-party data source is untrusted, we call the data it provides "attacker-controlled". The combination of attacker-controlled data and optimistic protocol transitions results in two significant security issues.¶
+In a Request Smuggling attack ([RFC9112], Section 11.2) the attacker-controlled data is chosen in such a way that it is interpreted by the server as an additional HTTP request. These attacks allow the attacker to speak on behalf of the client while bypassing the client's own rules about what requests it will issue. Request Smuggling can occur if the client and server have distinct interpretations of the data that flows between them.¶
+If the server accepts a protocol transition request, it interprets the subsequent bytes in accordance with the new protocol. If it rejects the request, it interprets those bytes as HTTP/1.1. However, the client doesn't know which interpretation the server will take until it receives the server's response status code. If it uses the new protocol optimistically, this creates a risk that the server will interpret attacker-controlled data in the new protocol as an additional HTTP request issued by the client.¶
+As a trivial example, consider an HTTP CONNECT client providing connectivity to an untrusted application. If the client is authenticated to the proxy server using a connection-level authentication method such as TLS Client Certificates, the attacker could send an HTTP/1.1 POST request for the proxy server at the beginning of its TCP connection. If the client delivers this data optimistically, and the CONNECT request fails, the server would misinterpret the application's data as a subsequent authenticated request issued by the client.¶
+A related category of attacks use protocol disagreement to exploit vulnerabilities in the server's request parsing logic. These attacks apply when the HTTP client is trusted by the server, but the post-transition data source is not. If the server software was developed under the assumption that some or all of the HTTP request data is not attacker-controlled, optimistic transmission can cause this assumption to be violated, exposing vulnerabilities in the server's HTTP request parser.¶
+If the server rejects the transition request, the connection can continue to be used for HTTP/1.1. There is no requirement to close the connection in response to a rejected transition, and keeping the connection open has performance advantages if additional HTTP requests to this server are likely. Thus, it is normally inappropriate to close the connection in response to a rejected transition.¶
+This section describes the impact of this document's considerations on some registered Upgrade Tokens that are believed to be in use at the time of writing.¶
+The "TLS" family of Upgrade Tokens was defined in [RFC2817], which correctly highlights the possibility of the server rejecting the upgrade. If a client ignores this possibility and sends TLS data optimistically, the result cannot be valid HTTP/1.1: the first octet of a TLS connection must be 22 (ContentType.handshake), but this is not an allowed character in an HTTP/1.1 method. A compliant HTTP/1.1 server will treat this as a parsing error and close the connection without processing further requests.¶
+Section 4.1 of [RFC6455] says:¶
+Once the client's opening handshake has been sent, the client MUST wait for a response from the server before sending any further data.¶
+Thus, optimistic use of HTTP Upgrade is already forbidden in the WebSocket protocol. Additionally, the WebSocket protocol requires high-entropy masking of client-to-server frames (Section 5.1 of [RFC6455]).¶
+A client MAY optimistically start sending UDP packets in HTTP Datagrams before receiving the response to its UDP proxying request.¶
+However, in HTTP/1.1, this "proxying request" is an HTTP Upgrade request. This upgrade is likely to be rejected in certain circumstances, such as when the UDP destination address (which is attacker-controlled) is invalid. Additionally, the contents of the "connect-udp" protocol stream can include untrusted material (i.e., the UDP packets, which might come from other applications on the client device). This creates the possibility of Request Smuggling attacks. To avoid these concerns, this text is updated as follows:¶
+When using HTTP/2 or later, a client MAY optimistically ...¶
+Section 3.3 of [RFC9298] describes the requirement for a successful proxy setup response, including upgrading to the "connect-udp" protocol, and says:¶
+If any of these requirements are not met, the client MUST treat this proxying attempt as failed and abort the connection.¶
+However, this could be interpreted as an instruction to abort the underlying TLS and TCP connections in the event of an unsuccessful response such as "407 ("Proxy Authentication Required)". To avoid an unnecessary delay in this case, this text is hereby updated as follows:¶
+If any of these requirements are not met, the client MUST treat this proxying attempt as failed. If the "Upgrade" response header field is absent, the client MAY reuse the connection for further HTTP/1.1 requests; otherwise it MUST abort the underlying connection.¶
+The "connect-ip" Upgrade Token is defined in [RFC9484]. Section 11 of [RFC9484] forbids clients from using optimistic upgrade, avoiding this issue.¶
+There are now several good examples of designs that reduce or eliminate the security concerns discussed in this document and may be applicable in future specifications:¶
+Forbid optimistic use of HTTP Upgrade (WebSocket, Section 4.1 of [RFC6455]).¶
+Embed a fixed preamble that terminates HTTP/1.1 processing (HTTP/2, Section 3.4 of [RFC9113]).¶
+Apply high-entropy masking of client-to-server data (WebSocket, Section 5.1 of [RFC6455]).¶
+Future specifications for Upgrade Tokens should account for the security issues discussed here and provide clear guidance on how implementations can avoid them.¶
+Some Upgrade Tokens, such as "TLS", are defined for use with any ordinary HTTP Method. The upgraded protocol continues to provide HTTP semantics, and will convey the response to this HTTP request.¶
+The other Upgrade Tokens mentioned in Section 5 do not preserve HTTP semantics, so the method is not relevant. All of these Upgrade Tokens are specified only for use with the "GET" method.¶
+Future specifications for Upgrade Tokens should restrict their use to "GET" requests if the HTTP method is otherwise irrelevant and a request body is not required. This improves consistency with other Upgrade Tokens and reduces the likelihood that a faulty server implementation might process the request body as the new protocol.¶
+In HTTP/1.1, clients that send CONNECT requests on behalf of untrusted TCP clients MUST wait for a 2xx (Successful) response before sending any TCP payload data.¶
+To mitigate vulnerabilities from any clients that do not conform to this requirement, proxy servers MAY close the underlying connection when rejecting an HTTP/1.1 CONNECT request, without processing any further data sent to the proxy server on that connection. Note that this behavior may impair performance, especially when returning a "407 (Proxy Authentication Required)" response.¶
+This document has no IANA actions.¶
+Thanks to Mark Nottingham and Lucas Pardue for early reviews of this document.¶
+Internet-Draft | +Resumable Uploads | +January 2025 | +
Kleidl, et al. | +Expires 11 July 2025 | +[Page] | +
HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation may have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests support this concept of resumable downloads from server to client. This document describes a mechanism that supports resumable uploads from client to server using HTTP.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-resumable-upload/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/resumable-upload.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+HTTP clients often encounter interrupted data transfers as a result of canceled requests or dropped connections. Prior to interruption, part of a representation (see Section 3.2 of [HTTP]) might have been exchanged. To complete the data transfer of the entire representation, it is often desirable to issue subsequent requests that transfer only the remainder of the representation. HTTP range requests (see Section 14 of [HTTP]) support this concept of resumable downloads from server to client.¶
+HTTP methods such as POST or PUT can be used by clients to request processing of representation data enclosed in the request message. The transfer of representation data from client to server is often referred to as an upload. Uploads are just as likely as downloads to suffer from the effects of data transfer interruption. Humans can play a role in upload interruptions through manual actions such as pausing an upload. Regardless of the cause of an interruption, servers may have received part of the representation before its occurrence and it is desirable if clients can complete the data transfer by sending only the remainder of the representation. The process of sending additional parts of a representation using subsequent HTTP requests from client to server is herein referred to as a resumable upload.¶
+Connection interruptions are common and the absence of a standard mechanism for resumable uploads has lead to a proliferation of custom solutions. Some of those use HTTP, while others rely on other transfer mechanisms entirely. An HTTP-based standard solution is desirable for such a common class of problem.¶
+This document defines an optional mechanism for HTTP that enables resumable uploads in a way that is backwards-compatible with conventional HTTP uploads. When an upload is interrupted, clients can send subsequent requests to query the server state and use this information to send the remaining data. Alternatively, they can cancel the upload entirely. Different from ranged downloads, this protocol does not support transferring different parts of the same representation in parallel.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+The terms Byte Sequence, Item, String, Token, Integer, and Boolean are imported from +[STRUCTURED-FIELDS].¶
+The terms "representation", "representation data", "representation metadata", "content", "client" and "server" are from [HTTP].¶
+Resumable uploads are supported in HTTP through use of a temporary resource, an upload resource, that is separate from the resource being uploaded to (hereafter, the target resource) and specific to that upload. By interacting with the upload resource, a client can retrieve the current offset of the upload (Section 5), append to the upload (Section 6), and cancel the upload (Section 7).¶
+The remainder of this section uses an example of a file upload to illustrate different interactions with the upload resource. Note, however, that HTTP message exchanges use representation data (see Section 8.1 of [HTTP]), which means that resumable uploads can be used with many forms of content -- not just static files.¶
+In this example, the client first attempts to upload a file with a known size in a single HTTP request to the target resource. An interruption occurs and the client then attempts to resume the upload using subsequent HTTP requests to the upload resource.¶
+1) The client notifies the server that it wants to begin an upload (Section 4). The server reserves the required resources to accept the upload from the client, and the client begins transferring the entire file in the request content.¶
+An informational response can be sent to the client, which signals the server's support of resumable upload as well as the upload resource URL via the Location header field (Section 10.2.2 of [HTTP]).¶
+2) If the connection to the server is interrupted, the client might want to resume the upload. However, before this is possible the client needs to know the amount of data that the server received before the interruption. It does so by retrieving the offset (Section 5) from the upload resource.¶
+3) The client can resume the upload by sending the remaining file content to the upload resource (Section 6), appending to the already stored data in the upload. The Upload-Offset
value is included to ensure that the client and server agree on the offset that the upload resumes from.¶
4) If the client is not interested in completing the upload, it can instruct the upload resource to delete the upload and free all related resources (Section 7).¶
+In some cases, clients might prefer to upload a file as a series of parts sent serially across multiple HTTP messages. One use case is to overcome server limits on HTTP message content size. Another use case is where the client does not know the final size, such as when file data originates from a streaming source.¶
+This example shows how the client, with prior knowledge about the server's resumable upload support, can upload parts of a file incrementally.¶
+1) If the client is aware that the server supports resumable upload, it can start an upload with the Upload-Complete
field value set to false and the first part of the file.¶
2) Subsequently, parts are appended (Section 6). The last part of the upload has a Upload-Complete
field value set to true to indicate the complete transfer.¶
When a resource supports resumable uploads, the first step is creating the upload resource. To be compatible with the widest range of resources, this is accomplished by including the Upload-Complete
header field in the request that initiates the upload.¶
As a consequence, resumable uploads support all HTTP request methods that can carry content, such as POST
, PUT
, and PATCH
. Similarly, the response to the upload request can have any status code. Both the method(s) and status code(s) supported are determined by the resource.¶
Upload-Complete
MUST be set to false if the end of the request content is not the end of the upload. Otherwise, it MUST be set to true. This header field can be used for request identification by a server. The request MUST NOT include the Upload-Offset
header field.¶
If the request is valid, the server SHOULD create an upload resource. Then, the server MUST include the Location
header field in the response and set its value to the URL of the upload resource. The client MAY use this URL for offset retrieval (Section 5), upload append (Section 6), and upload cancellation (Section 7).¶
Once the upload resource is available and while the request content is being uploaded, the target resource MAY send one or more informational responses with a 104 (Upload Resumption Supported)
status code to the client. In the first informational response, the Location
header field MUST be set to the URL pointing to the upload resource. In subsequent informational responses, the Location
header field MUST NOT be set. An informational response MAY contain the Upload-Offset
header field with the current upload offset as the value to inform the client about the upload progress.¶
The server MUST send the Upload-Offset
header field in the response if it considers the upload active, either when the response is a success (e.g. 201 (Created)
), or when the response is a failure (e.g. 409 (Conflict)
). The Upload-Offset
field value MUST be equal to the end offset of the entire upload, or the begin offset of the next chunk if the upload is still incomplete. The client SHOULD consider the upload failed if the response has a status code that indicates a success but the offset indicated in the Upload-Offset
field value does not equal the total of begin offset plus the number of bytes uploaded in the request.¶
If the request completes successfully and the entire upload is complete, the server MUST acknowledge it by responding with a 2xx (Successful) status code. Servers are RECOMMENDED to use 201 (Created)
unless otherwise specified. The response MUST NOT include the Upload-Complete
header field with the value of false.¶
If the request completes successfully but the entire upload is not yet complete, as indicated by an Upload-Complete
field value of false in the request, the server MUST acknowledge it by responding with the 201 (Created)
status code and an Upload-Complete
header value set to false.¶
The request can indicate the upload's final size in two different ways. Both indicators may be present in the same request as long as they convey the same size. If the sizes are inconsistent, the server MUST reject the request by responding with a 400 (Bad Request)
status code.¶
If the request includes an Upload-Complete
field value set to true and a valid Content-Length
header field, the client attempts to upload a fixed-length resource in one request. In this case, the upload's final size is the Content-Length
field value and the server MUST record it to ensure its consistency. The value can therefore not be used if the upload is split across multiple requests.¶
If the request includes the Upload-Length
header field, the server MUST record its value as the upload's final size. A client SHOULD provide this header field if the upload length is known at the time of upload creation.¶
The upload is not automatically completed if the offset reaches the upload's final size. Instead, a client MUST indicate the completion of an upload through the Upload-Complete
header field. Indicating an upload's final size can help the server allocate necessary resources for the upload and provide early feedback if the size does not match the server's limits (Section 8.2).¶
The server MAY enforce a maximum size of an upload resource. This limit MAY be equal to the upload's final size, if available, or an arbitrary value. The limit's value or its existence MUST NOT change throughout the lifetime of the upload resource. The server MAY indicate such a limit to the client by including the Upload-Limit
header field in the informational or final response to upload creation. If the client receives an Upload-Limit
header field indicating that the maximum size is less than the amount of bytes it intends to upload to a resource, it SHOULD stop the current upload transfer immediately and cancel the upload (Section 7).¶
The request content MAY be empty. If the Upload-Complete
header field is then set to true, the client intends to upload an empty resource representation. An Upload-Complete
header field is set to false is also valid. This can be used to create an upload resource URL before transferring data, which can save client or server resources. Since informational responses are optional, this technique provides another mechanism to learn the URL, at the cost of an additional round-trip before data upload can commence.¶
If the server does not receive the entire request content, for example because of canceled requests or dropped connections, it SHOULD append as much of the request content starting at its beginning and without discontinuities as possible. If the server did not append the entire request content, the upload MUST NOT be considered complete.¶
+ + +The next example shows an upload creation, where only the first 25 bytes of a 100 bytes upload are transferred. The server acknowledges the received data and that the upload is not complete yet:¶
+ + +If the client received an informational response with the upload URL in the Location field value, it MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a 5xx status is received. The client SHOULD NOT automatically retry if it receives a 4xx status code.¶
+File metadata can affect how servers might act on the uploaded file. Clients can send representation metadata (see Section 8.3 of [HTTP]) in the request that starts an upload. Servers MAY interpret this metadata or MAY ignore it. The Content-Type
header field (Section 8.3 of [HTTP]) can be used to indicate the media type of the file. The applied content codings are specified using the Content-Encoding
header field and are retained throughout the entire upload. When resuming an interrupted upload, the same content codings are used for appending to the upload, producing a representation of the upload resource. The Content-Disposition
header field ([RFC6266]) can be used to transmit a filename; if included, the parameters SHOULD be either filename
, filename*
or boundary
.¶
If the client has no knowledge of whether the resource supports resumable uploads, a resumable request can be used with some additional constraints. In particular, the Upload-Complete
field value (Section 8.3) MUST NOT be false if the server support is unclear. This allows the upload to function as if it is a regular upload.¶
Servers SHOULD use the 104 (Upload Resumption Supported)
informational response to indicate their support for a resumable upload request.¶
Clients MUST NOT attempt to resume an upload unless they receive 104 (Upload Resumption Supported)
informational response, or have other out-of-band methods to determine server support for resumable uploads.¶
RFC Editor's Note: Please remove this section and Upload-Draft-Interop-Version
from all examples prior to publication of a final version of this document.¶
The current interop version is 6.¶
+Client implementations of draft versions of the protocol MUST send a header field Upload-Draft-Interop-Version
with the interop version as its value to its requests. The Upload-Draft-Interop-Version
field value is an Integer.¶
Server implementations of draft versions of the protocol MUST NOT send a 104 (Upload Resumption Supported)
informational response when the interop version indicated by the Upload-Draft-Interop-Version
header field in the request is missing or mismatching.¶
Server implementations of draft versions of the protocol MUST also send a header field Upload-Draft-Interop-Version
with the interop version as its value to the 104 (Upload Resumption Supported)
informational response.¶
Client implementations of draft versions of the protocol MUST ignore a 104 (Upload Resumption Supported)
informational response with missing or mismatching interop version indicated by the Upload-Draft-Interop-Version
header field.¶
The reason both the client and the server are sending and checking the draft version is to ensure that implementations of the final RFC will not accidentally interop with draft implementations, as they will not check the existence of the Upload-Draft-Interop-Version
header field.¶
If an upload is interrupted, the client MAY attempt to fetch the offset of the incomplete upload by sending a HEAD
request to the upload resource.¶
The request MUST NOT include an Upload-Offset
, Upload-Complete
, or Upload-Length
header field. The server MUST reject requests with either of these fields by responding with a 400 (Bad Request)
status code.¶
If the server considers the upload resource to be active, it MUST respond with a 204 (No Content)
or 200 (OK)
status code. The response MUST include the Upload-Offset
header field, with the value set to the current resumption offset for the target resource. The response MUST include the Upload-Complete
header field; the value is set to true only if the upload is complete. The response MUST include the Upload-Length
header field set to the upload's final size if one was recorded during the upload creation (Section 4). The response MAY include the Upload-Limit
header field if corresponding limits on the upload resource exist.¶
An upload is considered complete only if the server completely and successfully received a corresponding creation request (Section 4) or append request (Section 6) with the Upload-Complete
header value set to true.¶
The client MUST NOT perform offset retrieval while creation (Section 4) or append (Section 6) is in progress.¶
+The offset MUST be accepted by a subsequent append (Section 6). Due to network delay and reordering, the server might still be receiving data from an ongoing transfer for the same upload resource, which in the client's perspective has failed. The server MAY terminate any transfers for the same upload resource before sending the response by abruptly terminating the HTTP connection or stream. Alternatively, the server MAY keep the ongoing transfer alive but ignore further bytes received past the offset.¶
+The client MUST NOT start more than one append (Section 6) based on the resumption offset from a single offset retrieving request.¶
+In order to prevent HTTP caching ([CACHING]), the response SHOULD include a Cache-Control
header field with the value no-store
.¶
If the server does not consider the upload resource to be active, it MUST respond with a 404 (Not Found)
status code.¶
The resumption offset can be less than or equal to the number of bytes the client has already sent. The client MAY reject an offset which is greater than the number of bytes it has already sent during this upload. The client is expected to handle backtracking of a reasonable length. If the offset is invalid for this upload, or if the client cannot backtrack to the offset and reproduce the same content it has already sent, the upload MUST be considered a failure. The client MAY cancel the upload (Section 7) after rejecting the offset.¶
+The following example shows an offset retrieval request. The server indicates the new offset and that the upload is not complete yet:¶
+ + +The client SHOULD NOT automatically retry if a 4xx (Client Error) status code is received.¶
+Upload appending is used for resuming an existing upload.¶
+The request MUST use the PATCH
method with the application/partial-upload
media type and MUST be sent to the upload resource. The Upload-Offset
field value (Section 8.1) MUST be set to the resumption offset.¶
If the end of the request content is not the end of the upload, the Upload-Complete
field value (Section 8.3) MUST be set to false.¶
The server SHOULD respect representation metadata received during creation (Section 4). An upload append request continues uploading the same representation as used in the upload creation (Section 4) and thus uses the same content codings, if they were applied. For example, if the initial upload creation included the Content-Encoding: gzip
header field, the upload append request resumes the transfer of the gzipped data without indicating again that the gzip coding is applied.¶
If the server does not consider the upload associated with the upload resource active, it MUST respond with a 404 (Not Found)
status code.¶
The client MUST NOT perform multiple upload transfers for the same upload resource in parallel. This helps avoid race conditions, and data loss or corruption. The server is RECOMMENDED to take measures to avoid parallel upload transfers: The server MAY terminate any creation (Section 4) or append for the same upload URL. Since the client is not allowed to perform multiple transfers in parallel, the server can assume that the previous attempt has already failed. Therefore, the server MAY abruptly terminate the previous HTTP connection or stream.¶
+If the offset indicated by the Upload-Offset
field value does not match the offset provided by the immediate previous offset retrieval (Section 5), or the end offset of the immediate previous incomplete successful transfer, the server MUST respond with a 409 (Conflict)
status code. The server MAY use the problem type [PROBLEM] of "https://iana.org/assignments/http-problem-types#mismatching-upload-offset" in the response; see Section 10.1.¶
The server applies the patch document of the application/partial-upload
media type by appending the request content to the targeted upload resource. If the server does not receive the entire patch document, for example because of canceled requests or dropped connections, it SHOULD append as much of the patch document starting at its beginning and without discontinuities as possible. Appending a continuous section starting at the patch document's beginning constitutes a successful PATCH as defined in Section 2 of [RFC5789]. If the server did not receive and apply the entire patch document, the upload MUST NOT be considered complete.¶
While the request content is being uploaded, the target resource MAY send one or more informational responses with a 104 (Upload Resumption Supported)
status code to the client. These informational responses MUST NOT contain the Location
header field. They MAY include the Upload-Offset
header field with the current upload offset as the value to inform the client about the upload progress.¶
The server MUST send the Upload-Offset
header field in the response if it considers the upload active, either when the response is a success (e.g. 201 (Created)
), or when the response is a failure (e.g. 409 (Conflict)
). The value MUST be equal to the end offset of the entire upload, or the begin offset of the next chunk if the upload is still incomplete. The client SHOULD consider the upload failed if the status code indicates a success but the offset indicated by the Upload-Offset
field value does not equal the total of begin offset plus the number of bytes uploaded in the request.¶
If the upload is already complete, the server MUST NOT modify the upload resource and MUST respond with a 400 (Bad Request)
status code. The server MAY use the problem type [PROBLEM] of "https://iana.org/assignments/http-problem-types#completed-upload" in the response; see Section 10.2.¶
If the request completes successfully and the entire upload is complete, the server MUST acknowledge it by responding with a 2xx (Successful) status code. Servers are RECOMMENDED to use a 201 (Created)
response if not otherwise specified. The response MUST NOT include the Upload-Complete
header field with the value set to false.¶
If the request completes successfully but the entire upload is not yet complete indicated by the Upload-Complete
field value set to false, the server MUST acknowledge it by responding with a 201 (Created)
status code and the Upload-Complete
field value set to false.¶
If the request includes the Upload-Complete
field value set to true and a valid Content-Length
header field, the client attempts to upload the remaining resource in one request. In this case, the upload's final size is the sum of the upload's offset and the Content-Length
header field. If the server does not have a record of the upload's final size from creation or the previous append, the server MUST record the upload's final size to ensure its consistency. If the server does have a previous record, that value MUST match the upload's final size. If they do not match, the server MUST reject the request with a 400 (Bad Request)
status code.¶
The server MUST prevent that the offset exceeds the upload's final size when appending. If a final size has been recorded and the upload append request exceeds this value, the server MUST stop appending bytes to the upload once the offset reaches the final size and reject the request with a 400 (Bad Request)
status code. It is not sufficient to rely on the Content-Length
header field for enforcement because the header field might not be present.¶
The request content MAY be empty. If the Upload-Complete
field is then set to true, the client wants to complete the upload without appending additional data.¶
The following example shows an upload append. The client transfers the next 100 bytes at an offset of 100 and does not indicate that the upload is then completed. The server acknowledges the new offset:¶
+ + +The client MAY automatically attempt upload resumption when the connection is terminated unexpectedly, or if a 5xx (Server Error) status code is received. The client SHOULD NOT automatically retry if a 4xx (Client Error) status code is received.¶
+If the client wants to terminate the transfer without the ability to resume, it can send a DELETE
request to the upload resource. Doing so is an indication that the client is no longer interested in continuing the upload, and that the server can release any resources associated with it.¶
The client MUST NOT initiate cancellation without the knowledge of server support.¶
+The request MUST use the DELETE
method. The request MUST NOT include an Upload-Offset
or Upload-Complete
header field. The server MUST reject the request with a Upload-Offset
or Upload-Complete
header field with a 400 (Bad Request)
status code.¶
If the server successfully deactivates the upload resource, it MUST respond with a 204 (No Content)
status code.¶
The server MAY terminate any in-flight requests to the upload resource before sending the response by abruptly terminating their HTTP connection(s) or stream(s).¶
+If the server does not consider the upload resource to be active, it MUST respond with a 404 (Not Found)
status code.¶
If the server does not support cancellation, it MUST respond with a 405 (Method Not Allowed)
status code.¶
The following example shows an upload cancellation:¶
+ + +The Upload-Offset
request and response header field indicates the resumption offset of corresponding upload, counted in bytes. The Upload-Offset
field value is an Integer.¶
The Upload-Limit
response header field indicates limits applying the upload resource. The Upload-Limit
field value is a Dictionary. The following limits are defined:¶
The max-size
key specifies a maximum size that an upload resource is allowed to reach, counted in bytes. The value is an Integer.¶
The min-size
key specifies a minimum size for a resumable upload, counted in bytes. The server MAY NOT create an upload resource if the client indicates that the uploaded data is smaller than the minimum size by including the Content-Length
and Upload-Complete: ?1
fields, but the server MAY still accept the uploaded data. The value is an Integer.¶
The max-append-size
key specifies a maximum size counted in bytes for the request content in a single upload append request (Section 6). The server MAY reject requests exceeding this limit and a client SHOULD NOT send larger upload append requests. The value is an Integer.¶
The min-append-size
key specifies a minimum size counted in bytes for the request content in a single upload append request (Section 6) that does not complete the upload by setting the Upload-Complete: ?1
field. The server MAY reject non-completing requests below this limit and a client SHOULD NOT send smaller non-completing upload append requests. A server MUST NOT reject an upload append request due to smaller size if the request includes the Upload-Complete: ?1
field. The value is an Integer.¶
The expires
key specifies the remaining lifetime of the upload resource in seconds counted from the generation of the response by the server. After the resource's lifetime is reached, the server MAY make the upload resource inaccessible and a client SHOULD NOT attempt to access the upload resource. The lifetime MAY be extended but SHOULD NOT be reduced once the upload resource is created. The value is an Integer.¶
When parsing this header field, unrecognized keys MUST be ignored and MUST NOT fail the parsing to facilitate the addition of new limits in the future.¶
+A server that supports the creation of a resumable upload resource (Section 4) under a target URI MUST include the Upload-Limit
header field with the corresponding limits in a response to an OPTIONS
request sent to this target URI. If a server supports the creation of upload resources for any target URI, it MUST include the Upload-Limit
header field with the corresponding limits in a response to an OPTIONS
request with the *
target. The limits announced in an OPTIONS
response SHOULD NOT be less restrictive than the limits applied to an upload once the upload resource has been created. If the server does not apply any limits, it MUST use min-size=0
instead of an empty header value. A client can use an OPTIONS
request to discover support for resumable uploads and potential limits before creating an upload resource.¶
The Upload-Complete
request and response header field indicates whether the corresponding upload is considered complete. The Upload-Complete
field value is a Boolean.¶
The Upload-Complete
header field MUST only be used if support by the resource is known to the client (Section 4.1).¶
The Upload-Length
request and response header field indicates the number of bytes to be uploaded for the corresponding upload resource, counted in bytes. The Upload-Length
field value is an Integer.¶
application/partial-upload
+ The application/partial-upload
media type describes a contiguous block of data that should be uploaded to a resource. There is no minimum block size and the block might be empty. The start and end of the block might align with the start and end of the file that should be uploaded, but they are not required to be aligned.¶
This section defines the "https://iana.org/assignments/http-problem-types#mismatching-upload-offset" problem type [PROBLEM]. A server MAY use this problem type when responding to an upload append request (Section 6) to indicate that the Upload-Offset
header field in the request does not match the upload resource's offset.¶
Two problem type extension members are defined: the expected-offset
and provided-offset
members. A response using this problem type SHOULD populate both members, with the value of expected-offset
taken from the upload resource and the value of provided-offset
taken from the upload append request.¶
The following example shows an example response, where the resource's offset was 100, but the client attempted to append at offset 200:¶
+ +This section defines the "https://iana.org/assignments/http-problem-types#completed-upload" problem type [PROBLEM]. A server MAY use this problem type when responding to an upload append request (Section 6) to indicate that the upload has already been completed and cannot be modified.¶
+The following example shows an example response:¶
+ +The offset of an upload resource is the number of bytes that have been appended to the upload resource. Appended data cannot be removed from an upload and, therefore, the upload offset MUST NOT decrease. A server MUST NOT generate responses containing an Upload-Offset
header field with a value that is smaller than was included in previous responses for the same upload resource. This includes informational and final responses for upload creation (Section 4), upload appending (Section 6), and offset retrieval (Section 5).¶
If a server loses data that has been appended to an upload, it MUST consider the upload resource invalid and reject further use of the upload resource. The Upload-Offset
header field in responses serves as an acknowledgement of the append operation and as a guarantee that no retransmission of the data will be necessary. Client can use this guarantee to free resources associated to already uploaded data while the upload is still ongoing.¶
The 301 (Moved Permanently)
and 302 (Found)
status codes MUST NOT be used in offset retrieval (Section 5) and upload cancellation (Section 7) responses. For other responses, the upload resource MAY return a 308 (Permanent Redirect)
status code and clients SHOULD use the new permanent URI for subsequent requests. If the client receives a 307 (Temporary Redirect)
response to an offset retrieval (Section 5) request, it MAY apply the redirection directly in an immediate subsequent upload append (Section 6).¶
Since the codings listed in Content-Encoding
are a characteristic of the representation (see Section 8.4 of [HTTP]), both the client and the server always compute the values for Upload-Offset
and optionally Upload-Length
on the content coded data (that is, the representation data). Moreover, the content codings are retained throughout the entire upload, meaning that the server is not required to decode the representation data to support resumable uploads. See Appendix A of [DIGEST-FIELDS] for more information.¶
Unlike Content-Encoding
(see Section 8.4.1 of [HTTP]), Transfer-Encoding
(see Section 6.1 of [HTTP/1.1]) is a property of the message, not of the representation. Moreover, transfer codings can be applied in transit (e.g., by proxies). This means that a client does not have to consider the transfer codings to compute the upload offset, while a server is responsible for transfer decoding the message before computing the upload offset. The same applies to the value of Upload-Length
. Please note that the Content-Length
header field cannot be used in conjunction with the Transfer-Encoding
header field.¶
The integrity of an entire upload or individual upload requests can be verifying using digests from [DIGEST-FIELDS].¶
+Representation digests help verify the integrity of the entire data that has been uploaded so far, which might strech across multiple requests.¶
+If the client knows the integrity digest of the entire data before creating an upload resource, it MAY include the Repr-Digest
header field when creating an upload (Section 4). Once the upload is completed, the server can compute the integrity digest of the received upload representation and compare it to the provided digest. If the digests don't match the server SHOULD consider the transfer failed and not process the uploaded data further. This way, the integrity of the entire uploaded data can be protected.¶
Alternatively, when creating an upload (Section 4), the client MAY ask the server to compute and return the integrity digests using a Want-Repr-Digest
field conveying the preferred algorithms.
+The response SHOULD include at least one of the requested digests, but MAY not include it.
+The server SHOULD compute the representation digests using the preferred algorithms once the upload is complete and include the corresponding Repr-Digest
header field in the response.
+Alternatively, the server MAY compute the digest continuously during the upload and include the Repr-Digest
header field in responses to upload creation (Section 4) and upload appending requests (Section 6) even when the upload is not completed yet.
+This allows the client to simultaneously compute the digest of the transmitted upload data, compare its digest to the server's digest, and spot data integrity issues.
+If an upload is spread across multiple requests, data integrity issues can be found even before the upload is fully completed.¶
Content digests help verify the integrity of the content in an individual request.¶
+If the client knows the integrity digest of the content from an upload creation (Section 4) or upload appending (Section 6) request, it MAY include the Content-Digest
header field in the request. Once the content has been received, the server can compute the integrity digest of the received content and compare it to the provided digest. If the digests don't match the server SHOULD consider the transfer failed and not append the content to the upload resource. This way, the integrity of an individual request can be protected.¶
The server might process the uploaded data and make its results available in another resource during or after the upload. This subsequent resource is different from the upload resource created by the upload creation request (Section 4). The subsequent resource does not handle the upload process itself, but instead facilitates further interaction with the uploaded data. The server MAY indicate the location of this subsequent resource by including the Content-Location
header field in the informational or final responses generated while creating (Section 4), appending to (Section 6), or retrieving the offset (Section 5) of an upload. For example, a subsequent resource could allow the client to fetch information extracted from the uploaded data.¶
The definition of the upload creation request (Section 4) provides the client with flexibility to choose whether the file is fully or partially transferred in the first request, or if no file data is included at all. Which behavior is best largely depends on the client's capabilities, its intention to avoid data re-transmission, and its knowledge about the server's support for resumable uploads.¶
+The following subsections describe two typical upload strategies that are suited for common environments. Note that these modes are never explicitly communicated to the server and clients are not required to stick to one strategy, but can mix and adapt them to their needs.¶
+An "optimistic upload creation" can be used independent of the client's knowledge about the server's support for resumable uploads. However, the client must be capable of handling and processing interim responses. An upload creation request then includes the full file because the client anticipates that the file will be transferred without interruptions or resumed if an interruption occurs.¶
+The benefit of this method is that if the upload creation request succeeds, the file was transferred in a single request without additional round trips.¶
+A possible drawback is that the client might be unable to resume an upload. If an upload is interrupted before the client received a 104 (Upload Resumption Supported)
intermediate response with the upload URL, the client cannot resume that upload due to the missing upload URL. The intermediate response might not be received if the interruption happens too early in the message exchange, the server does not support resumable uploads at all, the server does not support sending the 104 (Upload Resumption Supported)
intermediate response, or an intermediary dropped the intermediate response. Without a 104 response, the client needs to either treat the upload as failed or retry the entire upload creation request if this is allowed by the application.¶
Optimistic upload creation allows clients and servers to automatically upgrade non-resumable uploads to resumable ones. In a non-resumable upload, the file is transferred in a single request, usually POST
or PUT
, without any ability to resume from interruptions. The client can offer the server to upgrade such a request to a resumable upload (see Section 4.1) by adding the Upload-Complete: ?1
header field to the original request. The Upload-Length
header field SHOULD be added if the upload's final size is known upfront. The request is not changed otherwise.¶
A server that supports resumable uploads at the target URI can create a resumable upload resource and send its upload URL in a 104 (Upload Resumption Supported)
intermediate response for the client to resume the upload after interruptions. A server that does not support resumable uploads or does not want to upgrade to a resumable upload for this request ignores the Upload-Complete: ?1
header. The transfer then falls back to a non-resumable upload without additional cost.¶
This upgrade can also be performed transparently by the client without the user taking an active role. When a user asks the client to send a non-resumable request, the client can perform the upgrade and handle potential interruptions and resumptions under the hood without involving the user. The last response received by the client is considered the response for the entire file upload and should be presented to the user.¶
+For a "careful upload creation" the client knows that the server supports resumable uploads and sends an empty upload creation request without including any file data. Upon successful response reception, the client can use the included upload URL to transmit the file data (Section 6) and resume the upload at any stage if an interruption occurs. The client should inspect the response for the Upload-Limit
header field, which would indicate limits applying to the remaining upload procedure.¶
The retransmission of file data or the ultimate upload failure that can happen with an "optimistic upload creation" is therefore avoided at the expense of an additional request that does not carry file data.¶
+This approach best suited if the client cannot receive intermediate responses, e.g. due to a limitation in the provided HTTP interface, or if large files are transferred where the cost of the additional request is miniscule compared to the effort of transferring the large file itself.¶
+The upload resource URL is the identifier used for modifying the upload. Without further protection of this URL, an attacker may obtain information about an upload, append data to it, or cancel it. To prevent this, the server SHOULD ensure that only authorized clients can access the upload resource. In addition, the upload resource URL SHOULD be generated in such a way that makes it hard to be guessed by unauthorized clients.¶
+Some servers or intermediaries provide scanning of content uploaded by clients. Any scanning mechanism that relies on receiving a complete file in a single request message can be defeated by resumable uploads because content can be split across multiple messages. Servers or intermediaries wishing to perform content scanning SHOULD consider how resumable uploads can circumvent scanning and take appropriate measures. Possible strategies include waiting for the upload to complete before scanning a full file, or disabling resumable uploads.¶
+Resumable uploads are vulnerable to Slowloris-style attacks [SLOWLORIS]. A malicious client may create upload resources and keep them alive by regularly sending PATCH
requests with no or small content to the upload resources. This could be abused to exhaust server resources by creating and holding open uploads indefinitely with minimal work.¶
Servers SHOULD provide mitigations for Slowloris attacks, such as increasing the maximum number of clients the server will allow, limiting the number of uploads a single client is allowed to make, imposing restrictions on the minimum transfer speed an upload is allowed to have, and restricting the length of time an upload resource can exist.¶
+IANA is asked to register the following entries in the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
+Field Name | +Status | +Reference | +
---|---|---|
Upload-Complete | +permanent | ++ Section 8.3 of this document | +
Upload-Offset | +permanent | ++ Section 8.1 of this document | +
Upload-Limit | +permanent | ++ Section 8.2 of this document | +
Upload-Length | +permanent | ++ Section 8.4 of this document | +
IANA is asked to register the following entry in the "HTTP Status Codes" registry:¶
+104 (suggested value)¶
+Upload Resumption Supported¶
+This document¶
+IANA is asked to register the following entry in the "Media Types" registry:¶
+application¶
+partial-upload¶
+N/A¶
+N/A¶
+binary¶
+see Section 18 of this document¶
+N/A¶
+This document¶
+Applications that transfer files over unreliable networks or want pause- and resumable uploads.¶
+N/A¶
+Additional information:¶
+Deprecated alias names for this type: N/A¶
+Magic number(s): N/A¶
+File extension(s): N/A¶
+Macintosh file type code(s): N/A¶
+Windows Clipboard Name: N/A¶
+See the Authors' Addresses section of this document.¶
+COMMON¶
+N/A¶
+See the Authors' Addresses section of this document.¶
+IETF¶
+IANA is asked to register the following entry in the "HTTP Problem Types" registry:¶
+https://iana.org/assignments/http-problem-types#mismatching-upload-offset +Title:¶
+Mismatching Upload Offset +Recommended HTTP status code:¶
+409 +Reference:¶
+This document¶
+IANA is asked to register the following entry in the "HTTP Problem Types" registry:¶
+ +The server is allowed to respond to upload creation (Section 4) requests with a 104 (Upload Resumption Supported)
intermediate response as soon as the server has validated the request. This way, the client knows that the server supports resumable uploads before the complete response is received. The benefit is the clients can defer starting the actual data transfer until the server indicates full support (i.e. resumable are supported, the provided upload URL is active etc).¶
On the contrary, support for intermediate responses (the 1XX
range) in existing software is limited or not at all present. Such software includes proxies, firewalls, browsers, and HTTP libraries for clients and server. Therefore, the 104 (Upload Resumption Supported)
status code is optional and not mandatory for the successful completion of an upload. Otherwise, it might be impossible in some cases to implement resumable upload servers using existing software packages. Furthermore, as parts of the current internet infrastructure currently have limited support for intermediate responses, a successful delivery of a 104 (Upload Resumption Supported)
from the server to the client should be assumed.¶
We hope that support for intermediate responses increases in the near future, to allow a wider usage of 104 (Upload Resumption Supported)
.¶
This specification includes a section about feature detection (it was called service discovery in earlier discussions, but this name is probably ill-suited). The idea is to allow resumable uploads to be transparently implemented by HTTP clients. This means that application developers just keep using the same API of their HTTP library as they have done in the past with traditional, non-resumable uploads. Once the HTTP library gets updated (e.g. because mobile OS or browsers start implementing resumable uploads), the HTTP library can transparently decide to use resumable uploads without explicit configuration by the application developer. Of course, in order to use resumable uploads, the HTTP library needs to know whether the server supports resumable uploads. If no support is detected, the HTTP library should use the traditional, non-resumable upload technique. We call this process feature detection.¶
+Ideally, the technique used for feature detection meets following criteria (there might not be one approach which fits all requirements, so we have to prioritize them):¶
+Avoid additional roundtrips by the client, if possible (i.e. an additional HTTP request by the client should be avoided).¶
+Be backwards compatible to HTTP/1.1 and existing network infrastructure: This means to avoid using new features in HTTP/2, or features which might require changes to existing network infrastructure (e.g. nginx or HTTP libraries)¶
+Conserve the user's privacy (i.e. the feature detection should not leak information to other third-parties about which URLs have been connected to)¶
+Following approaches have already been considered in the past. All except the last approaches have not been deemed acceptable and are therefore not included in the specification. This follow list is a reference for the advantages and disadvantages of some approaches:¶
+Include a support statement in the SETTINGS frame. The SETTINGS frame is a HTTP/2 feature and is sent by the server to the client to exchange information about the current connection. The idea was to include an additional statement in this frame, so the client can detect support for resumable uploads without an additional roundtrip. The problem is that this is not compatible with HTTP/1.1. Furthermore, the SETTINGS frame is intended for information about the current connection (not bound to a request/response) and might not be persisted when transmitted through a proxy.¶
+Include a support statement in the DNS record. The client can detect support when resolving a domain name. Of course, DNS is not semantically the correct layer. Also, DNS might not be involved if the record is cached or retrieved from a hosts files.¶
+Send a HTTP request to ask for support. This is the easiest approach where the client sends an OPTIONS request and uses the response to determine if the server indicates support for resumable uploads. An alternative is that the client sends the request to a well-known URL to obtain this response, e.g. /.well-known/resumable-uploads
. Of course, while being fully backwards-compatible, it requires an additional roundtrip.¶
Include a support statement in previous responses. In many cases, the file upload is not the first time that the client connects to the server. Often additional requests are sent beforehand for authentication, data retrieval etc. The responses for those requests can also include a header field which indicates support for resumable uploads. There are two options:
+- Use the standardized Alt-Svc
response header field. However, it has been indicated to us that this header field might be reworked in the future and could also be semantically different from our intended usage.
+- Use a new response header field Resumable-Uploads: https://example.org/files/*
to indicate under which endpoints support for resumable uploads is available.¶
Send a 104 intermediate response to indicate support. The clients normally starts a traditional upload and includes a header field indicate that it supports resumable uploads (e.g. Upload-Offset: 0
). If the server also supports resumable uploads, it will immediately respond with a 104 intermediate response to indicate its support, before further processing the request. This way the client is informed during the upload whether it can resume from possible connection errors or not. While an additional roundtrip is avoided, the problem with that solution is that many HTTP server libraries do not support sending custom 1XX responses and that some proxies may not be able to handle new 1XX status codes correctly.¶
Send a 103 Early Hint response to indicate support. This approach is the similar to the above one, with one exception: Instead of a new 104 (Upload Resumption Supported)
status code, the existing 103 (Early Hint)
status code is used in the intermediate response. The 103 code would then be accompanied by a header field indicating support for resumable uploads (e.g. Resumable-Uploads: 1
). It is unclear whether the Early Hints code is appropriate for that, as it is currently only used to indicate resources for prefetching them.¶
When an upload is created (Section 4), the Content-Type
and Content-Disposition
header fields are allowed to be included. They are intended to be a standardized way of communicating the file name and file type, if available. However, this is not without controversy. Some argue that since these header fields are already defined in other specifications, it is not necessary to include them here again. Furthermore, the Content-Disposition
header field's format is not clearly enough defined. For example, it is left open which disposition value should be used in the header field. There needs to be more discussion whether this approach is suited or not.¶
However, from experience with the tus project, users are often asking for a way to communicate the file name and file type. Therefore, we believe it is help to explicitly include an approach for doing so.¶
+Are multipart requests supported? Yes, requests whose content is encoded using the multipart/form-data
are implicitly supported. The entire encoded content can be considered as a single file, which is then uploaded using the resumable protocol. The server, of course, must store the delimiter ("boundary") separating each part and must be able to parse the multipart format once the upload is completed.¶
This document is based on an Internet-Draft specification written by Jiten Mehta, Stefan Matsson, and the authors of this document.¶
+The tus v1 protocol is a specification for a resumable file upload protocol over HTTP. It inspired the early design of this protocol. Members of the tus community helped significantly in the process of bringing this work to the IETF.¶
+The authors would like to thank Mark Nottingham for substantive contributions to the text.¶
+This section is to be removed before publishing as an RFC.¶
+None yet¶
+Add note about Content-Location
for referring to subsequent resources.¶
Require application/partial-upload
for appending to uploads.¶
Explain handling of content and transfer codings.¶
+Add problem types for mismatching offsets and completed uploads.¶
+Clarify that completed uploads must not be appended to.¶
+Describe interaction with Digest Fields from RFC9530.¶
+Require that upload offset does not decrease over time.¶
+Add Upload-Limit header field.¶
+Increase the draft interop version.¶
+Add upload progress notifications via informational responses.¶
+Add security consideration regarding request filtering.¶
+Explain the use of empty requests for creation uploads and appending.¶
+Extend security consideration to include resource exhaustion attacks.¶
+Allow 200 status codes for offset retrieval.¶
+Increase the draft interop version.¶
+None¶
+Split the Upload Transfer Procedure into the Upload Creation Procedure and the Upload Appending Procedure.¶
+Internet-Draft | +Retrofit Structured Fields | +January 2025 | +
Nottingham | +Expires 11 July 2025 | +[Page] | +
This specification nominates a selection of existing HTTP fields whose values are compatible with Structured Fields syntax, so that they can be handled as such (subject to certain caveats).¶
+To accommodate some additional fields whose syntax is not compatible, it also defines mappings of their semantics into Structured Fields. It does not specify how to convey them in HTTP messages.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-retrofit/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/retrofit.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+Structured Field Values for HTTP [STRUCTURED-FIELDS] introduced a data model with associated parsing and serialization algorithms for use by new HTTP field values. Fields that are defined as Structured Fields can bring advantages that include:¶
+Improved interoperability and security: precisely defined parsing and serialisation algorithms are typically not available for fields defined with just ABNF and/or prose.¶
+Reuse of common implementations: many parsers for other fields are specific to a single field or a small family of fields.¶
+Canonical form: because a deterministic serialisation algorithm is defined for each type, Structure Fields have a canonical representation.¶
+Enhanced API support: a regular data model makes it easier to expose field values as a native data structure in implementations.¶
+Alternative serialisations: While [STRUCTURED-FIELDS] defines a textual serialisation of that data model, other, more efficient serialisations of the underlying data model are also possible.¶
+However, a field needs to be defined as a Structured Field for these benefits to be realised. Many existing fields are not, making up the bulk of header and trailer fields seen in HTTP traffic on the internet.¶
+This specification defines how a selection of existing HTTP fields can be handled as Structured Fields, so that these benefits can be realised -- thereby making them Retrofit Structured Fields.¶
+It does so using two techniques. Section 2 lists compatible fields -- those that can be handled as if they were Structured Fields due to the similarity of their defined syntax to that in Structured Fields. Section 3 lists mapped fields -- those whose syntax needs to be transformed into an underlying data model which is then mapped into that defined by Structured Fields.¶
+Retrofitting data structures onto existing and widely-deployed HTTP fields requires careful handling to assure interoperability and security. This section highlights considerations for applications that use Retrofit Structured Fields.¶
+While the majority of field values seen in HTTP traffic should be able to be parsed or mapped successfully, some will not. An application using Retrofit Structured Fields will need to define how unsuccessful values will be handled.¶
+For example, an API that exposes field values using Structured Fields data types might make the field value available as a string in cases where the field did not successfully parse or map.¶
+The mapped field values described in Section 3 are not compatible with the original syntax of their fields, and so cannot be used unless parties processing them have explicitly indicated their support for that form of the field value. An application using Retrofit Structured Fields will need to define how to negotiate support for them.¶
+For example, an alternative serialization of fields that takes advantage of Structured Fields would need to establish an explicit negotiation mechanism to assure that both peers would handle that serialization appropriately before using it.¶
+ +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+The HTTP fields listed in Table 1 have values that can be handled as Structured Field Values according to the parsing and serialisation algorithms in [STRUCTURED-FIELDS] corresponding to the listed top-level type, subject to the caveats in Section 2.1.¶
+The top-level types are chosen for compatibility with the defined syntax of the field as well as with actual internet traffic. However, not all instances of these fields will successfully parse as a Structured Field Value. This might be because the field value is clearly invalid, or it might be because it is valid but not parseable as a Structured Field.¶
+An application using this specification will need to consider how to handle such field values. Depending on its requirements, it might be advisable to reject such values, treat them as opaque strings, or attempt to recover a Structured Field Value from them in an ad hoc fashion.¶
+Field Name | +Structured Type | +
---|---|
Accept | +List | +
Accept-Encoding | +List | +
Accept-Language | +List | +
Accept-Patch | +List | +
Accept-Post | +List | +
Accept-Ranges | +List | +
Access-Control-Allow-Credentials | +Item | +
Access-Control-Allow-Headers | +List | +
Access-Control-Allow-Methods | +List | +
Access-Control-Allow-Origin | +Item | +
Access-Control-Expose-Headers | +List | +
Access-Control-Max-Age | +Item | +
Access-Control-Request-Headers | +List | +
Access-Control-Request-Method | +Item | +
Age | +Item | +
Allow | +List | +
ALPN | +List | +
Alt-Svc | +Dictionary | +
Alt-Used | +Item | +
Cache-Control | +Dictionary | +
CDN-Loop | +List | +
Clear-Site-Data | +List | +
Connection | +List | +
Content-Encoding | +List | +
Content-Language | +List | +
Content-Length | +List | +
Content-Type | +Item | +
Cross-Origin-Resource-Policy | +Item | +
DNT | +Item | +
Expect | +Dictionary | +
Expect-CT | +Dictionary | +
Host | +Item | +
Keep-Alive | +Dictionary | +
Max-Forwards | +Item | +
Origin | +Item | +
Pragma | +Dictionary | +
Prefer | +Dictionary | +
Preference-Applied | +Dictionary | +
Retry-After | +Item | +
Sec-WebSocket-Extensions | +List | +
Sec-WebSocket-Protocol | +List | +
Sec-WebSocket-Version | +Item | +
Server-Timing | +List | +
Surrogate-Control | +Dictionary | +
TE | +List | +
Timing-Allow-Origin | +List | +
Trailer | +List | +
Transfer-Encoding | +List | +
Upgrade-Insecure-Requests | +Item | +
Vary | +List | +
X-Content-Type-Options | +Item | +
X-Frame-Options | +Item | +
X-XSS-Protection | +List | +
Note the following caveats regarding compatibility:¶
+Some values may fail to parse as Structured Fields, even though they are valid according to their originally specified syntax. For example, HTTP parameter names are case-insensitive (per Section 5.6.6 of [HTTP]), but Structured Fields require them to be all-lowercase. +Likewise, many Dictionary-based fields (e.g., Cache-Control, Expect-CT, Pragma, Prefer, Preference-Applied, Surrogate-Control) have case-insensitive keys. +Similarly, the parameters rule in HTTP (see Section 5.6.6 of [HTTP]) allows whitespace before the ";" delimiter, but Structured Fields does not. +And, Section 5.6.4 of [HTTP] allows backslash-escaping most characters in quoted strings, whereas Structured Field Strings only escape "\" and DQUOTE. The vast majority of fields seen in typical traffic do not exhibit these behaviors.¶
+Parsing algorithms specified (or just widely implemented) for current HTTP headers may differ from those in Structured Fields in details such as error handling. For example, HTTP specifies that repeated directives in the Cache-Control header field have a different precedence than that assigned by a Dictionary structured field (which Cache-Control is mapped to).¶
+In Structured Fields, tokens are required to begin with an alphabetic character or "*", whereas HTTP tokens allow a wider range of characters. This prevents use of mapped values that begin with one of these characters. For example, media types, field names, methods, range-units, character and transfer codings that begin with a number or special character other than "*" might be valid HTTP protocol elements, but will not be able to be represented as Structured Field Tokens.¶
+Structured Fields Integers can have at most 15 digits; larger values will not be able to be represented in them.¶
+Fields whose values contain IPv6 literal addresses (such as CDN-Loop, Host, and Origin) are not able to be represented as Structured Fields Tokens, because the brackets used to delimit them are not allowed in Tokens.¶
+Empty and whitespace-only field values are considered errors in Structured Fields. For compatible fields, an empty field indicates that the field should be silently ignored.¶
+Some ALPN tokens (e.g., h3-Q43
) do not conform to key's syntax, and therefore cannot be represented as a Token. Since the final version of HTTP/3 uses the h3
token, this shouldn't be a long-term issue, although future tokens may again violate this assumption.¶
Note that Content-Length is defined as a List because it is not uncommon for implementations to mistakenly send multiple values. See Section 8.6 of [HTTP] for handling requirements.¶
+Only the delta-seconds form of Retry-After can be represented; a Retry-After value containing a http-date will need to be converted into delta-seconds to be conveyed as a Structured Field Value.¶
+Some HTTP field values have syntax that cannot be successfully parsed as Structured Field values. Instead, it is necessary to map them into a Structured Field value.¶
+For example, the Date HTTP header field carries a date:¶
+ +Its value would be mapped to:¶
+ +Unlike those listed in Section 2, these representations are not compatible with the original fields' syntax, and MUST NOT be used unless they are explicitly and unambiguously supported. For example, this means that sending them to a next-hop recipient in HTTP requires prior negotiation. This specification does not define how to do so.¶
+The field names in Table 2 have values that can be mapped into Structured Field values by treating the original field's value as a String.¶
+Field Name | +
---|
Content-Location | +
Location | +
Referer | +
For example, this Location field:¶
+ +would have a mapped value of:¶
++"https://example.com/foo" +¶ +
The field names in Table 3 have values that can be mapped into Structured Field values by parsing their payload according to Section 5.6.7 of [HTTP] and representing the result as a Date.¶
+Field Name | +
---|
Date | +
Expires | +
If-Modified-Since | +
If-Unmodified-Since | +
Last-Modified | +
For example, an Expires field's value could be mapped as:¶
+ +Please add the following note to the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
+A prefix of "*" in the Structured Type column indicates that it is a retrofit type (i.e., not +natively Structured); see RFC nnnn.¶
+Then, add a new column, "Structured Type", with the values from Section 2 assigned to the nominated registrations, prefixing each with "*" to indicate that it is a retrofit type.¶
+Finally, add a new column to the "Cookie Attribute Registry" established by [COOKIES] with the title "Structured Type", using information from Table 4.¶
+Section 2 identifies existing HTTP fields that can be parsed and serialised with the algorithms defined in [STRUCTURED-FIELDS]. Variances from existing parser behavior might be exploitable, particularly if they allow an attacker to target one implementation in a chain (e.g., an intermediary). However, given the considerable variance in parsers already deployed, convergence towards a single parsing algorithm is likely to have a net security benefit in the longer term.¶
+Section 3 defines alternative representations of existing fields. Because downstream consumers might interpret the message differently based upon whether they recognise the alternative representation, implementations are prohibited from generating such values unless they have negotiated support for them with their peer. This specification does not define such a mechanism, but any such definition needs to consider the implications of doing so carefully.¶
+Internet-Draft | +Cookies: HTTP State Management Mechanism | +January 2025 | +
Bingler, et al. | +Expires 11 July 2025 | +[Page] | +
This document defines the HTTP Cookie and Set-Cookie header fields. These +header fields can be used by HTTP servers to store state (called cookies) at +HTTP user agents, letting the servers maintain a stateful session over the +mostly stateless HTTP protocol. Although cookies have many historical +infelicities that degrade their security and privacy, the Cookie and Set-Cookie +header fields are widely used on the Internet. This document obsoletes RFC +6265.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-rfc6265bis/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/6265bis.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
++ This document may contain material from IETF Documents or IETF + Contributions published or made publicly available before November + 10, 2008. The person(s) controlling the copyright in some of this + material may not have granted the IETF Trust the right to allow + modifications of such material outside the IETF Standards Process. + Without obtaining an adequate license from the person(s) + controlling the copyright in such materials, this document may not + be modified outside the IETF Standards Process, and derivative + works of it may not be created outside the IETF Standards Process, + except to format it for publication as an RFC or to translate it + into languages other than English.¶
+This document defines the HTTP Cookie and Set-Cookie header fields. Using +the Set-Cookie header field, an HTTP server can pass name/value pairs and +associated metadata (called cookies) to a user agent. When the user agent makes +subsequent requests to the server, the user agent uses the metadata and other +information to determine whether to return the name/value pairs in the Cookie +header field.¶
+Although simple on their surface, cookies have a number of complexities. For +example, the server indicates a scope for each cookie when sending it to the +user agent. The scope indicates the maximum amount of time in which the user +agent should return the cookie, the servers to which the user agent should +return the cookie, and the connection types for which the cookie is applicable.¶
+For historical reasons, cookies contain a number of security and privacy +infelicities. For example, a server can indicate that a given cookie is +intended for "secure" connections, but the Secure attribute does not provide +integrity in the presence of an active network attacker. Similarly, cookies +for a given host are shared across all the ports on that host, even though the +usual "same-origin policy" used by web browsers isolates content retrieved via +different ports.¶
+This specification applies to developers of both cookie-producing servers and +cookie-consuming user agents. Section 3.2 helps to clarify the +intended target audience for each implementation type.¶
+To maximize interoperability with user agents, servers SHOULD limit themselves +to the well-behaved profile defined in Section 4 when generating cookies.¶
+User agents MUST implement the more liberal processing rules defined in Section 5, +in order to maximize interoperability with existing servers that do not +conform to the well-behaved profile defined in Section 4.¶
+This document specifies the syntax and semantics of these header fields as they are +actually used on the Internet. In particular, this document does not create +new syntax or semantics beyond those in use today. The recommendations for +cookie generation provided in Section 4 represent a preferred subset of current +server behavior, and even the more liberal cookie processing algorithm provided +in Section 5 does not recommend all of the syntactic and semantic variations in +use today. Where some existing software differs from the recommended protocol +in significant ways, the document contains a note explaining the difference.¶
+ +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", +"SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be +interpreted as described in [RFC2119].¶
+Requirements phrased in the imperative as part of algorithms (such as "strip any +leading space characters" or "return false and abort these steps") are to be +interpreted with the meaning of the key word ("MUST", "SHOULD", "MAY", etc.) +used in introducing the algorithm.¶
+Conformance requirements phrased as algorithms or specific steps can be +implemented in any manner, so long as the end result is equivalent. In +particular, the algorithms defined in this specification are intended to be +easy to understand and are not intended to be performant.¶
+This specification uses the Augmented Backus-Naur Form (ABNF) notation of +[RFC5234].¶
+The following core rules are included by reference, as defined in [RFC5234], +Appendix B.1: ALPHA (letters), CR (carriage return), CRLF (CR LF), CTLs +(controls), DIGIT (decimal 0-9), DQUOTE (double quote), HEXDIG +(hexadecimal 0-9/A-F/a-f), LF (line feed), NUL (null octet), OCTET (any +8-bit sequence of data except NUL), SP (space), HTAB (horizontal tab), +CHAR (any [USASCII] character), VCHAR (any visible [USASCII] character), +and WSP (whitespace).¶
+The OWS (optional whitespace) and BWS (bad whitespace) rules are defined in +Section 5.6.3 of [HTTP].¶
+The terms "user agent", "client", "server", "proxy", and "origin server" have +the same meaning as in the HTTP/1.1 specification ([HTTP], Section 3).¶
+The request-host is the name of the host, as known by the user agent, to which +the user agent is sending an HTTP request or from which it is receiving an HTTP +response (i.e., the name of the host to which it sent the corresponding HTTP +request).¶
+The term request-uri refers to "target URI" as defined in Section 7.1 of [HTTP].¶
+Two sequences of octets are said to case-insensitively match each other if and +only if they are equivalent under the i;ascii-casemap collation defined in +[RFC4790].¶
+The term string means a sequence of non-NUL octets.¶
+The terms "active browsing context", "active document", "ancestor navigables", +"container document", "content navigable", "dedicated worker", "Document", +"inclusive ancestor navigables", "navigable", "opaque origin", "sandboxed +origin browsing context flag", "shared worker", "the worker's Documents", +"top-level traversable", and "WorkerGlobalScope" are defined in [HTML].¶
+"Service Workers" are defined in the Service Workers specification +[SERVICE-WORKERS].¶
+The term "origin", the mechanism of deriving an origin from a URI, and the "the +same" matching algorithm for origins are defined in [RFC6454].¶
+"Safe" HTTP methods include GET
, HEAD
, OPTIONS
, and TRACE
, as defined
+in Section 9.2.1 of [HTTP].¶
A domain's "public suffix" is the portion of a domain that is controlled by a
+public registry, such as "com", "co.uk", and "pvt.k12.wy.us". A domain's
+"registrable domain" is the domain's public suffix plus the label to its left.
+That is, for https://www.site.example
, the public suffix is example
, and the
+registrable domain is site.example
. Whenever possible, user agents SHOULD
+use an up-to-date public suffix list, such as the one maintained by the Mozilla
+project at [PSL].¶
The term "request", as well as a request's "client", "current url", "method", +"target browsing context", and "url list", are defined in [FETCH].¶
+The term "non-HTTP APIs" refers to non-HTTP mechanisms used to set and retrieve +cookies, such as a web browser API that exposes cookies to scripts.¶
+The term "top-level navigation" refers to a navigation of a top-level +traversable.¶
+This section outlines a way for an origin server to send state information to a +user agent and for the user agent to return the state information to the origin +server.¶
+To store state, the origin server includes a Set-Cookie header field in an HTTP +response. In subsequent requests, the user agent returns a Cookie request +header field to the origin server. The Cookie header field contains cookies the user agent +received in previous Set-Cookie header fields. The origin server is free to ignore +the Cookie header field or use its contents for an application-defined purpose.¶
+Origin servers MAY send a Set-Cookie response header field with any response. An +origin server can include multiple Set-Cookie header fields in a single response. +The presence of a Cookie or a Set-Cookie header field does not preclude HTTP +caches from storing and reusing a response.¶
+Origin servers SHOULD NOT fold multiple Set-Cookie header fields into a single +header field. The usual mechanism for folding HTTP headers fields (i.e., as +defined in Section 5.3 of [HTTP]) might change the semantics of the Set-Cookie header +field because the %x2C (",") character is used by Set-Cookie in a way that +conflicts with such folding.¶
+User agents MAY ignore Set-Cookie header fields based on response status codes or +the user agent's cookie policy (see Section 5.3).¶
+Using the Set-Cookie header field, a server can send the user agent a short string +in an HTTP response that the user agent will return in future HTTP requests that +are within the scope of the cookie. For example, the server can send the user +agent a "session identifier" named SID with the value 31d4d96e407aad42. The +user agent then returns the session identifier in subsequent requests.¶
++== Server -> User Agent == + +Set-Cookie: SID=31d4d96e407aad42 + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42 +¶ +
The server can alter the default scope of the cookie using the Path and +Domain attributes. For example, the server can instruct the user agent to +return the cookie to every path and every subdomain of site.example.¶
++== Server -> User Agent == + +Set-Cookie: SID=31d4d96e407aad42; Path=/; Domain=site.example + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42 +¶ +
As shown in the next example, the server can store multiple cookies at the user +agent. For example, the server can store a session identifier as well as the +user's preferred language by returning two Set-Cookie header fields. Notice +that the server uses the Secure and HttpOnly attributes to provide +additional security protections for the more sensitive session identifier (see +Section 4.1.2).¶
++== Server -> User Agent == + +Set-Cookie: SID=31d4d96e407aad42; Path=/; Secure; HttpOnly +Set-Cookie: lang=en-US; Path=/; Domain=site.example + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42; lang=en-US +¶ +
Notice that the Cookie header field above contains two cookies, one named SID and +one named lang.¶
+Cookie names are case-sensitive, meaning that if a server sends the user agent +two Set-Cookie header fields that differ only in their name's case the user +agent will store and return both of those cookies in subsequent requests.¶
++== Server -> User Agent == + +Set-Cookie: SID=31d4d96e407aad42 +Set-Cookie: sid=31d4d96e407aad42 + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42; sid=31d4d96e407aad42 +¶ +
If the server wishes the user agent to persist the cookie over +multiple "sessions" (e.g., user agent restarts), the server can specify an +expiration date in the Expires attribute. Note that the user agent might +delete the cookie before the expiration date if the user agent's cookie store +exceeds its quota or if the user manually deletes the server's cookie.¶
++== Server -> User Agent == + +Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2021 10:18:14 GMT + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42; lang=en-US +¶ +
Finally, to remove a cookie, the server returns a Set-Cookie header field with an +expiration date in the past. The server will be successful in removing the +cookie only if the Path and the Domain attribute in the Set-Cookie header field +match the values used when the cookie was created.¶
++== Server -> User Agent == + +Set-Cookie: lang=; Expires=Sun, 06 Nov 1994 08:49:37 GMT + +== User Agent -> Server == + +Cookie: SID=31d4d96e407aad42 +¶ +
The upcoming two sections, Section 4 and Section 5, discuss +the set of requirements for two distinct types of implementations. This section +is meant to help guide implementers in determining which set of requirements +best fits their goals. Choosing the wrong set of requirements could result in a +lack of compatibility with other cookie implementations.¶
+It's important to note that being compatible means different things +depending on the implementer's goals. These differences have built up over time +due to both intentional and unintentional spec changes, spec interpretations, +and historical implementation differences.¶
+This section roughly divides implementers of the cookie spec into two types, +producers and consumers. These are not official terms and are only used here to +help readers develop an intuitive understanding of the use cases.¶
+ + +This section describes the syntax and semantics of a well-behaved profile of the +Cookie and Set-Cookie header fields.¶
+ + +This section specifies the Cookie and Set-Cookie header fields in sufficient +detail that a user agent implementing these requirements precisely can +interoperate with existing servers (even those that do not conform to the +well-behaved profile described in Section 4).¶
+A user agent could enforce more restrictions than those specified herein (e.g., +restrictions specified by its cookie policy, described in Section 7.2). +However, such additional restrictions may reduce the likelihood that a user +agent will be able to interoperate with existing servers.¶
+This section defines some algorithms used by user agents to process specific +subcomponents of the Cookie and Set-Cookie header fields.¶
+ +A canonicalized host name is the string generated by the following algorithm:¶
+Convert the host name to a sequence of individual domain name labels.¶
+Convert each label that is not a Non-Reserved LDH (NR-LDH) label, to an +A-label (see Section 2.3.2.1 of [RFC5890] for the former and latter).¶
+Concatenate the resulting labels, separated by a %x2E (".") character.¶
+A string domain-matches a given domain string if at least one of the following +conditions hold:¶
+ +Two origins are same-site if they satisfy the "same site" criteria defined in +[SAMESITE]. A request is "same-site" if the following criteria are true:¶
+The request is not the result of a reload navigation triggered through a +user interface element (as defined by the user agent; e.g., a request +triggered by the user clicking a refresh button on a toolbar).¶
+The request's current url's origin is same-site with the request's +client's "site for cookies" (which is an origin), or if the request has no +client or the request's client is null.¶
+Requests which are the result of a reload navigation triggered through a user +interface element are same-site if the reloaded document was originally +navigated to via a same-site request. A request that is not "same-site" is +instead "cross-site".¶
+The request's client's "site for cookies" is calculated depending upon its +client's type, as described in the following subsections:¶
+The URI displayed in a user agent's address bar is the only security context +directly exposed to users, and therefore the only signal users can reasonably +rely upon to determine whether or not they trust a particular website. The +origin of that URI represents the context in which a user most likely believes +themselves to be interacting. We'll define this origin, the top-level +traversable's active document's origin, as the "top-level origin".¶
+For a document displayed in a top-level traversable, we can stop here: the +document's "site for cookies" is the top-level origin.¶
+For container documents, we need to audit the origins of each of a document's +ancestor navigables' active documents in order to account for the +"multiple-nested scenarios" described in Section 4 of [RFC7034]. A document's +"site for cookies" is the top-level origin if and only if the top-level origin +is same-site with the document's origin, and with each of the document's +ancestor documents' origins. Otherwise its "site for cookies" is an origin set +to an opaque origin.¶
+Given a Document (document
), the following algorithm returns its "site for
+cookies":¶
Let top-document
be the active document in document
's navigable's
+top-level traversable.¶
Let top-origin
be the origin of top-document
's URI if top-document
's
+sandboxed origin browsing context flag is set, and top-document
's origin
+otherwise.¶
Let documents
be a list consisting of the active documents of
+document
's inclusive ancestor navigables.¶
For each item
in documents
:¶
Return top-origin
.¶
Note: This algorithm only applies when the entire chain of documents from
+top-document
to document
are all active.¶
Worker-driven requests aren't as clear-cut as document-driven requests, as +there isn't a clear link between a top-level traversable and a worker. +This is especially true for Service Workers [SERVICE-WORKERS], which may +execute code in the background, without any document visible at all.¶
+Note: The descriptions below assume that workers must be same-origin with +the documents that instantiate them. If this invariant changes, we'll need to +take the worker's script's URI into account when determining their status.¶
+ +Service Workers are more complicated, as they act as a completely separate +execution context with only tangential relationship to the Document which +registered them.¶
+How user agents handle Service Workers may differ, but user agents SHOULD +match the [SERVICE-WORKERS] specification.¶
+User agents' requirements for cookie name prefixes differ slightly from +servers' (Section 4.1.3) in that UAs MUST match the prefix string +case-insensitively.¶
+The normative requirements for the prefixes are detailed in the storage model +algorithm defined in Section 5.7.¶
+This is because some servers will process cookies case-insensitively, resulting +in them unintentionally miscapitalizing and accepting miscapitalized prefixes.¶
+For example, if a server sends the following Set-Cookie
header field¶
+Set-Cookie: __SECURE-SID=12345 +¶ +
to a UA which checks prefixes case-sensitively it will accept this cookie and
+the server would incorrectly believe the cookie is subject the same guarantees
+as one spelled __Secure-
.¶
Additionally the server is vulnerable to an attacker that purposefully
+miscapitalizes a cookie in order to impersonate a prefixed cookie. For example,
+a site already has a cookie __Secure-SID=12345
and by some means an attacker
+sends the following Set-Cookie
header field for the site to a UA which checks
+prefixes case-sensitively.¶
+Set-Cookie: __SeCuRe-SID=evil +¶ +
The next time a user visits the site the UA will send both cookies:¶
++Cookie: __Secure-SID=12345; __SeCuRe-SID=evil +¶ +
The server, being case-insensitive, won't be able to tell the difference +between the two cookies allowing the attacker to compromise the site.¶
+To prevent these issues, UAs MUST match cookie name prefixes case-insensitive.¶
+Note: Cookies with different names are still considered separate by UAs. So
+both __Secure-foo=bar
and __secure-foo=baz
can exist as distinct cookies
+simultaneously and both would have the requirements of the __Secure-
prefix
+applied.¶
The following are examples of Set-Cookie
header fields that would be rejected
+by a conformant user agent.¶
+Set-Cookie: __Secure-SID=12345; Domain=site.example +Set-Cookie: __secure-SID=12345; Domain=site.example +Set-Cookie: __SECURE-SID=12345; Domain=site.example +Set-Cookie: __Host-SID=12345 +Set-Cookie: __host-SID=12345; Secure +Set-Cookie: __host-SID=12345; Domain=site.example +Set-Cookie: __HOST-SID=12345; Domain=site.example; Path=/ +Set-Cookie: __Host-SID=12345; Secure; Domain=site.example; Path=/ +Set-Cookie: __host-SID=12345; Secure; Domain=site.example; Path=/ +Set-Cookie: __HOST-SID=12345; Secure; Domain=site.example; Path=/ +¶ +
Whereas the following Set-Cookie
header fields would be accepted if set from
+a secure origin.¶
+Set-Cookie: __Secure-SID=12345; Domain=site.example; Secure +Set-Cookie: __secure-SID=12345; Domain=site.example; Secure +Set-Cookie: __SECURE-SID=12345; Domain=site.example; Secure +Set-Cookie: __Host-SID=12345; Secure; Path=/ +Set-Cookie: __host-SID=12345; Secure; Path=/ +Set-Cookie: __HOST-SID=12345; Secure; Path=/ +¶ +
The user agent stores the following fields about each cookie: name, value, +expiry-time, domain, path, creation-time, last-access-time, +persistent-flag, host-only-flag, secure-only-flag, http-only-flag, +and same-site-flag.¶
+When the user agent "receives a cookie" from a request-uri with name +cookie-name, value cookie-value, and attributes cookie-attribute-list, the +user agent MUST process the cookie as follows:¶
+A user agent MAY ignore a received cookie in its entirety. See +Section 5.3.¶
+If cookie-name is empty and cookie-value is empty, abort these steps and +ignore the cookie entirely.¶
+If the cookie-name or the cookie-value contains a +%x00-08 / %x0A-1F / %x7F character (CTL characters excluding HTAB), +abort these steps and ignore the cookie entirely.¶
+If the sum of the lengths of cookie-name and cookie-value is more than +4096 octets, abort these steps and ignore the cookie entirely.¶
+Create a new cookie with name cookie-name, value cookie-value. Set the +creation-time and the last-access-time to the current date and time.¶
+If the cookie-attribute-list contains an attribute with an attribute-name +of "Max-Age":¶
+Set the cookie's persistent-flag to true.¶
+Set the cookie's expiry-time to attribute-value of the last +attribute in the cookie-attribute-list with an attribute-name of +"Max-Age".¶
++Otherwise, if the cookie-attribute-list contains an attribute with an +attribute-name of "Expires" (and does not contain an attribute with an +attribute-name of "Max-Age"):¶
+Set the cookie's persistent-flag to true.¶
+Set the cookie's expiry-time to attribute-value of the last +attribute in the cookie-attribute-list with an attribute-name of +"Expires".¶
++Otherwise:¶
+ +If the cookie-attribute-list contains an attribute with an +attribute-name of "Domain":¶
+Let the domain-attribute be the attribute-value of the last +attribute in the cookie-attribute-list with both an +attribute-name of "Domain" and an attribute-value whose +length is no more than 1024 octets. (Note that a leading %x2E +("."), if present, is ignored even though that character is not +permitted.)¶
++Otherwise:¶
+Let the domain-attribute be the empty string.¶
+If the domain-attribute contains a character that is not in the range of [USASCII] +characters, abort these steps and ignore the cookie entirely.¶
+If the user agent is configured to reject "public suffixes" and the +domain-attribute is a public suffix:¶
+If the domain-attribute is identical to the canonicalized +request-host:¶
+Let the domain-attribute be the empty string.¶
++Otherwise:¶
+Abort these steps and ignore the cookie entirely.¶
+
+NOTE: This step prevents attacker.example
from disrupting the integrity of
+site.example
by setting a cookie with a Domain attribute of "example".¶
If the domain-attribute is non-empty:¶
+If the canonicalized request-host does not domain-match the +domain-attribute:¶
+Abort these steps and ignore the cookie entirely.¶
++Otherwise:¶
+ ++Otherwise:¶
+ +If the cookie-attribute-list contains an attribute with an +attribute-name of "Path", set the cookie's path to attribute-value of +the last attribute in the cookie-attribute-list with both an +attribute-name of "Path" and an attribute-value whose length is no +more than 1024 octets. Otherwise, set the cookie's path to the +default-path of the request-uri.¶
+If the cookie-attribute-list contains an attribute with an +attribute-name of "Secure", set the cookie's secure-only-flag to true. +Otherwise, set the cookie's secure-only-flag to false.¶
+If the request-uri does not denote a "secure" connection (as defined by the +user agent), and the cookie's secure-only-flag is true, then abort these +steps and ignore the cookie entirely.¶
+If the cookie-attribute-list contains an attribute with an +attribute-name of "HttpOnly", set the cookie's http-only-flag to true. +Otherwise, set the cookie's http-only-flag to false.¶
+If the cookie was received from a "non-HTTP" API and the cookie's +http-only-flag is true, abort these steps and ignore the cookie entirely.¶
+If the cookie's secure-only-flag is false, and the request-uri does not +denote a "secure" connection, then abort these steps and ignore the cookie +entirely if the cookie store contains one or more cookies that meet all of +the following criteria:¶
+Their name matches the name of the newly-created cookie.¶
+Their secure-only-flag is true.¶
+Their domain domain-matches the domain of the newly-created cookie, or +vice-versa.¶
+The path of the newly-created cookie path-matches the path of the +existing cookie.¶
++Note: The path comparison is not symmetric, ensuring only that a +newly-created, non-secure cookie does not overlay an existing secure +cookie, providing some mitigation against cookie-fixing attacks. That is, +given an existing secure cookie named 'a' with a path of '/login', a +non-secure cookie named 'a' could be set for a path of '/' or '/foo', but +not for a path of '/login' or '/login/en'.¶
+If the cookie-attribute-list contains an attribute with an +attribute-name of "SameSite", and an attribute-value of "Strict", "Lax", or +"None", set the cookie's same-site-flag to the attribute-value of the last +attribute in the cookie-attribute-list with an attribute-name of "SameSite". +Otherwise, set the cookie's same-site-flag to "Default".¶
+If the cookie's same-site-flag
is not "None":¶
If the cookie was received from a "non-HTTP" API, and the API was called +from a navigable's active document whose "site for cookies" is +not same-site with the top-level origin, then abort these steps and +ignore the newly created cookie entirely.¶
+If the cookie was received from a "same-site" request (as defined in +Section 5.2), skip the remaining substeps and continue +processing the cookie.¶
+If the cookie was received from a request which is navigating a
+top-level traversable [HTML] (e.g. if the request's "reserved
+client" is either null
or an environment whose "target browsing
+context"'s navigable is a top-level traversable), skip the remaining
+substeps and continue processing the cookie.¶
+Note: Top-level navigations can create a cookie with any SameSite
+value, even if the new cookie wouldn't have been sent along with
+the request had it already existed prior to the navigation.¶
Abort these steps and ignore the newly created cookie entirely.¶
+If the cookie's "same-site-flag" is "None", abort these steps and ignore the +cookie entirely unless the cookie's secure-only-flag is true.¶
+If the cookie-name begins with a case-insensitive match for the string +"__Secure-", abort these steps and ignore the cookie entirely unless the +cookie's secure-only-flag is true.¶
+If the cookie-name begins with a case-insensitive match for the string +"__Host-", abort these steps and ignore the cookie entirely unless the +cookie meets all the following criteria:¶
+ +If the cookie-name is empty and either of the following conditions are +true, abort these steps and ignore the cookie entirely:¶
+ +If the cookie store contains a cookie with the same name, domain, +host-only-flag, and path as the newly-created cookie:¶
+Let old-cookie be the existing cookie with the same name, domain, +host-only-flag, and path as the newly-created cookie. (Notice that this +algorithm maintains the invariant that there is at most one such +cookie.)¶
+If the newly-created cookie was received from a "non-HTTP" API and the +old-cookie's http-only-flag is true, abort these steps and ignore the +newly created cookie entirely.¶
+Update the creation-time of the newly-created cookie to match the +creation-time of the old-cookie.¶
+Remove the old-cookie from the cookie store.¶
+Insert the newly-created cookie into the cookie store.¶
+A cookie is "expired" if the cookie has an expiry date in the past.¶
+The user agent MUST evict all expired cookies from the cookie store if, at any +time, an expired cookie exists in the cookie store.¶
+At any time, the user agent MAY "remove excess cookies" from the cookie store +if the number of cookies sharing a domain field exceeds some +implementation-defined upper bound (such as 50 cookies).¶
+At any time, the user agent MAY "remove excess cookies" from the cookie store +if the cookie store exceeds some predetermined upper bound (such as 3000 +cookies).¶
+When the user agent removes excess cookies from the cookie store, the user +agent MUST evict cookies in the following priority order:¶
+Expired cookies.¶
+Cookies whose secure-only-flag is false, and which share a domain field +with more than a predetermined number of other cookies.¶
+Cookies that share a domain field with more than a predetermined number of +other cookies.¶
+All cookies.¶
+If two cookies have the same removal priority, the user agent MUST evict the +cookie with the earliest last-access-time first.¶
+When "the current session is over" (as defined by the user agent), the user +agent MUST remove from the cookie store all cookies with the persistent-flag +set to false.¶
+This section defines how cookies are retrieved from a cookie store in the form +of a cookie-string. A "retrieval" is any event which requires generating a +cookie-string. For example, a retrieval may occur in order to build a Cookie +header field for an HTTP request, or may be required in order to return a +cookie-string from a call to a "non-HTTP" API that provides access to cookies. A +retrieval has an associated URI, same-site status, and type, which +are defined below depending on the type of retrieval.¶
+ +The user agent MAY implement "non-HTTP" APIs that can be used to access +stored cookies.¶
+A user agent MAY return an empty cookie-string in certain contexts, such as +when a retrieval occurs within a third-party context (see +Section 7.1).¶
+If a user agent does return cookies for a given call to a "non-HTTP" API with +an associated Document, then the user agent MUST compute the cookie-string +following the algorithm defined in Section 5.8.3, where the +retrieval's URI is defined by the caller (see [DOM-DOCUMENT-COOKIE]), the +retrieval's same-site status is "same-site" if the Document's "site for +cookies" is same-site with the top-level origin as defined in +Section 5.2.1 (otherwise it is "cross-site"), and the retrieval's type +is "non-HTTP".¶
+Given a cookie store and a retrieval, the following algorithm returns a +cookie-string from a given cookie store.¶
+Let cookie-list be the set of cookies from the cookie store that meets all +of the following requirements:¶
+Either:¶
+The cookie's host-only-flag is true and the canonicalized +host of the retrieval's URI is identical to the cookie's domain.¶
++Or:¶
+The cookie's host-only-flag is false and the canonicalized +host of the retrieval's URI domain-matches the cookie's domain.¶
++NOTE: (For user agents configured to reject "public suffixes") It's +possible that the public suffix list was changed since a cookie was +created. If this change results in a cookie's domain becoming a public +suffix then that cookie is considered invalid as it would have been +rejected during creation (See Section 5.7 step 9). User agents +should be careful to avoid retrieving these invalid cookies even if they +domain-match the host of the retrieval's URI.¶
+The retrieval's URI's path path-matches the cookie's path.¶
+If the cookie's secure-only-flag is true, then the retrieval's URI must +denote a "secure" connection (as defined by the user agent).¶
++NOTE: The notion of a "secure" connection is not defined by this document. +Typically, user agents consider a connection secure if the connection makes +use of transport-layer security, such as SSL or TLS, or if the host is +trusted. For example, most user agents consider "https" to be a scheme that +denotes a secure protocol and "localhost" to be trusted host.¶
+If the cookie's http-only-flag is true, then exclude the cookie if the +retrieval's type is "non-HTTP".¶
+If the cookie's same-site-flag is not "None" and the retrieval's same-site +status is "cross-site", then exclude the cookie unless all of the +following conditions are met:¶
+The retrieval's type is "HTTP".¶
+The same-site-flag is "Lax" or "Default".¶
+The HTTP request associated with the retrieval uses a "safe" method.¶
+The target browsing context of the HTTP request associated with the +retrieval is the active browsing context or a top-level traversable.¶
+The user agent SHOULD sort the cookie-list in the following order:¶
+Cookies with longer paths are listed before cookies with shorter +paths.¶
+Among cookies that have equal-length path fields, cookies with earlier +creation-times are listed before cookies with later creation-times.¶
++NOTE: Not all user agents sort the cookie-list in this order, but this order +reflects common practice when this document was written, and, historically, +there have been servers that (erroneously) depended on this order.¶
+Update the last-access-time of each cookie in the cookie-list to the +current date and time.¶
+Serialize the cookie-list into a cookie-string by processing each cookie +in the cookie-list in order:¶
+ +Practical user agent implementations have limits on the number and size of +cookies that they can store. General-use user agents SHOULD provide each of the +following minimum capabilities:¶
+ +User agents MAY limit the maximum number of cookies they store, and may evict +any cookie at any time (whether at the request of the user or due to +implementation limitations).¶
+Note that a limit on the maximum number of cookies also limits the total size of +the stored cookies, due to the length limits which MUST be enforced in +Section 5.6.¶
+Servers SHOULD use as few and as small cookies as possible to avoid reaching +these implementation limits, minimize network bandwidth due to the +Cookie header field being included in every request, and to avoid reaching +server header field limits (See Section 4.2.1).¶
+Servers SHOULD gracefully degrade if the user agent fails to return one or more +cookies in the Cookie header field because the user agent might evict any cookie +at any time.¶
+One reason the Cookie and Set-Cookie header fields use such esoteric syntax is +that many platforms (both in servers and user agents) provide a string-based +application programming interface (API) to cookies, requiring +application-layer programmers to generate and parse the syntax used by the +Cookie and Set-Cookie header fields, which many programmers have done incorrectly, +resulting in interoperability problems.¶
+Instead of providing string-based APIs to cookies, platforms would be +well-served by providing more semantic APIs. It is beyond the scope of this +document to recommend specific API designs, but there are clear benefits to +accepting an abstract "Date" object instead of a serialized date string.¶
+Cookies' primary privacy risk is their ability to correlate user activity. This +can happen on a single site, but is most problematic when activity is tracked across different, +seemingly unconnected Web sites to build a user profile.¶
+Over time, this capability (warned against explicitly in [RFC2109] and all of its successors) +has become widely used for varied reasons including:¶
+authenticating users across sites,¶
+assembling information on users,¶
+protecting against fraud and other forms of undesirable traffic,¶
+targeting advertisements at specific users or at users with specified attributes,¶
+measuring how often ads are shown to users, and¶
+recognizing when an ad resulted in a change in user behavior.¶
+While not every use of cookies is necessarily problematic for privacy, their potential for abuse +has become a widespread concern in the Internet community and broader society. In response to these concerns, user agents +have actively constrained cookie functionality in various ways (as allowed and encouraged by +previous specifications), while avoiding disruption to features they judge desirable for the health +of the Web.¶
+It is too early to declare consensus on which specific mechanism(s) should be used to mitigate cookies' privacy impact; user agents' ongoing changes to how they are handled are best characterised as experiments that +can provide input into that eventual consensus.¶
+Instead, this document describes limited, general mitigations against the privacy risks associated +with cookies that enjoy wide deployment at the time of writing. It is expected that implementations +will continue to experiment and impose stricter, more well-defined limitations on cookies over +time. Future versions of this document might codify those mechanisms based upon deployment +experience. If functions that currently rely on cookies can be supported by separate, targeted +mechanisms, they might be documented in separate specifications and stricter limitations on cookies +might become feasible.¶
+Note that cookies are not the only mechanism that can be used to track users across sites, so while +these mitigations are necessary to improve Web privacy, they are not sufficient on their own.¶
+ + +User agents SHOULD provide users with a mechanism for managing the cookies +stored in the cookie store. For example, a user agent might let users delete +all cookies received during a specified time period or all the cookies related +to a particular domain. In addition, many user agents include a user interface +element that lets users examine the cookies stored in their cookie store.¶
+User agents SHOULD provide users with a mechanism for disabling cookies. When +cookies are disabled, the user agent MUST NOT include a Cookie header field in +outbound HTTP requests and the user agent MUST NOT process Set-Cookie header fields +in inbound HTTP responses.¶
+User agents MAY offer a way to change the cookie policy (see +Section 7.2).¶
+User agents MAY provide users the option of preventing persistent storage of +cookies across sessions. When configured thusly, user agents MUST treat all +received cookies as if the persistent-flag were set to false. Some popular +user agents expose this functionality via "private browsing" mode +[Aggarwal2010].¶
+Although servers can set the expiration date for cookies to the distant future, +most user agents do not actually retain cookies for multiple decades. Rather +than choosing gratuitously long expiration periods, servers SHOULD promote user +privacy by selecting reasonable cookie expiration periods based on the purpose +of the cookie. For example, a typical session identifier might reasonably be +set to expire in two weeks.¶
+Cookies have a number of security pitfalls. This section overviews a few of the +more salient issues.¶
+In particular, cookies encourage developers to rely on ambient authority for +authentication, often becoming vulnerable to attacks such as cross-site request +forgery [CSRF]. Also, when storing session identifiers in cookies, developers +often create session fixation vulnerabilities.¶
+Transport-layer encryption, such as that employed in HTTPS, is insufficient to +prevent a network attacker from obtaining or altering a victim's cookies because +the cookie protocol itself has various vulnerabilities (see "Weak Confidentiality" +and "Weak Integrity", below). In addition, by default, cookies do not provide +confidentiality or integrity from network attackers, even when used in conjunction +with HTTPS.¶
+Unless sent over a secure channel (such as TLS), the information in the Cookie +and Set-Cookie header fields is transmitted in the clear.¶
+All sensitive information conveyed in these header fields is exposed to an +eavesdropper.¶
+A malicious intermediary could alter the header fields as they travel in either +direction, with unpredictable results.¶
+A malicious client could alter the Cookie header fields before transmission, +with unpredictable results.¶
+Servers SHOULD encrypt and sign the contents of cookies (using whatever format +the server desires) when transmitting them to the user agent (even when sending +the cookies over a secure channel). However, encrypting and signing cookie +contents does not prevent an attacker from transplanting a cookie from one user +agent to another or from replaying the cookie at a later time.¶
+In addition to encrypting and signing the contents of every cookie, servers that +require a higher level of security SHOULD use the Cookie and Set-Cookie +header fields only over a secure channel. When using cookies over a secure channel, +servers SHOULD set the Secure attribute (see Section 4.1.2.5) for every +cookie. If a server does not set the Secure attribute, the protection +provided by the secure channel will be largely moot.¶
+For example, consider a webmail server that stores a session identifier in a +cookie and is typically accessed over HTTPS. If the server does not set the +Secure attribute on its cookies, an active network attacker can intercept any +outbound HTTP request from the user agent and redirect that request to the +webmail server over HTTP. Even if the webmail server is not listening for HTTP +connections, the user agent will still include cookies in the request. The +active network attacker can intercept these cookies, replay them against the +server, and learn the contents of the user's email. If, instead, the server had +set the Secure attribute on its cookies, the user agent would not have +included the cookies in the clear-text request.¶
+Instead of storing session information directly in a cookie (where it might be +exposed to or replayed by an attacker), servers commonly store a nonce (or +"session identifier") in a cookie. When the server receives an HTTP request +with a nonce, the server can look up state information associated with the +cookie using the nonce as a key.¶
+Using session identifier cookies limits the damage an attacker can cause if the +attacker learns the contents of a cookie because the nonce is useful only for +interacting with the server (unlike non-nonce cookie content, which might itself +be sensitive). Furthermore, using a single nonce prevents an attacker from +"splicing" together cookie content from two interactions with the server, which +could cause the server to behave unexpectedly.¶
+Using session identifiers is not without risk. For example, the server SHOULD +take care to avoid "session fixation" vulnerabilities. A session fixation attack +proceeds in three steps. First, the attacker transplants a session identifier +from his or her user agent to the victim's user agent. Second, the victim uses +that session identifier to interact with the server, possibly imbuing the +session identifier with the user's credentials or confidential information. +Third, the attacker uses the session identifier to interact with server +directly, possibly obtaining the user's authority or confidential information.¶
+Cookies do not provide isolation by port. If a cookie is readable by a service +running on one port, the cookie is also readable by a service running on another +port of the same server. If a cookie is writable by a service on one port, the +cookie is also writable by a service running on another port of the same server. +For this reason, servers SHOULD NOT both run mutually distrusting services on +different ports of the same host and use cookies to store security-sensitive +information.¶
+Cookies do not provide isolation by scheme. Although most commonly used with +the http and https schemes, the cookies for a given host might also be +available to other schemes, such as ftp and gopher. Although this lack of +isolation by scheme is most apparent in non-HTTP APIs that permit access to +cookies (e.g., HTML's document.cookie API), the lack of isolation by scheme +is actually present in requirements for processing cookies themselves (e.g., +consider retrieving a URI with the gopher scheme via HTTP).¶
+Cookies do not always provide isolation by path. Although the network-level +protocol does not send cookies stored for one path to another, some user +agents expose cookies via non-HTTP APIs, such as HTML's document.cookie API. +Because some of these user agents (e.g., web browsers) do not isolate resources +received from different paths, a resource retrieved from one path might be able +to access cookies stored for another path.¶
+Cookies do not provide integrity guarantees for sibling domains (and their +subdomains). For example, consider foo.site.example and bar.site.example. The +foo.site.example server can set a cookie with a Domain attribute of +"site.example" (possibly overwriting an existing "site.example" cookie set by +bar.site.example), and the user agent will include that cookie in HTTP requests +to bar.site.example. In the worst case, bar.site.example will be unable to +distinguish this cookie from a cookie it set itself. The foo.site.example +server might be able to leverage this ability to mount an attack against +bar.site.example.¶
+Even though the Set-Cookie header field supports the Path attribute, the Path +attribute does not provide any integrity protection because the user agent +will accept an arbitrary Path attribute in a Set-Cookie header field. For +example, an HTTP response to a request for http://site.example/foo/bar can set +a cookie with a Path attribute of "/qux". Consequently, servers SHOULD NOT +both run mutually distrusting services on different paths of the same host and +use cookies to store security-sensitive information.¶
+An active network attacker can also inject cookies into the Cookie header field +sent to https://site.example/ by impersonating a response from +http://site.example/ and injecting a Set-Cookie header field. The HTTPS server +at site.example will be unable to distinguish these cookies from cookies that +it set itself in an HTTPS response. An active network attacker might be able +to leverage this ability to mount an attack against site.example even if +site.example uses HTTPS exclusively.¶
+Servers can partially mitigate these attacks by encrypting and signing the
+contents of their cookies, or by naming the cookie with the __Secure-
prefix.
+However, using cryptography does not mitigate the issue completely because an
+attacker can replay a cookie he or she received from the authentic site.example
+server in the user's session, with unpredictable results.¶
Finally, an attacker might be able to force the user agent to delete cookies by +storing a large number of cookies. Once the user agent reaches its storage +limit, the user agent will be forced to evict some cookies. Servers SHOULD NOT +rely upon user agents retaining cookies.¶
+Cookies rely upon the Domain Name System (DNS) for security. If the DNS is +partially or fully compromised, the cookie protocol might fail to provide the +security properties required by applications.¶
+Adds the same-site concept and the SameSite attribute. +(Section 5.2 and Section 4.1.2.7)¶
+Introduces cookie prefixes and prohibits nameless cookies from setting a +value that would mimic a cookie prefix. (Section 4.1.3 and +Section 5.7)¶
+Prohibits non-secure origins from setting cookies with a Secure
flag or
+overwriting cookies with this flag. (Section 5.7)¶
Limits maximum cookie size. (Section 5.7)¶
+Limits maximum values for max-age and expire. (Section 5.6.1 and Section 5.6.2)¶
+Includes the host-only-flag as part of a cookie's uniqueness computation. +(Section 5.7)¶
+Considers potentially trustworthy origins as "secure". (Section 5.7)¶
+Improves cookie syntax¶
+Treats Set-Cookie: token as creating the cookie ("", "token"). +(Section 5.6)¶
+Rejects cookies without a name nor value. (Section 5.7)¶
+Specifies how to serialize a nameless/valueless cookie. (Section 5.8.3)¶
+Adjusts ABNF for cookie-pair and the Cookie header production to allow +for spaces. (Section 4.1.1)¶
+Explicitly handle control characters. (Section 5.6 and Section 5.7)¶
+Specifies how to handle empty domain attributes. (Section 5.7)¶
+Requires ASCII characters for the domain attribute. (Section 5.7)¶
+Refactors cookie retrieval algorithm to support non-HTTP APIs. (Section 5.8.2)¶
+Specifies that the Set-Cookie line should not be decoded. (Section 5.6)¶
+Adds an advisory section to assist implementers in deciding which requirements +to implement. (Section 3.2)¶
+Advises against sending invalid cookies due to public suffix list changes. +(Section 5.8.3)¶
+Removes the single cookie header requirement. (Section 5.8.1)¶
+Address errata 3444 by updating the path-value andextension-av grammar, +errata 4148 by updating the day-of-month, year, and time grammar, and errata +3663 by adding the requested note. (Section 4.1 and Section 5.1.4)¶
+RFC 6265 was written by Adam Barth. This document is an update of RFC 6265, +adding features and aligning the specification with the reality of today's +deployments. Here, we're standing upon the shoulders of a giant since the +majority of the text is still Adam's.¶
+Thank you to both Lily Chen and Steven Englehardt, editors emeritus, for their +significant contributions improving this draft.¶
+Internet-Draft | +The HTTP QUERY Method | +January 2025 | +
Reschke, et al. | +Expires 11 July 2025 | +[Page] | +
+ This specification defines a new HTTP method, QUERY, as a safe, idempotent + request method that can carry request content.¶
+This note is to be removed before publishing as an RFC.¶
++ Discussion of this draft takes place on the HTTP working group + mailing list (ietf-http-wg@w3.org), which is archived at + https://lists.w3.org/Archives/Public/ietf-http-wg/.¶
++ Working Group information can be found at https://httpwg.org/; + source code and issues list for this draft can be found at + https://github.com/httpwg/http-extensions/labels/query-method.¶
++ The changes in this draft are summarized in Appendix B.8.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
++ This specification defines the HTTP QUERY request method as a means of + making a safe, idempotent request that contains content.¶
++ Most often, this is desirable when the data conveyed in a request is + too voluminous to be encoded into the request's URI. For example, + this is a common query pattern:¶
+ ++ However, for a query with parameters that are complex or large in size, + encoding it in the request URI may not be the best option because¶
++ As an alternative to using GET, many implementations make use of the + HTTP POST method to perform queries, as illustrated in the example + below. In this case, the input parameters to the query operation are + passed along within the request content as opposed to using the + request URI.¶
++ A typical use of HTTP POST for requesting a query:¶
+ ++ This variation, however, suffers from the same basic limitation as GET + in that it is not readily apparent -- absent specific knowledge of the + resource and server to which the request is being sent -- that a safe, + idempotent query is being performed.¶
++ The QUERY method provides a solution that spans the gap between the use of GET and POST, with + the example above being expressed as:¶
+ ++ As with POST, the input to the query operation is passed along within the content of the request + rather than as part of the request URI. Unlike POST, however, the method is explicitly safe + and idempotent, allowing functions like caching and automatic retries to operate.¶
+Summarizing:¶
++ | GET | +QUERY | +POST | +
---|---|---|---|
Safe | +yes | +yes | +potentially no | +
Idempotent | +yes | +yes | +potentially no | +
Cacheable | +yes | +yes | +no | +
Content (body) | +"no defined semantics" | +expected (semantics per target resource) | +expected (semantics per target resource) | +
+ This document uses terminology defined in Section 3 of [HTTP].¶
++ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL + NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", + "MAY", and "OPTIONAL" in this document are to be interpreted as + described in BCP 14 [RFC2119] [RFC8174] when, and only when, they + appear in all capitals, as shown here.¶
++ The QUERY method is used to initiate a server-side query. Unlike + the HTTP GET method, which requests that a server return a + representation of the resource identified by the target URI + (as defined by Section 7.1 of [HTTP]), the QUERY + method is used to ask the server to perform a query operation + (described by the request content) over some set of data scoped to the + target URI. The content returned in response to a QUERY + cannot be assumed to be a representation of the resource identified by + the target URI.¶
++ The content of the request defines the query. Implementations MAY use + a request content of any media type with the QUERY method, provided that it + has appropriate query semantics.¶
++ QUERY requests are both safe and idempotent with regards to the + resource identified by the request URI. That is, QUERY requests do not + alter the state of the targeted resource. However, while processing a + QUERY request, a server can be expected to allocate computing and memory + resources or even create additional HTTP resources through which the + response can be retrieved.¶
++ A successful response to a QUERY request is expected to provide some + indication as to the final disposition of the operation. For + instance, a successful query that yields no results can be represented + by a 204 No Content response. If the response includes content, + it is expected to describe the results of the operation.¶
++ Furthermore, a successful response can include a Content-Location + header field (see Section 8.7 of [HTTP]) containing an + identifier for a resource corresponding to the results of the + operation. This represents a claim from the server that a client can send + a GET request for the indicated URI to retrieve the results of the query + operation just performed. The indicated resource might be temporary.¶
++ A server MAY create or locate a resource that identifies the query + operation for future use. If the server does so, the URI of the resource + can be included in the Location header field of the response (see Section 10.2.2 of [HTTP]). This represents a claim that a client can + send a GET request to the indicated URI to repeat the query operation just + performed without resending the query parameters. This resource might be + temporary; if a future request fails, the client can retry using the + original QUERY resource and the previously submitted parameters again.¶
++ In some cases, the server may choose to respond indirectly to the QUERY + request by redirecting the user agent to a different URI (see + Section 15.4 of [HTTP]). The semantics of the redirect + response do not differ from other methods. For instance, a 303 (See Other) + response would indicate that the Location field identifies an + alternate URI from which the results can be retrieved + using a GET request (this use case is also covered by the + use of the Location response field in a 2xx response). + On the other hand, response codes 307 (Temporary Redirect) and 308 + (Permanent Redirect) can be used to request the user agent to redo + the QUERY request on the URI specified by the Location field. + Various non-normative examples of successful + QUERY responses are illustrated in Appendix A.¶
++ A conditional QUERY requests that the selected representation + (i.e., the query results, after any content negotiation) be + returned in the response only under the circumstances described by the + conditional header field(s), as defined in + Section 13 of [HTTP].¶
++ The response to a QUERY method is cacheable; a cache MAY use it to satisfy subsequent + QUERY requests as per Section 4 of [HTTP-CACHING]).¶
++ The cache key for a query (see Section 2 of [HTTP-CACHING]) MUST + incorporate the request content. When doing so, caches SHOULD first normalize request + content to remove semantically insignificant differences, thereby improving cache + efficiency, by:¶
++ Note that any such normalization is performed solely for the purpose of generating a cache key; it + does not change the request itself.¶
++ The "Accept-Query" response header field can be used by a resource to + directly signal support for the QUERY method while identifying + the specific query format media type(s) that may be used.¶
++ "Accept-Query" contains a list of media ranges (Section 12.5.1 of [HTTP]) + using "Structured Fields" syntax ([STRUCTURED-FIELDS]). + Media ranges are represented by a List Structured Header Field of either Tokens or + Strings, containing the media range value without parameters. Parameters, + if any, are mapped to Parameters of type String.¶
++ The choice of Token vs. String is semantically insignificant. That is, + recipients MAY convert Tokens to Strings, but MUST NOT process them + differently based on the received type.¶
++ Media types do not exactly map to Tokens, for instance they + allow a leading digit. In cases like these, the String format needs to + be used.¶
++ The only supported uses of wildcards are "*/*", which matches any type, + or "xxxx/*", which matches any subtype of the indicated type.¶
++ The order of types listed in the field value is not significant.¶
++ The only allowed format for parameters is String.¶
++ Accept-Query's value applies to every URI on the server that shares the same path; in + other words, the query component is ignored. If requests to the same resource return + different Accept-Query values, the most recently received fresh value (per + Section 4.2 of [HTTP-CACHING]) is used.¶
++ Example:¶
++Accept-Query: "application/jsonpath", application/sql;charset="UTF-8"¶ +
+ Although the syntax for this field appears to be similar to other + fields, such as "Accept" (Section 12.5.1 of [HTTP]), + it is a Structured Field and thus MUST be processed as specified in + Section 4 of [STRUCTURED-FIELDS].¶
++ The QUERY method is subject to the same general security + considerations as all HTTP methods as described in + [HTTP].¶
++ It can be used as an alternative to passing request + information in the URI (e.g., in the query section). This is preferred in some + cases, as the URI is more likely to be logged or otherwise processed + by intermediaries than the request content. + If a server creates a temporary resource to represent the results of a QUERY + request (e.g., for use in the Location or Content-Location field) and the request + contains sensitive information that cannot be logged, then the URI of this + resource SHOULD be chosen such that it does not include any sensitive + portions of the original request content.¶
++ Caches that normalize QUERY content incorrectly or in ways that are + significantly different than how the resource processes the content + can return the incorrect response if normalization results in a false positive.¶
++ A QUERY request from user agents implementing CORS (Cross-Origin Resource Sharing) + will require a "preflight" request, + as QUERY does not belong to the set of CORS-safelisted methods + (see "Methods" in + [FETCH]).¶
++ IANA is requested to add the QUERY method to the HTTP + Method Registry at <http://www.iana.org/assignments/http-methods> + (see Section 16.3.1 of [HTTP]).¶
+Method Name | +Safe | +Idempotent | +Specification | +
---|---|---|---|
QUERY | +Yes | +Yes | ++ Section 2 + | +
+ IANA is requested to add the Accept-Query field to the HTTP Field Name + Registry at <https://www.iana.org/assignments/http-fields> + (see Section 16.1.1 of [HTTP]).¶
+Field Name | +Status | +Structured Type | +Reference | +Comments | +
---|---|---|---|---|
Accept-Query | +permanent | +List | ++ Section 3 of this document. | ++ |
+ The non-normative examples in this section make use of a simple, + hypothetical plain-text based query syntax based on SQL with results + returned as comma-separated values. This is done for illustration + purposes only. Implementations are free to use any format they wish on + both the request and response.¶
+A simple query with a direct response:¶
+ +Response:¶
+ +A simple query with a direct response:¶
+ +Response:¶
+ ++ A subsequent GET request on /contacts/responses/42 would return + the same response, until the server decides to remove that + resource.¶
++ A GET request on /contacts/queries/17 however would execute the same + query again, and return a fresh result for that query:¶
+ +Response:¶
+ +A simple query with an Indirect Response (303 See Other):¶
+ +Response:¶
+ +Retrieval of the Query Response:¶
+ +Response:¶
+ +A simple query being redirected:¶
+ +Response:¶
+ +Redirected request:¶
+ +Response:¶
+ +This section is to be removed before publishing as an RFC.¶
+None yet.¶
+Internet-Draft | +HTTP Server Secondary Cert Auth | +January 2025 | +
Gorbaty & Bishop | +Expires 11 July 2025 | +[Page] | +
This document defines a way for HTTP/2 and HTTP/3 servers to send additional +certificate-based credentials after a TLS connection is established, based +on TLS Exported Authenticators.¶
+This note is to be removed before publishing as an RFC.¶
++ The latest revision of this draft can be found at https://httpwg.org/http-extensions/draft-ietf-httpbis-secondary-server-certs.html. + Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-secondary-server-certs/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/secondary-server-certs.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+HTTP [HTTP] clients need to know that the content they receive on a +connection comes from the origin from which they intended to retrieve it. The +traditional form of server authentication in HTTP has been in the form of a +single X.509 certificate provided during the TLS [TLS13] handshake.¶
+TLS supports one server and one client certificate on a connection. These +certificates may contain multiple identities, but only one certificate may be +provided.¶
+Many HTTP servers host content from several origins. HTTP/2 [H2] and +HTTP/3 [H3] permit clients to reuse an existing HTTP connection to a +server provided that the secondary origin is also in the certificate provided +during the TLS handshake. In many cases, servers choose to maintain separate +certificates for different origins but still desire the benefits of a shared +HTTP connection. This document defines a capability for servers to use and +to authenticate with those seperate certificates over a shared connection.¶
+The ability to maintain seperate certificates for different origins can also +allow proxies that cache content from secondary origins to communicate to +clients that they can service some of those origins directly, allowing the +proxy to behave as a TLS-terminating reverse proxy for those origins instead of +establishing a TLS encrypted tunnel through the proxy.¶
+Section 9.1.1 of [H2] and Section 3.3 of [H3] describe how connections may +be used to make requests from multiple origins as long as the server is +authoritative for both. A server is considered authoritative for an origin if +DNS resolves the origin to the IP address of the server and (for TLS) if the +certificate presented by the server contains the origin in the Subject +Alternative Names field.¶
+[ALTSVC] enables a step of abstraction from the DNS resolution. If +both hosts have provided an Alternative Service at hostnames which resolve to +the IP address of the server, they are considered authoritative just as if DNS +resolved the origin itself to that address. However, the server's one TLS +certificate is still required to contain the name of each origin in question.¶
+[ORIGIN] relaxes the requirement to perform the DNS lookup if already +connected to a server with an appropriate certificate which claims support for +a particular origin.¶
+Servers which host many origins often would prefer to have separate certificates +for some sets of origins. This may be for ease of certificate management +(the ability to separately revoke or renew them), due to different sources of +certificates (a CDN acting on behalf of multiple origins), or other factors +which might drive this administrative decision. Clients connecting to such +origins cannot currently reuse connections, even if both client and server +would prefer to do so.¶
+Because the TLS SNI extension is exchanged in the clear, clients might also +prefer to retrieve certificates inside the encrypted context. When this +information is sensitive, it might be advantageous to request a general-purpose +certificate or anonymous ciphersuite at the TLS layer, while acquiring the +"real" certificate in HTTP after the connection is established.¶
+TLS Exported Authenticators [EXPORTED-AUTH] are structured messages +that can be exported by either party of a TLS connection and validated by the +other party. Given an established TLS connection, an authenticator message can +be constructed proving possession of a certificate and a corresponding private +key. The mechanisms that this document defines are primarily focused on the +server's ability to generate TLS Exported Authenticators.¶
+Each Authenticator is computed using a Handshake Context and Finished MAC Key +derived from the TLS session. The Handshake Context is identical for both +parties of the TLS connection, while the Finished MAC Key is dependent on +whether the Authenticator is created by the client or the server.¶
+Successfully verified Authenticators result in certificate chains, with verified +possession of the corresponding private key, which can be supplied into a +collection of available certificates. Likewise, descriptions of desired +certificates can also be supplied into these collections.¶
+This document defines HTTP/2 and HTTP/3 CERTIFICATE
frames (Section 5) to
+carry the relevant certificate messages, enabling certificate-based
+authentication of servers independent of TLS version. This mechanism can be
+implemented at the HTTP layer without breaking the existing interface between
+HTTP and applications above it.¶
TLS Exported Authenticators [EXPORTED-AUTH] allow the opportunity for an +HTTP/2 and HTTP/3 servers to send certificate frames which can be used to prove +the servers authenticity for multiple origins.¶
+This document additionally defines SETTINGS parameters for HTTP/2 and HTTP/3 +(Section 4) that allow the client and server to indicate support for +HTTP-Layer certificate authentication.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+A certificate chain with proof of possession of the private key corresponding to
+the end-entity certificate is sent as a sequence of CERTIFICATE
frames (see
+Section 5.1, Section 5.2) to the client. Once the holder of a certificate
+has sent the chain and proof, this certificate chain is cached by the recipient
+and available for future use.¶
The SETTINGS_HTTP_SERVER_CERT_AUTH
parameters for HTTP/2 and HTTP/3 are
+defined in Section 4 so that clients and servers can indicate support for
+secondary certificate authentication of servers.¶
HTTP/2 and HTTP/3 endpoints who wish to indicate support for HTTP-Layer
+certificate authentication MUST send a SETTINGS_HTTP_SERVER_CERT_AUTH
+parameter set to "1" in their SETTINGS frame. Endpoints MUST NOT use any of the
+authentication functionality described in this document unless the parameter has
+been negotiated by both sides.¶
Endpoints MUST NOT send a SETTINGS_HTTP_SERVER_CERT_AUTH
parameter with a
+value of 0 after previously sending a value of 1.¶
SETTINGS_HTTP_SERVER_CERT_AUTH
indicates that servers are able to offer
+additional certificates to demonstrate control over other origin hostnames, and
+that clients are able to make requests for hostnames received in a TLS Exported
+Authenticator that the server sends.¶
When both peers have advertised support for HTTP-layer certificates in a given
+direction as in Section 3.1, the indicated endpoint can supply
+additional certificates into the connection at any time. That is, if both
+endpoints have sent SETTINGS_HTTP_SERVER_CERT_AUTH
and validated the value
+received from the peer, the server may send certificates spontaneously, at any
+time, as described by the Spontaneous Server Authentication
message sequence
+in Section 3 of [EXPORTED-AUTH].¶
This does mean that if a server knows it supports secondary certificate
+authentication, and it receives SETTINGS_HTTP_SERVER_CERT_AUTH
from the
+client, that it can enqueue certificates immediately following the received
+SETTINGS frame.¶
Certificates supplied by servers can be considered by clients without further
+action by the server. A server SHOULD NOT send certificates which do not cover
+origins which it is prepared to service on the current connection, and SHOULD NOT send them if the client has not indicated support with
+SETTINGS_HTTP_SERVER_CERT_AUTH
.¶
A client MUST NOT send certificates to the server. The server SHOULD close the +connection upon receipt of a CERTIFICATE frame from a client.¶
+A server MAY send a CERTIFICATE
immediately after sending its SETTINGS
.
+However, it MAY also send certificates at any time later. For example, a proxy
+might discover that a client is interested in an origin that it can reverse
+proxy at the time that a client sends a CONNECT
request. It can then send
+certificates for those origins to allow for TLS-terminated reverse proxying to
+those origins for the remainder of the connection lifetime.
+Figure 2 illustrates this behavior.¶
SETTINGS parameters for HTTP/2 and HTTP/3 seperately are defined below.¶
+This document adds a new HTTP/2 SETTINGS(0xTBD) parameter to those defined by +Section 6.5.2 of [H2].¶
+The new parameter name is SETTINGS_HTTP_SERVER_CERT_AUTH
. The value of the
+parameter MUST be 0 or 1.¶
The usage of this parameter is described in Section 3.1.¶
+This document adds a new HTTP/3 SETTINGS(0xTBD) parameter to those defined by +Section 7.2.4.1 of [H3].¶
+The new parameter name is SETTINGS_HTTP_SERVER_CERT_AUTH
. The value of the
+parameter MUST be 0 or 1.¶
The usage of this parameter is described in Section 3.1.¶
+The CERTIFICATE frame contains an exported authenticator message from the TLS +layer that provides a chain of certificates and associated extensions, proving +possession of the private key corresponding to the end-entity certificate.¶
+A server sends a CERTIFICATE frame on stream 0 for HTTP/2 and on the control +stream for HTTP/3. The client is permitted to make subsequent requests for +resources upon receipt of a CERTIFICATE frame without further action from the +server.¶
+Upon receiving a complete series of CERTIFICATE frames, the receiver may +validate the Exported Authenticator value by using the exported authenticator +API. This returns either an error indicating that the message was invalid or +the certificate chain and extensions used to create the message.¶
+A CERTIFICATE frame in HTTP/2 (type=0xTBD) carrries a TLS Exported authenticator +that clients can use to authenticate secondary origins from a sending server.¶
+The CERTIFICATE frame MUST be sent on stream 0. A CERTIFICATE frame received on +any other stream MUST not be used for server authentication.¶
+ +The Length, Type, Unused Flag(s), Reserved, and Stream Identifier fields are +described in Section 4 of [H2].¶
+The CERTIFICATE frame does not define any flags.¶
+The authenticator field is a portion of the opaque data returned from the TLS +connection exported authenticator authenticate API. See Section 5.3 for more +details on the input to this API.¶
+The CERTIFICATE frame applies to the connection, not a specific stream. An +endpoint MUST treat a CERTIFICATE frame with a stream identifier other than +0x00 as a connection error.¶
+A CERTIFICATE frame in HTTP/3 (type=0xTBD) carrries a TLS Exported authenticator +that clients can use to authenticate secondary origins from a sending server.¶
+The CERTIFICATE frame MUST be sent on the control stream. A CERTIFICATE frame +received on any other stream MUST not be used for server authentication.¶
+ +The Type and Length fields are described in Section 7.1 of [H3].¶
+The authenticator field is a portion of the opaque data returned from the TLS +connection exported authenticator authenticate API. See Section 5.3 for more +details on the input to this API.¶
+The CERTIFICATE frame applies to the connection, not a specific stream. An +endpoint MUST treat a CERTIFICATE frame received on any stream other than the +control stream as a connection error.¶
+The Exported Authenticator API defined in [EXPORTED-AUTH] takes as input a
+request, a set of certificates, and supporting information about the
+certificate (OCSP, SCT, etc.). The result is an opaque token which is used
+when generating the CERTIFICATE
frame.¶
Upon receipt of a CERTIFICATE
frame, an endpoint which has negotiated support
+for secondary certfiicates MUST perform the following steps to validate the
+token it contains:¶
Using the get context
API, retrieve the certificate_request_context
used
+to generate the authenticator, if any. Because the certificate_request_context
+for spontaneous server certificates is chosen by the server, the usage of
+the certificate_request_context
is implementation-dependent. For details,
+see Section 5 of [EXPORTED-AUTH].¶
Use the validate
API to confirm the validity of the authenticator with
+regard to the generated request, if any.¶
If the authenticator cannot be validated, this SHOULD be treated as a connection +error.¶
+Once the authenticator is accepted, the endpoint can perform any other checks +for the acceptability of the certificate itself.¶
+Because this document permits certificates to be exchanged at the HTTP framing +layer instead of the TLS layer, several certificate-related errors which are +defined at the TLS layer might now occur at the HTTP framing layer.¶
+There are two classes of errors which might be encountered, and they are handled +differently.¶
+This category of errors could indicate a peer failing to follow requirements in +this document or might indicate that the connection is not fully secure. These +errors are fatal to stream or connection, as appropriate.¶
+An exported authenticator could not be validated.¶
+Unacceptable certificates (expired, revoked, or insufficient to satisfy the +request) are not treated as stream or connection errors. This is typically not +an indication of a protocol failure. Clients SHOULD establish a new connection +in an attempt to reach an authoritative server if they deem a +certificate from the server unacceptable.¶
+This mechanism defines an alternate way to obtain server and client certificates +other than in the initial TLS handshake. While the signature of exported +authenticator values is expected to be equally secure, it is important to +recognize that a vulnerability in this code path is at least equal to a +vulnerability in the TLS handshake.¶
+This mechanism could increase the impact of a key compromise. Rather than +needing to subvert DNS or IP routing in order to use a compromised certificate, +a malicious server now only needs a client to connect to some HTTPS site +under its control in order to present the compromised certificate. Clients +SHOULD consult DNS for hostnames presented in secondary certificates if they +would have done so for the same hostname if it were present in the primary +certificate.¶
+As recommended in [ORIGIN], clients opting not to consult DNS ought to employ
+some alternative means to increase confidence that the certificate is
+legitimate, such as an ORIGIN
frame.¶
As noted in the Security Considerations of [EXPORTED-AUTH], it is difficult to +formally prove that an endpoint is jointly authoritative over multiple +certificates, rather than individually authoritative on each certificate. As a +result, clients MUST NOT assume that because one origin was previously +colocated with another, those origins will be reachable via the same endpoints +in the future. Clients MUST NOT consider previous secondary certificates to be +validated after TLS session resumption. Servers MAY re-present certificates +if a TLS Session is resumed.¶
+This document defines a mechanism which could be used to probe servers for origins +they support, but it opens no new attack that was not already possible by +making repeat TLS connections with different SNI values.¶
+CNAME records in the DNS are frequently used to delegate authority for an origin +to a third-party provider. This delegation can be changed without notice, even +to the third-party provider, simply by modifying the CNAME record in question.¶
+After the owner of the domain has redirected traffic elsewhere by changing the +CNAME, new connections will not arrive for that origin, but connections which +are properly directed to this provider for other origins would continue to +claim control of this origin (via Secondary Certificates). This is proper +behavior based on the third-party provider's configuration, but would likely +not be what is intended by the owner of the origin.¶
+This is not an issue which can be mitigated by the protocol, but something about +which third-party providers SHOULD educate their customers before using the +features described in this document.¶
+Implementations need to be aware of the potential for confusion about the state
+of a connection. The presence or absence of a validated certificate can change
+during the processing of a request, potentially multiple times, as
+CERTIFICATE
frames are received. A client that uses certificate
+authentication needs to be prepared to reevaluate the authorization state of a
+request as the set of certificates changes.¶
Behavior for TLS-Terminated reverse proxies is also worth considering. If a +server which situationally reverse-proxies wishes for the client to view a +request made prior to receipt of certificates as TLS-Terminated, or wishes for +the client to start a new tunnel alternatively, this document does not currently +define formal mechanisms to facilitate that intention.¶
+This document registers the CERTIFICATE
frame type and
+SETTINGS_HTTP_SERVER_CERT_AUTH
setting for both [H2] and [H3].¶
This specification registers the following entry in the "HTTP/2 Frame Type" +registry defined in [H2]:¶
+Code: : TBD¶
+Frame Type: : CERTIFICATE¶
+Reference: : This document¶
+This specification registers the following entry in the "HTTP/3 Frame Types" +registry established by [H3]:¶
+Value: : TBD¶
+Frame Type: : CERTIFICATE¶
+Status: : permanent¶
+Reference: : This document¶
+Change Controller: : IETF¶
+Contact: : ietf-http-wg@w3.org¶
+This specification registers the following entry in the "HTTP/2 Settings" +registry defined in [H2]:¶
+Code: : TBD¶
+Name: : SETTINGS_HTTP_SERVER_CERT_AUTH¶
+Initial Value: : 0¶
+Reference: : This document¶
+This specification registers the following entry in the "HTTP/3 Settings" +registry defined in [H3]:¶
+Code: : TBD¶
+Name: : SETTINGS_HTTP_SERVER_CERT_AUTH¶
+Default: : 0¶
+Reference: : This document¶
+Change Controller: : IETF¶
+Contact: : ietf-http-wg@w3.org¶
+Thanks to Mike Bishop, Nick Sullivan, Martin Thomson and other +contributors for their work on the document that this is based on.¶
+And thanks to Eric Kinnear, Tommy Pauly, and Lucas Pardue for their guidance and +editorial contributions to this document.¶
+Internet-Draft | +Structured Field Values for HTTP | +January 2025 | +
Nottingham & Kamp | +Expires 11 July 2025 | +[Page] | +
This document describes a set of data types and associated algorithms that are intended to make it easier and safer to define and handle HTTP header and trailer fields, known as "Structured Fields", "Structured Headers", or "Structured Trailers". It is intended for use by specifications of new HTTP fields that wish to use a common syntax that is more restrictive than traditional HTTP field values.¶
+This document obsoletes RFC 8941.¶
+This note is to be removed before publishing as an RFC.¶
++ Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-sfbis/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/header-structure.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+Specifying the syntax of new HTTP header (and trailer) fields is an onerous task; even with the guidance in Section 16.3.2 of [HTTP], there are many decisions -- and pitfalls -- for a prospective HTTP field author.¶
+Once a field is defined, bespoke parsers and serializers often need to be written, because each field value has a slightly different handling of what looks like common syntax.¶
+This document introduces a set of common data structures for use in definitions of new HTTP field values to address these problems. In particular, it defines a generic, abstract model for them, along with a concrete serialization for expressing that model in HTTP [HTTP] header and trailer fields.¶
+An HTTP field that is defined as a "Structured Header" or "Structured Trailer" (if the field can be either, it is a "Structured Field") uses the types defined in this specification to define its syntax and basic handling rules, thereby simplifying both its definition by specification writers and handling by implementations.¶
+Additionally, future versions of HTTP can define alternative serializations of the abstract model of these structures, allowing fields that use that model to be transmitted more efficiently without being redefined.¶
+Note that it is not a goal of this document to redefine the syntax of existing HTTP fields; the mechanisms described herein are only intended to be used with fields that explicitly opt into them.¶
+Section 2 describes how to specify a Structured Field.¶
+Section 3 defines a number of abstract data types that can be used in Structured Fields.¶
+Those abstract types can be serialized into and parsed from HTTP field values using the algorithms described in Section 4.¶
+This specification intentionally defines strict parsing and serialization behaviors using step-by-step algorithms; the only error handling defined is to fail the entire operation altogether.¶
+It is designed to encourage faithful implementation and good interoperability. Therefore, an implementation that tried to be helpful by being more tolerant of input would make interoperability worse, since that would create pressure on other implementations to implement similar (but likely subtly different) workarounds.¶
+In other words, strict processing is an intentional feature of this specification; it allows non-conformant input to be discovered and corrected by the producer early and avoids both interoperability and security issues that might otherwise result.¶
+Note that as a result of this strictness, if a field is appended to by multiple parties (e.g., intermediaries or different components in the sender), an error in one party's value is likely to cause the entire field value to fail parsing.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.¶
+This document uses the VCHAR, SP, DIGIT, ALPHA, and DQUOTE rules from [RFC5234] to specify characters and/or their corresponding ASCII bytes, depending on context. It uses the tchar and OWS rules from [HTTP] for the same purpose.¶
+This document uses algorithms to specify parsing and serialization behaviors. When parsing from HTTP fields, implementations MUST have behavior that is indistinguishable from following the algorithms.¶
+For serialization to HTTP fields, the algorithms define the recommended way to produce them. Implementations MAY vary from the specified behavior so long as the output is still correctly handled by the parsing algorithm described in Section 4.2.¶
+To specify an HTTP field as a Structured Field, its authors need to:¶
+Normatively reference this specification. Recipients and generators of the field need to know that the requirements of this document are in effect.¶
+Identify whether the field is a Structured Header (i.e., it can only be used in the header section -- the common case), a Structured Trailer (only in the trailer section), or a Structured Field (both).¶
+Specify the type of the field value; either List (Section 3.1), Dictionary (Section 3.2), or Item (Section 3.3).¶
+Define the semantics of the field value.¶
+Specify any additional constraints upon the field value, as well as the consequences when those constraints are violated.¶
+Typically, this means that a field definition will specify the top-level type -- List, Dictionary, or Item -- and then define its allowable types and constraints upon them. For example, a header defined as a List might have all Integer members, or a mix of types; a header defined as an Item might allow only Strings, and additionally only strings beginning with the letter "Q", or strings in lowercase. Likewise, Inner Lists (Section 3.1.1) are only valid when a field definition explicitly allows them.¶
+Fields that use the Display String type are advised to carefully specify their allowable unicode code points; for example, specifying the use of a profile from [PRECIS].¶
+Field definitions can only use this specification for the entire field value, not a portion thereof.¶
+Specifications can refer to a field name as a "structured header name", "structured trailer name", or "structured field name" as appropriate. Likewise, they can refer its field value as a "structured header value", "structured trailer value", or "structured field value" as necessary.¶
+This specification defines minimums for the length or number of various structures supported by implementations. It does not specify maximum sizes in most cases, but authors should be aware that HTTP implementations do impose various limits on the size of individual fields, the total number of fields, and/or the size of the entire header or trailer section.¶
+A fictitious Foo-Example header field might be specified as:¶
+++42. Foo-Example Header Field¶
+The Foo-Example HTTP header field conveys information about how +much Foo the message has.¶
+Foo-Example is an Item Structured Header Field [RFCnnnn]. Its value +MUST be an Integer (Section 3.3.1 of [RFCnnnn]).¶
+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.¶
+The following parameter is defined:¶
++
+- A parameter whose key is "foourl", and whose value is a String + (Section 3.3.3 of [RFCnnnn]), conveying the Foo URL + for the message. See below for processing requirements.¶ +
+"foourl" contains a URI-reference (Section 4.1 of [RFC3986]). If +its value is not a valid URI-reference, the entire header field +MUST be ignored. If its value is a relative reference (Section 4.2 +of [RFC3986]), it MUST be resolved (Section 5 of [RFC3986]) before +being used.¶
+For example:¶
++++ Foo-Example: 2; foourl="https://foo.example.com/" +¶ +
When parsing fails, the entire field is ignored (see Section 4.2). Field definitions cannot override this, because doing so would preclude handling by generic software; they can only add additional constraints (for example, on the numeric range of Integers and Decimals, the format of Strings and Tokens, the types allowed in a Dictionary's values, or the number of Items in a List).¶
+When field-specific constraints are violated, the entire field is also ignored, unless the field definition defines other handling requirements. For example, if a header field is defined as an Item and required to be an Integer, but a String is received, it should be ignored unless that field's definition explicitly specifies otherwise.¶
+Structured Fields are designed to be extensible, because experience has shown that even when it is not foreseen, it is often necessary to modify and add to the allowable syntax and semantics of a field in a controlled fashion.¶
+Both Items and Inner Lists allow Parameters as an extensibility mechanism; this means that their values can later be extended to accommodate more information, if need be. To preserve forward compatibility, field specifications are discouraged from defining the presence of an unrecognized parameter as an error condition.¶
+Field specifications are required to be either an Item, List, or Dictionary to preserve extensibility. Fields that erroneously defined as another type (e.g., Integer) are assumed to be Items (i.e., they allow Parameters).¶
+To further assure that this extensibility is available in the future, and to encourage consumers to use a complete parser implementation, a field definition can specify that "grease" parameters be added by senders. A specification could stipulate that all parameters that fit a defined pattern are reserved for this use and then encourage them to be sent on some portion of requests. This helps to discourage recipients from writing a parser that does not account for Parameters.¶
+Specifications that use Dictionaries can also allow for forward compatibility by requiring that the presence of -- as well as value and type associated with -- unknown keys be ignored. Subsequent specifications can then add additional keys, specifying constraints on them as appropriate.¶
+An extension to a Structured Field can then require that an entire field value be ignored by a recipient that understands the extension if constraints on the value it defines are not met.¶
+Because a field definition needs to reference a specific RFC for Structured Fields, the types available for use in its value are limited to those defined in that RFC. For example, a field whose definition references this document can have a value that uses the Date type (Section 3.3.7), whereas a field whose definition references RFC 8941 cannot, because it will be treated as invalid (and therefore discarded) by implementations of that specification.¶
+This limitation also applies to future extensions to a field; for example, a field that is defined with reference to RFC 8941 cannot use the Date type, because some recipients might still be using an RFC 8941 parser to process it.¶
+However, this document is designed to be backwards-compatible with RFC 8941; a parser that implements the requirements here can also parse valid Structured Fields whose definitions reference RFC 8941.¶
+Upgrading a Structured Fields implementation to support a newer revision of the specification (such as this document) brings the possibility that some field values that were invalid according to the earlier RFC might become valid when processed.¶
+For example, field instance might contain a syntactically valid Date (Section 3.3.7), even though that field's definition does not accommodate Dates. An RFC8941 implementation would fail parsing such a field instance, because they are not defined in that specification. If that implementation were upgraded to this specification, parsing would now succeed. In some cases, the resulting Date value will be rejected by field-specific logic, but values in fields that are otherwise ignored (such as extension parameters) might not be detected and the field might subsequently be accepted and processed.¶
+This section provides an overview of the abstract types that Structured Fields use, and gives a brief description and examples of how each of those types are serialized into textual HTTP fields. Section 4 specifies the details of how they are parsed from and serialized into textual HTTP fields.¶
+In summary:¶
+There are three top-level types that an HTTP field can be defined as: Lists, Dictionaries, and Items.¶
+Lists and Dictionaries are containers; their members can be Items or Inner Lists (which are themselves arrays of Items).¶
+Both Items and Inner Lists can be Parameterized with key/value pairs.¶
+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 can be Parameterized (Section 3.1.2).¶
+An empty List is denoted by not serializing the field at all. This implies that fields defined as Lists have a default empty value.¶
+When serialized as a textual HTTP field, each member is separated by a comma and optional whitespace. For example, a field whose value is defined as a List of Tokens could look like:¶
+ +Note that Lists can have their members split across multiple lines of the same header or trailer section, as per Section 5.3 of [HTTP]; for example, the following are equivalent:¶
+ +and¶
+ +However, individual members of a List cannot be safely split between lines; see Section 4.2 for details.¶
+Parsers MUST support Lists containing at least 1024 members. Field specifications can constrain the types and cardinality of individual List values as they require.¶
+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 (Section 3.1.2).¶
+When serialized in a textual HTTP field, Inner Lists are denoted by surrounding parenthesis, and their values are delimited by one or more spaces. A field whose value is defined as a List of Inner Lists of Strings could look like:¶
+ +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 Parameters at both levels could look like:¶
+ +Parsers MUST support Inner Lists containing at least 256 members. Field specifications can constrain the types and cardinality of individual Inner List members as they require.¶
+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 are unique within the scope of the Parameters they occur within, and the values are bare items (i.e., they themselves cannot be 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.¶
+Note that parameters are ordered, and parameter keys cannot contain uppercase letters.¶
+When serialized in a textual HTTP field, a Parameter is separated from its Item or Inner List and other Parameters by a semicolon. For example:¶
+ +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:¶
+ +Note that this requirement is only on serialization; parsers are still required to correctly handle the true value when it appears in a parameter.¶
+Parsers MUST support at least 256 parameters on an Item or Inner List, and support parameter keys with at least 64 characters. Field specifications can constrain the order of individual parameters, as well as their values' types as required.¶
+Dictionaries are ordered maps of key-value pairs, where the keys 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). There can be zero or more members, and their keys are unique in the scope of the Dictionary they occur within.¶
+Implementations MUST provide access to Dictionaries both by index and by key. Specifications MAY use either means of accessing the members.¶
+As with Lists, an empty Dictionary is represented by omitting the entire field. This implies that fields defined as Dictionaries have a default empty value.¶
+Typically, a field specification will define the semantics of Dictionaries by specifying the allowed type(s) for individual members by their keys, as well as whether their presence is required or optional. Recipients MUST ignore members whose keys are undefined or unknown, unless the field's specification specifically disallows them.¶
+When serialized as a textual HTTP field, Members are ordered as serialized and separated by a comma with optional whitespace. Member keys cannot contain uppercase characters. Keys and values are separated by "=" (without whitespace). For example:¶
+ +Note that in this example, the final "=" is due to the inclusion of a Byte Sequence; see Section 3.3.5.¶
+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:¶
+ +Note that this requirement is only on serialization; parsers are still required to correctly handle the true Boolean value when it appears in Dictionary values.¶
+A Dictionary with a member whose value is an Inner List of Tokens:¶
+ +A Dictionary with a mix of Items and Inner Lists, some with parameters:¶
+ +Note that Dictionaries can have their members split across multiple lines of the same header or trailer section; for example, the following are equivalent:¶
+ +and¶
+ +However, individual members of a Dictionary cannot be safely split between lines; see Section 4.2 for details.¶
+Parsers MUST support Dictionaries containing at least 1024 key/value pairs and keys with at least 64 characters. Field specifications can constrain the order of individual Dictionary members, as well as their values' types as required.¶
+An Item can be an Integer (Section 3.3.1), a Decimal (Section 3.3.2), a String (Section 3.3.3), a Token (Section 3.3.4), a Byte Sequence (Section 3.3.5), a Boolean (Section 3.3.6), or a Date (Section 3.3.7). It can have associated parameters (Section 3.1.2).¶
+For example, a header field that is defined to be an Item that is an Integer might look like:¶
+ +or with parameters:¶
+ +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 compatibility [IEEE754].¶
+For example:¶
+ +Integers larger than 15 digits can be supported in a variety of ways; 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 factor.¶
+While it is possible to serialize 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 for readability; they are not valid in the wire format.¶
+Decimals are numbers with an integer and a fractional component. The integer component has at most 12 digits; the fractional component has at most three digits.¶
+For example, a header whose value is defined as a Decimal could look like:¶
+ +While it is possible to serialize 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 serialization algorithm (Section 4.1.5) rounds input with more than three digits of precision in the fractional component. If an alternative rounding strategy is desired, this should be specified by the field definition to occur before serialization.¶
+Strings are zero or more printable ASCII [RFC0020] characters (i.e., the range %x20 to %x7E). Note that this excludes tabs, newlines, carriage returns, etc.¶
+Non-ASCII characters are not directly supported in Strings, because they cause a number of interoperability issues, and -- with few exceptions -- field values do not require them.¶
+When it is necessary for a field value to convey non-ASCII content, a Display String (Section 3.3.8) can be specified.¶
+When serialized in a textual HTTP field, Strings are delimited with double quotes, using a backslash ("\") to escape double quotes and backslashes. For example:¶
+ +Note that Strings only use DQUOTE as a delimiter; single quotes do not delimit Strings. Furthermore, only DQUOTE and "\" can be escaped; other characters after "\" MUST cause parsing to fail.¶
+Parsers MUST support Strings (after any decoding) with at least 1024 characters.¶
+Tokens are short textual words that begin with an alphabetic character or "*", followed by zero to many token characters, which are the same as those allowed by the "token" ABNF rule defined in [HTTP], plus the ":" and "/" characters.¶
+For example:¶
+ +Parsers MUST support Tokens with at least 512 characters.¶
+Note that Tokens are defined largely for compatibility with the data model of existing HTTP fields, and may require additional steps to use in some implementations. As a result, new fields are encouraged to use Strings.¶
+Byte Sequences can be conveyed in Structured Fields.¶
+When serialized in a textual HTTP field, a Byte Sequence is delimited with colons and encoded using base64 ([RFC4648], Section 4). For example:¶
+ +Parsers MUST support Byte Sequences with at least 16384 octets after decoding.¶
+Boolean values can be conveyed in Structured Fields.¶
+When serialized in a textual HTTP field, a Boolean is indicated with a leading "?" character followed by a "1" for a true value or "0" for false. For example:¶
+ +Note that in Dictionary (Section 3.2) and Parameter (Section 3.1.2) values, Boolean true is indicated by omitting the value.¶
+Date values can be conveyed in Structured Fields.¶
+Dates have a data model that is similar to Integers, representing a (possibly negative) delta in seconds from 1970-01-01T00:00:00Z, excluding leap seconds. Accordingly, their serialization in textual HTTP fields is similar to that of Integers, distinguished from them with a leading "@".¶
+For example:¶
+ +Parsers MUST support Dates whose values include all days in years 1 to 9999 (i.e., -62,135,596,800 to 253,402,214,400 delta seconds from 1970-01-01T00:00:00Z).¶
+Display Strings are similar to Strings, in that they consist of zero or more characters, but they allow Unicode scalar values (i.e., all Unicode code points except for surrogates), unlike Strings.¶
+Display Strings are intended for use in cases where a value is displayed to end users, and therefore may need to carry non-ASCII content. It is NOT RECOMMENDED that they be used in situations where a String (Section 3.3.3) or Token (Section 3.3.4) would be adequate, because Unicode has processing considerations (e.g., normalization) and security considerations (e.g., homograph attacks) that make it more difficult to handle correctly.¶
+Note that Display Strings do not indicate the language used in the value; that can be done separately if necessary (e.g., with a parameter).¶
+In textual HTTP fields, Display Strings are represented in a manner similar to Strings, except that non-ASCII characters are percent-encoded; there is a leading "%" to distinguish them from Strings.¶
+For example:¶
+ +See Section 6 for additional security considerations when handling Display Strings.¶
+This section defines how to serialize and parse the abstract types defined by Section 3 into textual HTTP field values and other encodings compatible with them (e.g., in HTTP/2 [HTTP/2] before compression with HPACK [HPACK]).¶
+Given a structure defined in this specification, return an ASCII string suitable for use in an HTTP field value.¶
+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., omit both the field-name and field-value).¶
+If the structure is a List, let output_string be the result of running Serializing a List (Section 4.1.1) with the structure.¶
+Else, if the structure is a Dictionary, let output_string be the result of running Serializing a Dictionary (Section 4.1.2) with the structure.¶
+Else, if the structure is an Item, let output_string be the result of running Serializing an Item (Section 4.1.3) with the structure.¶
+Else, fail serialization.¶
+Return output_string converted into an array of bytes, using ASCII encoding [RFC0020].¶
+Given an array of (member_value, parameters) tuples as input_list, return an ASCII string suitable for use in an HTTP field value.¶
+Let output be an empty string.¶
+For each (member_value, parameters) of input_list:¶
+If member_value is an array, append the result of running Serializing an Inner List (Section 4.1.1.1) with (member_value, parameters) to output.¶
+Otherwise, append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
+If more member_values remain in input_list:¶
+ +Return output.¶
+Given an array of (member_value, parameters) tuples as inner_list, and parameters as list_parameters, return an ASCII string suitable for use in an HTTP field value.¶
+Let output be the string "(".¶
+For each (member_value, parameters) of inner_list:¶
+Append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
+If more values remain in inner_list, append a single SP to output.¶
+Append ")" to output.¶
+Append the result of running Serializing Parameters (Section 4.1.1.2) with list_parameters to output.¶
+Return output.¶
+Given an ordered Dictionary as input_parameters (each member having a param_key and a param_value), return an ASCII string suitable for use in an HTTP field value.¶
+Let output be an empty string.¶
+For each param_key with a value of param_value in input_parameters:¶
+Append ";" to output.¶
+Append the result of running Serializing a Key (Section 4.1.1.3) with param_key to output.¶
+If param_value is not Boolean true:¶
+Append "=" to output.¶
+Append the result of running Serializing a bare Item (Section 4.1.3.1) with param_value to output.¶
+Return output.¶
+Given a key as input_key, return an ASCII string suitable for use in an HTTP field value.¶
+Convert input_key into a sequence of ASCII characters; if conversion fails, fail serialization.¶
+If input_key contains characters not in lcalpha, DIGIT, "_", "-", ".", or "*", fail serialization.¶
+If the first character of input_key is not lcalpha or "*", fail serialization.¶
+Let output be an empty string.¶
+Append input_key to output.¶
+Return output.¶
+Given an ordered Dictionary as input_dictionary (each member having a member_key and a tuple value of (member_value, parameters)), return an ASCII string suitable for use in an HTTP field value.¶
+Let output be an empty string.¶
+For each member_key with a value of (member_value, parameters) in input_dictionary:¶
+Append the result of running Serializing a Key (Section 4.1.1.3) with member's member_key to output.¶
+If member_value is Boolean true:¶
+Append the result of running Serializing Parameters (Section 4.1.1.2) with parameters to output.¶
+Otherwise:¶
+Append "=" to output.¶
+If member_value is an array, append the result of running Serializing an Inner List (Section 4.1.1.1) with (member_value, parameters) to output.¶
+Otherwise, append the result of running Serializing an Item (Section 4.1.3) with (member_value, parameters) to output.¶
+If more members remain in input_dictionary:¶
+ +Return output.¶
+Given an Item as bare_item and Parameters as item_parameters, return an ASCII string suitable for use in an HTTP field value.¶
+Let output be an empty string.¶
+Append the result of running Serializing a Bare Item (Section 4.1.3.1) with bare_item to output.¶
+Append the result of running Serializing Parameters (Section 4.1.1.2) with item_parameters to output.¶
+Return output.¶
+Given an Item as input_item, return an ASCII string suitable for use in an HTTP field value.¶
+If input_item is an Integer, return the result of running Serializing an Integer (Section 4.1.4) with input_item.¶
+If input_item is a Decimal, return the result of running Serializing a Decimal (Section 4.1.5) with input_item.¶
+If input_item is a String, return the result of running Serializing a String (Section 4.1.6) with input_item.¶
+If input_item is a Token, return the result of running Serializing a Token (Section 4.1.7) with input_item.¶
+If input_item is a Byte Sequence, return the result of running Serializing a Byte Sequence (Section 4.1.8) with input_item.¶
+If input_item is a Boolean, return the result of running Serializing a Boolean (Section 4.1.9) with input_item.¶
+If input_item is a Date, return the result of running Serializing a Date (Section 4.1.10) with input_item.¶
+If input_item is a Display String, return the result of running Serializing a Display String (Section 4.1.11) with input_item.¶
+Otherwise, fail serialization.¶
+Given an Integer as input_integer, return an ASCII string suitable for use in an HTTP field value.¶
+If input_integer is not an integer in the range of -999,999,999,999,999 to 999,999,999,999,999 inclusive, fail serialization.¶
+Let output be an empty string.¶
+If input_integer is less than (but not equal to) 0, append "-" to output.¶
+Append input_integer's numeric value represented in base 10 using only decimal digits to output.¶
+Return output.¶
+Given a decimal number as input_decimal, return an ASCII string suitable for use in an HTTP field value.¶
+If input_decimal is not a decimal number, fail serialization.¶
+If input_decimal has more than three significant digits to the right of the decimal point, round it to three decimal places, rounding the final digit to the nearest value, or to the even value if it is equidistant.¶
+If input_decimal has more than 12 significant digits to the left of the decimal point after rounding, fail serialization.¶
+Let output be an empty string.¶
+If input_decimal is less than (but not equal to) 0, append "-" to output.¶
+Append input_decimal's integer component represented in base 10 (using only decimal digits) to output; if it is zero, append "0".¶
+Append "." to output.¶
+If input_decimal's fractional component is zero, append "0" to output.¶
+Otherwise, append the significant digits of input_decimal's fractional component represented in base 10 (using only decimal digits) to output.¶
+Return output.¶
+Given a String as input_string, return an ASCII string suitable for use in an HTTP field value.¶
+Convert input_string into a sequence of ASCII characters; if conversion fails, fail serialization.¶
+If input_string contains characters in the range %x00-1f or %x7f-ff (i.e., not in VCHAR or SP), fail serialization.¶
+Let output be the string DQUOTE.¶
+For each character char in input_string:¶
+ +Append DQUOTE to output.¶
+Return output.¶
+Given a Token as input_token, return an ASCII string suitable for use in an HTTP field value.¶
+Convert input_token into a sequence of ASCII characters; if conversion fails, fail serialization.¶
+If the first character of input_token is not ALPHA or "*", or the remaining portion contains a character not in tchar, ":", or "/", fail serialization.¶
+Let output be an empty string.¶
+Append input_token to output.¶
+Return output.¶
+Given a Byte Sequence as input_bytes, return an ASCII string suitable for use in an HTTP field value.¶
+If input_bytes is not a sequence of bytes, fail serialization.¶
+Let output be an empty string.¶
+Append ":" to output.¶
+Append the result of base64-encoding input_bytes as per [RFC4648], Section 4, taking account of the requirements below.¶
+Append ":" to output.¶
+Return output.¶
+The encoded data is required to be padded with "=", as per [RFC4648], Section 3.2.¶
+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 implementation constraints.¶
+Given a Boolean as input_boolean, return an ASCII string suitable for use in an HTTP field value.¶
+ +Given a Date as input_date, return an ASCII string suitable for use in an HTTP field value.¶
+Let output be "@".¶
+Append to output the result of running Serializing an Integer with input_date (Section 4.1.4).¶
+Return output.¶
+Given a sequence of Unicode codepoints as input_sequence, return an ASCII string suitable for use in an HTTP field value.¶
+If input_sequence is not a sequence of Unicode codepoints, fail serialization.¶
+Let byte_array be the result of applying UTF-8 encoding (Section 3 of [UTF8]) to input_sequence. If encoding fails, fail serialization.¶
+Let encoded_string be a string containing "%" followed by DQUOTE.¶
+For each byte in byte_array:¶
+ +Append DQUOTE to encoded_string.¶
+Return encoded_string.¶
+Note that [UTF8] prohibits the encoding of codepoints between U+D800 and U+DFFF (surrogates); if they occur in input_sequence, serialization will fail.¶
+When a receiving implementation parses HTTP fields that are known to be Structured Fields, it is important that care be taken, as there are a number of edge cases that can cause interoperability or even security problems. This section specifies the algorithm for doing so.¶
+Given an array of bytes as input_bytes that represent the chosen field's field-value (which is empty if that field is not present) and field_type (one of "dictionary", "list", or "item"), return the parsed field value.¶
+Convert input_bytes into an ASCII string input_string; if conversion fails, fail parsing.¶
+Discard any leading SP characters from input_string.¶
+If field_type is "list", let output be the result of running Parsing a List (Section 4.2.1) with input_string.¶
+If field_type is "dictionary", let output be the result of running Parsing a Dictionary (Section 4.2.2) with input_string.¶
+If field_type is "item", let output be the result of running Parsing an Item (Section 4.2.3) with input_string.¶
+Discard any leading SP characters from input_string.¶
+If input_string is not empty, fail parsing.¶
+Otherwise, return output.¶
+When generating input_bytes, parsers MUST combine all field lines in the same section (header or trailer) that case-insensitively match the field name into one comma-separated field-value, as per Section 5.2 of [HTTP]; this assures that the entire field value is processed correctly.¶
+For Lists and Dictionaries, this has the effect of correctly concatenating all of the field's lines, as long as individual members of the top-level data structure are not split across multiple field 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 results, because one or more commas (with optional whitespace) will become part of the string output by the parser. Since concatenation might be done by an upstream intermediary, the results are not under the control of the serializer or the parser, even when they are both under the control of the same party.¶
+Tokens, Integers, Decimals, and Byte Sequences cannot be split across multiple field lines because the inserted commas will cause parsing 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 an sf-string is allowed to fail when processing this field section:¶
+ +If parsing fails, either the entire field value MUST be ignored (i.e., treated as if the field were not present in the section), or alternatively the complete HTTP message MUST be treated as malformed. This is intentionally strict to improve interoperability and safety, and field specifications that use Structured Fields are not allowed to loosen this requirement.¶
+Note that this requirement does not apply to an implementation that is not parsing the field; for example, an intermediary is not required to strip a failing field from a message before forwarding it.¶
+Given an ASCII string as input_string, return an array of (item_or_inner_list, parameters) tuples. input_string is modified to remove the parsed value.¶
+Let members be an empty array.¶
+While input_string is not empty:¶
+Append the result of running Parsing an Item or Inner List (Section 4.2.1.1) with input_string to members.¶
+Discard any leading OWS characters from input_string.¶
+If input_string is empty, return members.¶
+Consume the first character of input_string; if it is not ",", fail parsing.¶
+Discard any leading OWS characters from input_string.¶
+If input_string is empty, there is a trailing comma; fail parsing.¶
+No structured data has been found; return members (which is empty).¶
+Given an ASCII string as input_string, return the tuple (item_or_inner_list, parameters), where item_or_inner_list can be either a single bare item or an array of (bare_item, parameters) tuples. input_string is modified to remove the parsed value.¶
+If the first character of input_string is "(", return the result of running Parsing an Inner List (Section 4.2.1.2) with input_string.¶
+Return the result of running Parsing an Item (Section 4.2.3) with input_string.¶
+Given an ASCII string as input_string, return the tuple (inner_list, parameters), where inner_list is an array of (bare_item, parameters) tuples. input_string is modified to remove the parsed value.¶
+Consume the first character of input_string; if it is not "(", fail parsing.¶
+Let inner_list be an empty array.¶
+While input_string is not empty:¶
+Discard any leading SP characters from input_string.¶
+If the first character of input_string is ")":¶
+Consume the first character of input_string.¶
+Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
+Return the tuple (inner_list, parameters).¶
+Let item be the result of running Parsing an Item (Section 4.2.3) with input_string.¶
+Append item to inner_list.¶
+If the first character of input_string is not SP or ")", fail parsing.¶
+The end of the Inner List was not found; fail parsing.¶
+Given an ASCII string as input_string, return an ordered map whose values are (item_or_inner_list, parameters) tuples. input_string is modified to remove the parsed value.¶
+Let dictionary be an empty, ordered map.¶
+While input_string is not empty:¶
+Let this_key be the result of running Parsing a Key (Section 4.2.3.3) with input_string.¶
+If the first character of input_string is "=":¶
+Consume the first character of input_string.¶
+Let member be the result of running Parsing an Item or Inner List (Section 4.2.1.1) with input_string.¶
+Otherwise:¶
+Let value be Boolean true.¶
+Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
+Let member be the tuple (value, parameters).¶
+If dictionary already contains a key this_key (comparing character for character), overwrite its value with member.¶
+Otherwise, append key this_key with value member to dictionary.¶
+Discard any leading OWS characters from input_string.¶
+If input_string is empty, return dictionary.¶
+Consume the first character of input_string; if it is not ",", fail parsing.¶
+Discard any leading OWS characters from input_string.¶
+If input_string is empty, there is a trailing comma; fail parsing.¶
+No structured data has been found; return dictionary (which is empty).¶
+Note that when duplicate Dictionary keys are encountered, all but the last instance are ignored.¶
+Given an ASCII string as input_string, return a (bare_item, parameters) tuple. input_string is modified to remove the parsed value.¶
+Let bare_item be the result of running Parsing a Bare Item (Section 4.2.3.1) with input_string.¶
+Let parameters be the result of running Parsing Parameters (Section 4.2.3.2) with input_string.¶
+Return the tuple (bare_item, parameters).¶
+Given an ASCII string as input_string, return a bare Item. input_string is modified to remove the parsed value.¶
+If the first character of input_string is a "-" or a DIGIT, return the result of running Parsing an Integer or Decimal (Section 4.2.4) with input_string.¶
+If the first character of input_string is a DQUOTE, return the result of running Parsing a String (Section 4.2.5) with input_string.¶
+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.¶
+If the first character of input_string is ":", return the result of running Parsing a Byte Sequence (Section 4.2.7) with input_string.¶
+If the first character of input_string is "?", return the result of running Parsing a Boolean (Section 4.2.8) with input_string.¶
+If the first character of input_string is "@", return the result of running Parsing a Date (Section 4.2.9) with input_string.¶
+If the first character of input_string is "%", return the result of running Parsing a Display String (Section 4.2.10) with input_string.¶
+Otherwise, the item type is unrecognized; fail parsing.¶
+Given an ASCII string as input_string, return an ordered map whose values are bare Items. input_string is modified to remove the parsed value.¶
+Let parameters be an empty, ordered map.¶
+While input_string is not empty:¶
+If the first character of input_string is not ";", exit the loop.¶
+Consume the ";" character from the beginning of input_string.¶
+Discard any leading SP characters from input_string.¶
+Let param_key be the result of running Parsing a Key (Section 4.2.3.3) with input_string.¶
+Let param_value be Boolean true.¶
+If the first character of input_string is "=":¶
+Consume the "=" character at the beginning of input_string.¶
+Let param_value be the result of running Parsing a Bare Item (Section 4.2.3.1) with input_string.¶
+If parameters already contains a key param_key (comparing character for character), overwrite its value with param_value.¶
+Otherwise, append key param_key with value param_value to parameters.¶
+Return parameters.¶
+Note that when duplicate parameter keys are encountered, all but the last instance are ignored.¶
+Given an ASCII string as input_string, return a key. input_string is modified to remove the parsed value.¶
+ +Given an ASCII string as input_string, return an Integer or Decimal. input_string is modified to remove the parsed value.¶
+NOTE: This algorithm parses both Integers (Section 3.3.1) and Decimals (Section 3.3.2), and returns the corresponding structure.¶
+Let type be "integer".¶
+Let sign be 1.¶
+Let input_number be an empty string.¶
+If the first character of input_string is "-", consume it and set sign to -1.¶
+If input_string is empty, there is an empty integer; fail parsing.¶
+If the first character of input_string is not a DIGIT, fail parsing.¶
+While input_string is not empty:¶
+Let char be the result of consuming the first character of input_string.¶
+If char is a DIGIT, append it to input_number.¶
+Else, if type is "integer" and char is ".":¶
+ +Otherwise, prepend char to input_string, and exit the loop.¶
+If type is "integer" and input_number contains more than 15 characters, fail parsing.¶
+If type is "decimal" and input_number contains more than 16 characters, fail parsing.¶
+If type is "integer":¶
+Let output_number be an Integer that is the result of parsing input_number as an integer.¶
+Otherwise:¶
+ +Let output_number be the product of output_number and sign.¶
+Return output_number.¶
+Given an ASCII string as input_string, return an unquoted String. input_string is modified to remove the parsed value.¶
+Let output_string be an empty string.¶
+If the first character of input_string is not DQUOTE, fail parsing.¶
+Discard the first character of input_string.¶
+While input_string is not empty:¶
+Let char be the result of consuming the first character of input_string.¶
+If char is a backslash ("\"):¶
+ +Else, if char is DQUOTE, return output_string.¶
+Else, if char is in the range %x00-1f or %x7f-ff (i.e., it is not in VCHAR or SP), fail parsing.¶
+Else, append char to output_string.¶
+Reached the end of input_string without finding a closing DQUOTE; fail parsing.¶
+Given an ASCII string as input_string, return a Token. input_string is modified to remove the parsed value.¶
+ +Given an ASCII string as input_string, return a Byte Sequence. input_string is modified to remove the parsed value.¶
+If the first character of input_string is not ":", fail parsing.¶
+Discard the first character of input_string.¶
+If there is not a ":" character before the end of input_string, fail parsing.¶
+Let b64_content be the result of consuming content of input_string up to but not including the first instance of the character ":".¶
+Consume the ":" character at the beginning of input_string.¶
+If b64_content contains a character not included in ALPHA, DIGIT, "+", "/", and "=", fail parsing.¶
+Let binary_content be the result of base64-decoding [RFC4648] b64_content, synthesizing padding if necessary (note the requirements about recipient behavior below). If base64 decoding fails, parsing fails.¶
+Return binary_content.¶
+Because some implementations of base64 do not allow rejection of encoded data that is not properly "=" padded (see [RFC4648], Section 3.2), parsers SHOULD NOT fail when "=" padding is not present, unless they cannot be configured to do so.¶
+Because some implementations of base64 do not allow rejection of 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 they cannot be configured to do so.¶
+This specification does not relax the requirements in Sections 3.1 and 3.3 of [RFC4648]; therefore, parsers MUST fail on characters outside the base64 alphabet and on line feeds in encoded data.¶
+Given an ASCII string as input_string, return a Boolean. input_string is modified to remove the parsed value.¶
+If the first character of input_string is not "?", fail parsing.¶
+Discard the first character of input_string.¶
+If the first character of input_string matches "1", discard the first character, and return true.¶
+If the first character of input_string matches "0", discard the first character, and return false.¶
+No value has matched; fail parsing.¶
+Given an ASCII string as input_string, return a Date. input_string is modified to remove the parsed value.¶
+If the first character of input_string is not "@", fail parsing.¶
+Discard the first character of input_string.¶
+Let output_date be the result of running Parsing an Integer or Decimal (Section 4.2.4) with input_string.¶
+If output_date is a Decimal, fail parsing.¶
+Return output_date.¶
+Given an ASCII string as input_string, return a sequence of Unicode codepoints. input_string is modified to remove the parsed value.¶
+If the first two characters of input_string are not "%" followed by DQUOTE, fail parsing.¶
+Discard the first two characters of input_string.¶
+Let byte_array be an empty byte array.¶
+While input_string is not empty:¶
+Let char be the result of consuming the first character of input_string.¶
+If char is in the range %x00-1f or %x7f-ff (i.e., it is not in VCHAR or SP), fail parsing.¶
+If char is "%":¶
+Let octet_hex be the result of consuming two characters from input_string. If there are not two characters, fail parsing.¶
+If octet_hex contains characters outside the range %x30-39 or %x61-66 (i.e., it is not in 0-9 or lowercase a-f), fail parsing.¶
+Let octet be the result of hex decoding octet_hex (Section 8 of [RFC4648]).¶
+Append octet to byte_array.¶
+If char is DQUOTE:¶
+ +Otherwise, if char is not "%" or DQUOTE:¶
+ +Reached the end of input_string without finding a closing DQUOTE; fail parsing.¶
+Please add the following note to the "Hypertext Transfer Protocol (HTTP) Field Name Registry":¶
+The "Structured Type" column indicates the type of the field (per RFC nnnn), if any, and may be +"Dictionary", "List" or "Item".¶
+Note that field names beginning with characters other than ALPHA or "*" will not be able to be +represented as a Structured Fields Token, and therefore may be incompatible with being mapped into +field values that refer to it.¶
+Then, add a new column, "Structured Type".¶
+Then, add the indicated Structured Type for each existing registry entry listed in Table 1.¶
+Field Name | +Structured Type | +
---|---|
Accept-CH | +List | +
Cache-Status | +List | +
CDN-Cache-Control | +Dictionary | +
Cross-Origin-Embedder-Policy | +Item | +
Cross-Origin-Embedder-Policy-Report-Only | +Item | +
Cross-Origin-Opener-Policy | +Item | +
Cross-Origin-Opener-Policy-Report-Only | +Item | +
Origin-Agent-Cluster | +Item | +
Priority | +Dictionary | +
Proxy-Status | +List | +
The size of most types defined by Structured Fields is not limited; as a result, extremely large fields could be an attack vector (e.g., for resource consumption). Most HTTP implementations limit the sizes of individual fields as well as the overall header or trailer section size to mitigate such attacks.¶
+It is possible for parties with the ability to inject new HTTP fields to change the meaning +of a Structured Field. In some circumstances, this will cause parsing to fail, but it is not possible to reliably fail in all such circumstances.¶
+The Display String type can convey any possible Unicode code point without sanitization; for example, they might contain unassigned code points, control points (including NUL), or noncharacters. Therefore, applications consuming Display Strings need to consider strategies such as filtering or escaping untrusted content before displaying it. See [PRECIS] and [UNICODE-SECURITY].¶
+Earlier proposals for Structured Fields were based upon JSON [RFC8259]. However, constraining its use to make it suitable for HTTP fields required senders and recipients to implement specific additional handling.¶
+For example, JSON has specification issues around large numbers and objects with duplicate members. Although advice for avoiding these issues is available (e.g., [RFC7493]), it cannot be relied upon.¶
+Likewise, JSON strings are by default Unicode strings, which have a number of potential interoperability issues (e.g., in comparison). Although implementers can be advised to avoid non-ASCII content where unnecessary, this is difficult to enforce.¶
+Another example is JSON's ability to nest content to arbitrary depths. Since the resulting memory commitment might be unsuitable (e.g., in embedded and other limited server deployments), it's necessary to limit it in some fashion; however, existing JSON implementations have no such limits, and even if a limit is specified, it's likely that some field definition will find a need to violate it.¶
+Because of JSON's broad adoption and implementation, it is difficult to impose such additional constraints across all implementations; some deployments would fail to enforce them, thereby harming interoperability. In short, if it looks like JSON, people will be tempted to use a JSON parser/serializer on field values.¶
+Since a major goal for Structured Fields is to improve interoperability and simplify implementation, these concerns led to a format that requires a dedicated parser and serializer.¶
+Additionally, there were widely shared feelings that JSON doesn't "look right" in HTTP fields.¶
+A generic implementation of this specification should expose the top-level serialize (Section 4.1) and parse (Section 4.2) functions. They need not be functions; for example, it could be implemented as an object, with methods for each of the different top-level types.¶
+For interoperability, it's important that generic implementations be complete and follow the algorithms closely; see Section 1.1. To aid this, a common test suite is being maintained by the community at <https://github.com/httpwg/structured-field-tests>.¶
+Implementers should note that Dictionaries and Parameters are order-preserving maps. Some fields may not convey meaning in the ordering of these data types, but it should still be exposed so that it will be available to applications that need to use it.¶
+Likewise, implementations should note that it's important to preserve the distinction between Tokens and Strings. While most programming 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 functions to assure that these types remain separate.¶
+The serialization algorithm is defined in a way that it is not strictly limited to the data types defined in Section 3 in every case. For example, Decimals are designed to take broader input and round to allowed values.¶
+Implementations are allowed to limit the size of different structures, subject to the minimums defined for each type. When a structure exceeds an implementation limit, that structure fails parsing or serialization.¶
+This section uses the Augmented Backus-Naur Form (ABNF) notation [RFC5234] to illustrate expected syntax of Structured Fields. However, it cannot be used to validate their syntax, because it does not capture all requirements.¶
+This section is non-normative. If there is disagreement between the parsing algorithms and ABNF, the specified algorithms take precedence.¶
++sf-list = list-member *( OWS "," OWS list-member ) +list-member = sf-item / inner-list + +inner-list = "(" *SP [ sf-item *( 1*SP sf-item ) *SP ] ")" + parameters + +parameters = *( ";" *SP parameter ) +parameter = param-key [ "=" param-value ] +param-key = key +key = ( lcalpha / "*" ) + *( lcalpha / DIGIT / "_" / "-" / "." / "*" ) +lcalpha = %x61-7A ; a-z +param-value = bare-item + +sf-dictionary = dict-member *( OWS "," OWS dict-member ) +dict-member = member-key ( parameters / ( "=" member-value )) +member-key = key +member-value = sf-item / inner-list + +sf-item = bare-item parameters +bare-item = sf-integer / sf-decimal / sf-string / sf-token + / sf-binary / sf-boolean / sf-date / sf-displaystring + +sf-integer = ["-"] 1*15DIGIT +sf-decimal = ["-"] 1*12DIGIT "." 1*3DIGIT +sf-string = DQUOTE *( unescaped / "%" / bs-escaped ) DQUOTE +sf-token = ( ALPHA / "*" ) *( tchar / ":" / "/" ) +sf-binary = ":" base64 ":" +sf-boolean = "?" ( "0" / "1" ) +sf-date = "@" sf-integer +sf-displaystring = "%" DQUOTE *( unescaped / "\" / pct-encoded ) + DQUOTE + +base64 = *( ALPHA / DIGIT / "+" / "/" ) *"=" + +unescaped = %x20-21 / %x23-24 / %x26-5B / %x5D-7E +bs-escaped = "\" ( DQUOTE / "\" ) + +pct-encoded = "%" lc-hexdig lc-hexdig +lc-hexdig = DIGIT / %x61-66 ; 0-9, a-f +¶ +
This revision of the Structured Field Values for HTTP specification has made the following changes:¶
+Added the Date structured type. (Section 3.3.7)¶
+Stopped encouraging use of ABNF in definitions of new structured fields. (Section 2)¶
+Moved ABNF to an informative appendix. (Appendix C)¶
+Added a "Structured Type" column to the HTTP Field Name Registry. (Section 5)¶
+Refined parse failure handling. (Section 4.2)¶
+Added the Display String structured type. (Section 3.3.8)¶
+Many thanks to Matthew Kerwin for his detailed feedback and careful consideration during the development of this specification.¶
+Thanks also to Ian Clelland, Roy Fielding, Anne van Kesteren, Kazuho Oku, Evert Pot, Julian Reschke, Martin Thomson, Mike West, and Jeffrey Yasskin for their contributions.¶
+Internet-Draft | +The Concealed HTTP Authentication Scheme | +January 2025 | +
Schinazi, et al. | +Expires 11 July 2025 | +[Page] | +
Most HTTP authentication schemes are probeable in the sense that it is possible +for an unauthenticated client to probe whether an origin serves resources that +require authentication. It is possible for an origin to hide the fact that it +requires authentication by not generating Unauthorized status codes, however +that only works with non-cryptographic authentication schemes: cryptographic +signatures require a fresh nonce to be signed. Prior to this document, there +was no existing way for the origin to share such a nonce without exposing the +fact that it serves resources that require authentication. This document +defines a new non-probeable cryptographic authentication scheme.¶
+This note is to be removed before publishing as an RFC.¶
++ The latest revision of this draft can be found at https://httpwg.org/http-extensions/draft-ietf-httpbis-unprompted-auth.html. + Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-unprompted-auth/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/. + Working Group information can be found at https://httpwg.org/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/unprompted-auth.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+HTTP authentication schemes (see Section 11 of [HTTP]) allow origins +to restrict access for some resources to only authenticated requests. While +these schemes commonly involve a challenge where the origin asks the client to +provide authentication information, it is possible for clients to send such +information unprompted. This is particularly useful in cases where an origin +wants to offer a service or capability only to "those who know" while all +others are given no indication the service or capability exists. Such designs +rely on an externally-defined mechanism by which keys are distributed. For +example, a company might offer remote employee access to company services +directly via its website using their employee credentials, or offer access to +limited special capabilities for specific employees, while making discovering +(or probing for) such capabilities difficult. As another example, members of +less well-defined communities might use more ephemeral keys to acquire access +to geography- or capability-specific resources, as issued by an entity whose +user base is larger than the available resources can support (by having that +entity metering the availability of keys temporally or geographically).¶
+While digital-signature-based HTTP authentication schemes already exist (e.g., +[HOBA]), they rely on the origin explicitly sending a fresh +challenge to the client, to ensure that the signature input is fresh. That +makes the origin probeable as it sends the challenge to unauthenticated +clients. This document defines a new signature-based authentication scheme that +is not probeable.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+This document uses the notation from Section 1.3 of [QUIC].¶
+This document defines the "Concealed" HTTP authentication scheme. It uses +asymmetric cryptography. Clients possess a key ID and a public/private key +pair, and origin servers maintain a mapping of authorized key IDs to associated +public keys.¶
+The client uses a TLS keying material exporter to generate data to be signed +(see Section 3) then sends the signature using the Authorization (or +Proxy-Authorization) header field (see Section 11 of [HTTP]). The signature +and additional information are exchanged using authentication parameters (see +Section 4). Once the server receives these, it can check whether the +signature validates against an entry in its database of known keys. The server +can then use the validation result to influence its response to the client, for +example by restricting access to certain resources.¶
+When a client wishes to use the Concealed HTTP authentication scheme with a +request, it SHALL compute the authentication proof using a TLS keying material +exporter with the following parameters:¶
+the label is set to "EXPORTER-HTTP-Concealed-Authentication"¶
+the context is set to the structure described in Section 3.1¶
+the exporter output length is set to 48 bytes (see Section 3.2)¶
+Note that TLS 1.3 keying material exporters are defined in Section 7.5 of [TLS], while TLS 1.2 keying material exporters are defined in +[KEY-EXPORT].¶
+The TLS key exporter context is described in Figure 1, using the +notation from Section 1.3 of [QUIC]:¶
+The key exporter context contains the following fields:¶
+The signature scheme sent in the s
Parameter (see Section 4.4).¶
The key ID sent in the k
Parameter (see Section 4.1).¶
The public key used by the server to validate the signature provided by the +client. Its encoding is described in Section 3.1.1.¶
+The scheme for this request, encoded using the format of the scheme portion +of a URI as defined in Section 3.1 of [URI].¶
+The host for this request, encoded using the format of the host portion of a +URI as defined in Section 3.2.2 of [URI].¶
+The port for this request, encoded in network byte order. Note that the port +is either included in the URI, or is the default port for the scheme in use; +see Section 3.2.3 of [URI].¶
+The realm of authentication that is sent in the realm authentication +parameter (Section 11.5 of [HTTP]). If the realm authentication parameter is +not present, this SHALL be empty. This document does not define a means for the +origin to communicate a realm to the client. If a client is not configured to +use a specific realm, it SHALL use an empty realm and SHALL NOT send the realm +authentication parameter.¶
+The Signature Algorithm and Port fields are encoded as unsigned 16-bit integers +in network byte order. The Key ID, Public Key, Scheme, Host, and Realm fields +are length prefixed strings; they are preceded by a Length field that +represents their length in bytes. These length fields are encoded using the +variable-length integer encoding from Section 16 of [QUIC] and MUST be +encoded in the minimum number of bytes necessary.¶
+Both the "Public Key" field of the TLS key exporter context (see above) and the
+a
Parameter (see Section 4.2) carry the same public key. The encoding of
+the public key is determined by the Signature Algorithm in use as follows:¶
The public key is an RSAPublicKey structure [PKCS1] encoded in DER +[X.690]. BER encodings which are not DER MUST be rejected.¶
+The public key is a UncompressedPointRepresentation structure defined in +Section 4.2.8.2 of [TLS], using the curve specified by the SignatureScheme.¶
+The public key is the byte string encoding defined in [EdDSA].¶
+This document does not define the public key encodings for other algorithms. In +order for a SignatureScheme to be usable with the Concealed HTTP authentication +scheme, its public key encoding needs to be defined in a corresponding document.¶
+The key exporter output is 48 bytes long. Of those, the first 32 bytes are part +of the input to the signature and the next 16 bytes are sent alongside the +signature. This allows the recipient to confirm that the exporter produces the +right values. This is described in Figure 2, using the notation from +Section 1.3 of [QUIC]:¶
+The key exporter output contains the following fields:¶
+This is part of the data signed using the client's chosen asymmetric private +key (see Section 3.3).¶
+The verification is transmitted to the server using the v
Parameter (see
+Section 4.5).¶
Once the Signature Input has been extracted from the key exporter output (see +Section 3.2), it is prefixed with static data before being signed. The signature +is computed over the concatenation of:¶
+A string that consists of octet 32 (0x20) repeated 64 times¶
+The context string "HTTP Concealed Authentication"¶
+A single 0 byte which serves as a separator¶
+The Signature Input extracted from the key exporter output (see Section 3.2)¶
+For example, if the Signature Input has all its 32 bytes set to 01, the content +covered by the signature (in hexadecimal format) would be:¶
+The purpose of this static prefix is to mitigate issues that could arise if +authentication asymmetric keys were accidentally reused across protocols (even +though this is forbidden, see Section 8). This construction mirrors that of +the TLS 1.3 CertificateVerify message defined in Section 4.4.3 of [TLS].¶
+The resulting signature is then transmitted to the server using the p
+Parameter (see Section 4.3).¶
This specification defines the following authentication parameters.¶
+All of the byte sequences below are encoded using base64url (see Section 5 of [BASE64]) without quotes and without padding. In other words, the +values of these byte-sequence authentication parameters MUST NOT include any +characters other than ASCII letters, digits, dash and underscore.¶
+The integer below is encoded without a minus and without leading zeroes. In +other words, the value of this integer authentication parameter MUST NOT +include any characters other than digits, and MUST NOT start with a zero unless +the full value is "0".¶
+Using the syntax from [ABNF]:¶
+The REQUIRED "k" (key ID) Parameter is a byte sequence that identifies which +key the client wishes to use to authenticate. This is used by the backend to +point to an entry in a server-side database of known keys, see Section 6.3.¶
+The REQUIRED "a" (public key) Parameter is a byte sequence that specifies the +public key used by the server to validate the signature provided by the client. +This avoids key confusion issues (see [SEEMS-LEGIT]). The encoding of the +public key is described in Section 3.1.1.¶
+The REQUIRED "p" (proof) Parameter is a byte sequence that specifies the proof +that the client provides to attest to possessing the credential that matches +its key ID.¶
+The REQUIRED "s" (signature) Parameter is an integer that specifies the
+signature scheme used to compute the proof transmitted in the p
Parameter.
+Its value is an integer between 0 and 65535 inclusive from the IANA "TLS
+SignatureScheme" registry maintained at
+<https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-signaturescheme>.¶
The REQUIRED "v" (verification) Parameter is a byte sequence that specifies the +verification that the client provides to attest to possessing the key exporter +output (see Section 3.2 for details). This avoids issues with signature schemes +where certain keys can generate signatures that are valid for multiple inputs +(see [SEEMS-LEGIT]).¶
+For example, the key ID "basement" authenticating using Ed25519 +[ED25519] could produce the following header field:¶
+In this section, we subdivide the server role in two:¶
+the "frontend" runs in the HTTP server that terminates the TLS or QUIC +connection created by the client.¶
+the "backend" runs in the HTTP server that has access to the database of +accepted key identifiers and public keys.¶
+In most deployments, we expect the frontend and backend roles to both be +implemented in a single HTTP origin server (as defined in Section 3.6 of [HTTP]). However, these roles can be split such that the frontend is an HTTP +gateway (as defined in Section 3.7 of [HTTP]) and the backend is an HTTP +origin server.¶
+If a frontend is configured to check the Concealed authentication scheme, it +will parse the Authorization (or Proxy-Authorization) header field. If the +authentication scheme is set to "Concealed", the frontend MUST validate that +all the required authentication parameters are present and can be parsed +correctly as defined in Section 4. If any parameter is missing or fails +to parse, the frontend MUST ignore the entire Authorization (or +Proxy-Authorization) header field.¶
+The frontend then uses the data from these authentication parameters to compute +the key exporter output, as defined in Section 3.2. The frontend then shares the +header field and the key exporter output with the backend.¶
+If the frontend and backend roles are implemented in the same machine, this can +be handled by a simple function call.¶
+If the roles are split between two separate HTTP servers, then the backend +won't be able to directly access the TLS keying material exporter from the TLS +connection between the client and frontend, so the frontend needs to explictly +send it. This document defines the "Concealed-Auth-Export" request header field +for this purpose. The Concealed-Auth-Export header field's value is a +Structured Field Byte Sequence (see Section 3.3.5 of [STRUCTURED-FIELDS]) that contains the 48-byte key exporter output +(see Section 3.2), without any parameters. Note that Structured Field Byte +Sequences are encoded using the non-URL-safe variant of base64. For example:¶
+The frontend SHALL forward the HTTP request to the backend, including the +original unmodified Authorization (or Proxy-Authorization) header field and the +newly added Concealed-Auth-Export header field.¶
+Note that, since the security of this mechanism requires the key exporter +output to be correct, backends need to trust frontends to send it truthfully. +This trust relationship is common because the frontend already needs access to +the TLS certificate private key in order to respond to requests. HTTP servers +that parse the Concealed-Auth-Export header field MUST ignore it unless they +have already established that they trust the sender. Similarly, frontends that +send the Concealed-Auth-Export header field MUST ensure that they do not +forward any Concealed-Auth-Export header field received from the client.¶
+Once the backend receives the Authorization (or Proxy-Authorization) header +field and the key exporter output, it looks up the key ID in its database of +public keys. The backend SHALL then perform the following checks:¶
+validate that all the required authentication parameters are present and can +be parsed correctly as defined in Section 4¶
+ensure the key ID is present in the backend's database and maps to a +corresponding public key¶
+validate that the public key from the database is equal to the one in the +Authorization (or Proxy-Authorization) header field¶
+validate that the verification field from the Authorization (or +Proxy-Authorization) header field matches the one extracted from the key +exporter output¶
+verify the cryptographic signature as defined in Section 3.3¶
+If all of these checks succeed, the backend can consider the request to be +properly authenticated, and can reply accordingly (the backend can also forward +the request to another HTTP server).¶
+If any of the above checks fail, the backend MUST treat it as if the +Authorization (or Proxy-Authorization) header field was missing.¶
+Servers that wish to introduce resources whose existence cannot be probed need +to ensure that they do not reveal any information about those resources to +unauthenticated clients. In particular, such servers MUST respond to +authentication failures with the exact same response that they would have used +for non-existent resources. For example, this can mean using HTTP status code +404 (Not Found) instead of 401 (Unauthorized).¶
+The authentication checks described above can take time to compute, and an +attacker could detect use of this mechanism if that time is observable by +comparing the timing of a request for a known non-existent resource to the +timing of a request for a potentially authenticated resource. Servers can +mitigate this observability by slightly delaying responses to some non-existent +resources such that the timing of the authentication verification is not +observable. This delay needs to be carefully considered to avoid having the +delay itself leak the fact that this origin uses this mechanism at all.¶
+Non-probeable resources also need to be non-discoverable for unauthenticated +users. For example, if a server operator wishes to hide an authenticated +resource by pretending it does not exist to unauthenticated users, then the +server operator needs to ensure there are no unauthenticated pages with links +to that resource, and no other out-of-band ways for unauthenticated users to +discover this resource.¶
+This authentication scheme is only defined for uses of HTTP with TLS +[TLS]. This includes any use of HTTP over TLS as typically used for +HTTP/2 [HTTP/2], or HTTP/3 [HTTP/3] where the transport protocol uses TLS as its +authentication and key exchange mechanism [QUIC-TLS].¶
+Because the TLS keying material exporter is only secure for authentication when +it is uniquely bound to the TLS session [RFC7627], the Concealed +authentication scheme requires either one of the following properties:¶
+The TLS version in use is 1.2 and the Extended Master Secret extension +[RFC7627] has been negotiated.¶
+Clients MUST NOT use the Concealed authentication scheme on connections that do +not meet one of the two properties above. If a server receives a request that +uses this authentication scheme on a connection that meets neither of the above +properties, the server MUST treat the request as if the authentication were not +present.¶
+The Concealed HTTP authentication scheme allows a client to authenticate to an +origin server while guaranteeing freshness and without the need for the server +to transmit a nonce to the client. This allows the server to accept +authenticated clients without revealing that it supports or expects +authentication for some resources. It also allows authentication without the +client leaking the presence of authentication to observers due to clear-text +TLS Client Hello extensions.¶
+Since the freshness described above is provided by a TLS key exporter, it can +be as old as the underlying TLS connection. Servers can require better +freshness by forcing clients to create new connections using mechanisms such as +the GOAWAY frame (see Section 5.2 of [HTTP/3]).¶
+The authentication proofs described in this document are not bound to +individual HTTP requests; if the key is used for authentication proofs on +multiple requests on the same connection, they will all be identical. This +allows for better compression when sending over the wire, but implies that +client implementations that multiplex different security contexts over a single +HTTP connection need to ensure that those contexts cannot read each other's +header fields. Otherwise, one context would be able to replay the Authorization +header field of another. This constraint is met by modern Web browsers. If an +attacker were to compromise the browser such that it could access another +context's memory, the attacker might also be able to access the corresponding +key, so binding authentication to requests would not provide much benefit in +practice.¶
+Authentication asymmetric keys used for the Concealed HTTP authentication +scheme MUST NOT be reused in other protocols. Even though we attempt to +mitigate these issues by adding a static prefix to the signed data (see +Section 3.3), reusing keys could undermine the security guarantees of the +authentication.¶
+Origins offering this scheme can link requests that use the same key. +However, requests are not linkable across origins if the keys used are specific +to the individual origins using this scheme.¶
+This document, if approved, requests IANA to register the following entry in +the "HTTP Authentication Schemes" Registry maintained at +<https://www.iana.org/assignments/http-authschemes>:¶
+ +This document, if approved, requests IANA to register the following entry in +the "TLS Exporter Labels" registry maintained at +<https://www.iana.org/assignments/tls-parameters#exporter-labels>:¶
+ +This document, if approved, requests IANA to register the following entry in +the "Hypertext Transfer Protocol (HTTP) Field Name" registry maintained at +<https://www.iana.org/assignments/http-fields/http-fields.xhtml>:¶
+ +The authors would like to thank many members of the IETF community, as this +document is the fruit of many hallway conversations. In particular, the authors +would like to thank David Benjamin, Reese Enghardt, Nick Harper, Dennis Jackson, Ilari Liusvaara, François Michel, +Lucas Pardue, Justin Richer, Ben Schwartz, Martin Thomson, and Chris A. Wood for their reviews and contributions. The +mechanism described in this document was originally part of the first iteration +of MASQUE [MASQUE-ORIGINAL].¶
+Internet-Draft | +Zstd Window Size | +January 2025 | +
Jaju & Handte | +Expires 11 July 2025 | +[Page] | +
Deployments of Zstandard, or "zstd", can use different window sizes to limit +memory usage during compression and decompression. Some browsers and user +agents limit window sizes to mitigate memory usage concerns, causing +interoperability issues. This document updates the window size limit in RFC8878 +from a recommendation to a requirement in HTTP contexts.¶
+This note is to be removed before publishing as an RFC.¶
++ The latest revision of this draft can be found at https://httpwg.org/http-extensions/draft-ietf-httpbis-zstd-window-size.html. + Status information for this document may be found at https://datatracker.ietf.org/doc/draft-ietf-httpbis-zstd-window-size/.¶
++ Discussion of this document takes place on the + HTTP Working Group mailing list (mailto:ietf-http-wg@w3.org), + which is archived at https://lists.w3.org/Archives/Public/ietf-http-wg/.¶
+Source for this draft and an issue tracker can be found at + https://github.com/httpwg/http-extensions/labels/zstd-window-size.¶
++ This Internet-Draft is submitted in full conformance with the + provisions of BCP 78 and BCP 79.¶
++ Internet-Drafts are working documents of the Internet Engineering Task + Force (IETF). Note that other groups may also distribute working + documents as Internet-Drafts. The list of current Internet-Drafts is + at https://datatracker.ietf.org/drafts/current/.¶
++ Internet-Drafts are draft documents valid for a maximum of six months + and may be updated, replaced, or obsoleted by other documents at any + time. It is inappropriate to use Internet-Drafts as reference + material or to cite them other than as "work in progress."¶
++ This Internet-Draft will expire on 11 July 2025.¶
++ Copyright (c) 2025 IETF Trust and the persons identified as the + document authors. All rights reserved.¶
++ This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (https://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with + respect to this document. Code Components extracted from this + document must include Revised BSD License text as described in + Section 4.e of the Trust Legal Provisions and are provided without + warranty as described in the Revised BSD License.¶
+Zstandard, or "zstd", specified in [RFC8878], is a lossless data compression +mechanism similar to gzip. When used with HTTP, the "zstd" content coding +token signals to the decoder that the content is Zstandard-compressed.¶
+An important property of Zstandard-compressed content is its Window_Size +([RFC8878], Section 3.1.1.1.2), which describes the maximum distance for +back-references and therefore how much of the content must be kept in memory +during decompression.¶
+The minimum Window_Size is 1 KB. The maximum Window_Size is +(1<<41) + 7*(1<<38) bytes, which is 3.75 TB. Larger Window_Size values tend +to improve the compression ratio, but at the cost of increased memory usage.¶
+To protect against unreasonable memory usage, some browsers and user agents +limit the maximum Window_Size they will handle. This causes failures to decode +responses when the content is compressed with a larger Window_Size than the +recipient allows, leading to decreased interoperability.¶
+[RFC8878], Section 3.1.1.1.2 recommends that decoders support a Window_Size +of up to 8 MB, and that encoders not generate frames using a Window_Size larger +than 8 MB. However, it imposes no requirements.¶
+This document updates [RFC8878] to enforce Window_Size limits on the encoder +and decoder for the "zstd" HTTP content coding.¶
+The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", +"MAY", and "OPTIONAL" in this document are to be interpreted as +described in BCP 14 [RFC2119] [RFC8174] when, and only when, they +appear in all capitals, as shown here.¶
+To ensure interoperability, when using the "zstd" content coding, decoders MUST +support a Window_Size of up to and including 8 MB, and encoders MUST NOT +generate frames requiring a Window_Size larger than 8 MB (see +Section 5.1).¶
+This document introduces no new security considerations beyond those discussed +in [RFC8878].¶
+Note that decoders still need to take into account that they can receive +oversized frames that do not follow the window size limit specified in this +document and fail decoding when such invalid frames are received.¶
+This document updates the entry added in [RFC8878] to the "HTTP Content +Coding Registry" +within the "Hypertext Transfer Protocol (HTTP) +Parameters" +registry:¶
+ +Zstandard was developed by Yann Collet.¶
+The authors would like to thank Yann Collet, Klaus Post, Adam Rice, and members +of the Web Performance Working Group in the W3C for collaborating on the window +size issue and helping to formulate a solution. Also, thank you to Nick Terrell +for providing feedback that went into RFC 8478 and RFC 8878.¶
+