RFC 7240
Prefer Header for HTTP
Prefer Header for HTTP β¨
Okay bestie, the title block first π This is RFC 7240, written by J. Snell and dated June 2014. It's on the Standards Track, with ISSN 2070-1721. The title block doesn't list anything it obsoletes or updates.
Abstract π
So this spec defines an HTTP header field that a client can use to ask a server to use certain behaviors while it's processing a request. Iconic. π¦
Status of This Memo π
This is an Internet Standards Track document.
It's a product of the Internet Engineering Task Force (IETF), so it represents the consensus of the IETF community. It got public review and was approved for publication by the Internet Engineering Steering Group (IESG). More on Internet Standards is in Section 2 of RFC 5741.
For the current status, any errata, and how to give feedback, check http://www.rfc-editor.org/info/rfc7240. πΈ
Copyright Notice π
Copyright (c) 2014 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 (http://trustee.ietf.org/license-info) as in effect on the date of publication. Please read these carefully, because they describe your rights and restrictions for this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions, and they're provided without warranty as described in the Simplified BSD License. π«Ά
Table of Contents ποΈ
1. Introduction ....................................................2
1.1. Syntax Notation ............................................4
2. The Prefer Request Header Field .................................4
2.1. Examples ...................................................6
3. The Preference-Applied Response Header Field ....................7
4. Preference Definitions ..........................................8
4.1. The "respond-async" Preference .............................8
4.2. The "return=representation" and "return=minimal"
Preferences ................................................9
4.3. The "wait" Preference .....................................11
4.4. The "handling=strict" and "handling=lenient" Processing ...12
5. IANA Considerations ............................................13
5.1. The Registry of Preferences ...............................13
5.2. Initial Registry Contents .................................15
6. Security Considerations ........................................16
7. References .....................................................16
7.1. Normative References ......................................16
7.2. Informative References ....................................16
1. Introduction β¨
Okay so while an HTTP request is being processed, there's usually a whole bunch of behaviors that a server or intermediary can use. They show up in the response in lots of subtle and not-so-subtle ways. π
Take the HTTP PUT method for changing a resource (kinda like the one defined for the Atom Publishing Protocol [RFC5023]). The server gets to pick: it can send back a complete representation of the modified resource, or just a minimal response saying the operation worked. Which one it picks usually doesn't affect whether the request succeeds, but it can change what the client has to do next. Like, if the response already includes the modified resource, the client can skip sending an extra GET request. Big brain move. π§ β¨
Servers also keep running into requests that are technically invalid or incorrect but still understandable. Sometimes the server can ignore those technical errors and still process the request successfully. Whether the client thinks that lenient processing is okay depends on the app's requirements and what the request is actually doing. π
Here's the thing: the server gets the final say on exactly which behaviors to use in these cases, but the server might want to defer to the client about which optional behavior it prefers. π
The problem is that HTTP doesn't have any explicit way to say what the client prefers about the optional parts of handling a request. HTTP does have the Expect header, which can identify mandatory expectations for processing a request. But using it to share optional preferences is messy:
- The semantics of the Expect header field are such that intermediaries and servers are required to reject any request that states unrecognized or unsupported expectations.
- While the Expect header field is end to end, the HTTP specification requires that the header be processed hop by hop. That means every intervening intermediary that handles a request between the client and the origin server is required to process an expectation and determine whether it's capable of handling it appropriately.
So the must-understand semantics of the Expect header make it a bad fit for optional preferences. π
Clients could also put preferences in Request URI query-string parameters. But anything that changes the URI can cause problems, like when caches record the altered URI. π
So this spec goes a different route: it defines a brand new HTTP request header field that clients can use to ask a server to apply optional behaviors while it processes the request. It also defines a handful of starter preference tokens to use with the new header. Main character energy. π
In this document, the key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [RFC2119]. π¦
1.1. Syntax Notation π§©
This spec uses the Augmented Backus-Naur Form (ABNF) notation from [RFC5234]. It also pulls in, by reference, the token, word, OWS, and BWS rules and the #rule extension, all defined in Sections 3.2.1 and 3.2.4 of [RFC7230]. And it includes the delta-seconds rule defined in Section 8.1.3 of [RFC7231]. π·
Part 1 is done, bestie! π₯Ή Part 2 is coming up next with Section 2 and the Prefer Request Header Field, so stay tuned. π
- The Prefer Request Header Field β¨
Okay so bestie, the Prefer request header is how a client says "hey, I'd really like the server to do this thing π₯Ί" π but it's NOT a demand. It's kinda like the Expect header from Section 6.1.2 of [RFC7231] π, except the server is totally allowed to just ignore the preference. Iconic behavior, ngl π
ABNF:
Prefer = "Prefer" ":" 1#preference
preference = token [ BWS "=" BWS word ]
*( OWS ";" [ OWS parameter ] )
parameter = token [ BWS "=" BWS word ]
This header is built with an extensible syntax so future values can be added to the Registry of Preferences (Section 5.1) π¦. Now here's the important part π: a server that doesn't recognize a preference token, or just can't follow it, MUST ignore that token and keep processing instead of throwing an error. No drama, no 400s, just vibes πΈ
Empty or zero-length values on both the preference token and within parameters are the same as having no value at all. So these are all equivalent examples of a "foo" preference with a single "bar" parameter π§
Prefer: foo; bar
Prefer: foo; bar=""
Prefer: foo=""; bar
Any preference token can have an optional set of parameters π. What they mean depends on how each preference is defined and how the server implements it. The order of parameters doesn't matter at all, no cap π
For both preference token names and parameter names, comparison is case insensitive. Values, though, are case sensitive, whether they're token or quoted-string values π
The Prefer header is end to end, so a proxy MUST forward it if the request gets forwarded, UNLESS Prefer is explicitly marked as hop by hop using the Connection header field defined by [RFC7230], Section 6.1 π₯
Sometimes a proxy can honor a preference all on its own, without asking the origin server first π For example, an in-between proxy might be able to handle a request asynchronously with 202 (Accepted) responses, even if the origin server can't. Those proxies can choose to honor the "respond-async" preference by themselves, whether or not the origin is able or willing to do it. Main character energy for proxies β¨
Individual preference tokens MAY set their own rules about whether and how intermediaries can apply the preference on their own, without the origin server π¦
A client MAY send multiple Prefer header fields in one message, OR it MAY send a single Prefer header with multiple comma-separated preference tokens π If there are multiple Prefer headers, it's the same as one Prefer header with all the tokens joined by commas. For example, these two are equivalent:
Multiple Prefer header fields defining three distinct preference tokens:
POST /foo HTTP/1.1
Host: example.org
Prefer: respond-async, wait=100
Prefer: handling=lenient
Date: Tue, 20 Dec 2011 12:34:56 GMT
A single Prefer header field defining the same three preference tokens:
POST /foo HTTP/1.1
Host: example.org
Prefer: handling=lenient, wait=100, respond-async
Date: Tue, 20 Dec 2011 12:34:56 GMT
To avoid any confusion, individual preference tokens SHOULD NOT appear more than once in a single request π If a preference shows up more than once, only the first instance counts. Any later ones SHOULD be ignored, without signaling an error or otherwise changing how the request is processed. This is the ONLY case where the order of preferences in a request matters π
Server-driven content negotiation, caching, and optional preferences are all super tricky to get right together, so implementers are urged to be careful when a preference affects caching of a response π Preferences SHOULD NOT be used for content negotiation π«Ά If a server supports the optional application of a preference that might change how a cache handles a response body, a Vary header field MUST be included in the response listing the Prefer header field, even if the client didn't actually use Prefer in the request. Alternatively, the server MAY include a Vary header with the special value "*" as defined by [RFC7231], Section 8.2.1. Just note that "Vary: *" makes it impossible for a proxy to cache the response π
Preference tokens look a lot like Expect tokens, but Prefer and Expect are totally different things, so preferences can't be used as expectations π β¨
2.1. Examples
These examples show off some preferences defined in this spec, plus some made-up extensions just for illustration π§
- Return a 202 (Accepted) response for async processing if the request can't be processed within 10 seconds. There's also an undefined "priority" preference here π¦:
POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async, wait=10
Prefer: priority=5
{...}
- Use lenient processing πΈ:
POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: Lenient
{...}
- Use of an optional, undefined parameter on the return=minimal preference π:
POST /some-resource HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: return=minimal; foo="some parameter"
{...}
- The Preference-Applied Response Header Field π
The Preference-Applied response header MAY be included in a response to say which Prefer tokens the server actually honored and applied to processing the request π
ABNF:
Preference-Applied = "Preference-Applied" ":" 1#applied-pref
applied-pref = token [ BWS "=" BWS word ]
The big difference from Prefer syntax is that Preference-Applied doesn't include parameters π
You only need Preference-Applied when it's NOT obvious that the server applied a preference, and when that uncertainty could mess with how the client handles the response π€ For example, with "return=representation" or "return=minimal", a client might not be able to tell reliably just by looking at the payload whether the preference was applied. In that case, Preference-Applied can help π
Request:
PATCH /my-document HTTP/1.1
Host: example.org
Content-Type: application/example-patch
Prefer: return=representation
[{"op": "add", "path": "/a", "value": 1}]
Response:
HTTP/1.1 200 OK
Content-Type: application/json
Preference-Applied: return=representation
Content-Location: /my-document
{"a": 1}
- Preference Definitions π
The next subsections define a starter set of preferences π More can be registered for convenience or so other apps can reuse them β¨ This spec sets up an IANA registry of preferences (see Section 5.1) π¦
4.1. The "respond-async" Preference π₯
The "respond-async" preference says the client would like the server to respond asynchronously π For example, if generating the response is going to take longer than some threshold the server picked, the server can honor "respond-async" by returning a 202 (Accepted) response π§
ABNF:
respond-async = "respond-async"
The whole point of "respond-async" is to make async handling work, by letting the client tell the server "I can handle async responses and I'd like that" π«Ά
An example request asking for "respond-async":
POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async
{Data}
An example async response using 202 (Accepted):
HTTP/1.1 202 Accepted
Location: http://example.org/collection/123
202 (Accepted) is defined by [RFC7231], but that spec doesn't really say how or when to use it, and how the final result gets figured out is left totally undefined π So whether and how a server supports async responses is an implementation-specific detail, and it's out of scope for this specification πΈ
4.2. The "return=representation" and "return=minimal" Preferences
okay so return=representation is the client basically saying "hey bestie, after a successful request, can you send back the current state of the resource in your response? π₯Ίπ" π
return=minimal is the opposite vibe: "keep it short, just send me the bare minimum after a successful request" π€β¨ Usually that's a 204 (No Content) status, but other codes MAY be used when they make sense, like a 200 (OK) status with a zero-length response entity. Figuring out what counts as an appropriate minimal response is totally at the server's discretion π
ABNF:
return = "return" BWS "=" BWS ("representation" / "minimal")
when the server honors return=representation, the returned representation might not be a representation of the effective request URI if the request is affecting a different resource π in that case, the Content-Location header can be used to say which URI the returned representation belongs to πΊοΈ
return=representation is all about optimizing the conversation between client and server π It cuts out the need for a follow-up GET request just to fetch the current representation of the resource after a modification. Iconic efficiency π€
after successfully processing a modification request like a POST or PUT, a server can pick between returning an entity that describes the status of the operation, or a representation of the modified resource itself π Which one it sends (or whether it sends anything at all) is 100% the server's call. But return=representation and the return=minimal preference (defined below) let the server take the client's preferences into account while building the response. It's giving collaboration π«Ά
an example request specifying return=representation:
PATCH /item/123 HTTP/1.1
Host: example.org
Content-Type: application/example-patch
Prefer: return=representation
1c1
< ABCDEFGHIJKLMNOPQRSTUVWXYZ
---
> BCDFGHJKLMNPQRSTVWXYZ
an example response containing the resource representation:
HTTP/1.1 200 OK
Content-Location: http://example.org/item/123
Content-Type: text/plain
ETag: "d3b07384d113edec49eaa6238ad5ff00"
BCDFGHJKLMNPQRSTVWXYZ
meanwhile, return=minimal can shrink the amount of data the server is required to send back after a request πͺΆ This is especially handy when someone is on a limited-bandwidth mobile device, or when the client just needs to know whether the request was successfully processed and doesn't care about anything else π±π
an example request specifying return=minimal:
POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: return=minimal
{Data}
an example minimal response:
HTTP/1.1 201 Created
Location: http://example.org/collection/123
return=minimal and return=representation are mutually exclusive directives π
ββοΈ It's anticipated that there will never be a situation where it makes sense for one request to include both. If a request does have both, it's most likely a coding error on the client's side π So a request containing both preferences can be treated as though neither were specified π€·ββοΈ
4.3. The "wait" Preference
the wait preference lets the client set an upper bound, in seconds, on how long it expects the server to take to process the request once it's been received β³ If generating a response is going to take longer than that time, the server, or a proxy, can choose to switch to an asynchronous processing model, for example by returning a 202 (Accepted) response π§
ABNF:
wait = "wait" BWS "=" BWS delta-seconds
this part is important π¬ HTTP messages spend some time traveling across the network and getting processed by intermediaries. That adds to how long a client waits for a response, on top of the time the server spends processing the request. A client with strict timing needs can estimate these factors and adjust the wait value to match π―
as with other preferences, the wait preference could be ignored π« Clients can abandon requests that take longer than they're prepared to wait πββοΈ
for example, a server receiving the following request might choose to respond asynchronously if processing the request will take longer than 10 seconds:
POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: respond-async, wait=10
{Data}
4.4. The "handling=strict" and "handling=lenient" Processing Preferences
the handling=strict and handling=lenient preferences tell the server, at its discretion, how the client wants it to handle potential error conditions that can pop up while processing a request π§ For instance, say the payload of a request has a few minor syntactical or semantic errors, but the server can still understand and successfully process it. Then the server has to decide: reject the request with an appropriate "4xx" error response, or just go ahead and process it π€ handling=strict says that, even if a particular error could be recovered from, the client would rather the server reject the request π« handling=lenient, on the other hand, says the client wants the server to try to process the request anyway π
ABNF:
handling = "handling" BWS "=" BWS ("strict" / "lenient")
an example request specifying the strict preference:
POST /collection HTTP/1.1
Host: example.org
Content-Type: text/plain
Prefer: handling=strict
handling=strict and handling=lenient are mutually exclusive directives too π It's anticipated that there will never be a situation where it makes sense for one request to include both. Any request that does is most likely the result of a coding error on the client's side π So a request containing both preferences can be treated as though neither were specified π«Ά
5. IANA Considerations
the Prefer and Preference-Applied header fields have been added to the "Permanent Message Header Field Names" registry defined in [RFC3864] (http://www.iana.org/assignments/message-headers) πβ¨
Header field name: Prefer
Applicable Protocol: HTTP
Status: Standard
Author: James M Snell <jasnell@gmail.com>
Change controller: IETF
Specification document: this specification, Section 2
Header field name: Preference-Applied
Applicable Protocol: HTTP
Status: Standard
Author: James M Snell <jasnell@gmail.com>
Change controller: IETF
Specification document: this specification, Section 3
5.1. The Registry of Preferences
IANA has created a new registry, "HTTP Preferences", under the "Hypertext Transfer Protocol (HTTP) Parameters" registry ποΈ New registrations will use the Specification Required policy [RFC5226]. The requirements for registered preferences are described in Section 4 π
registration requests usually consist of the completed registration template below, typically published in the required specification. But to allow values to be allocated before publication, the Designated Expert can approve a registration based on a separately submitted template, once they're satisfied that a specification will be published π Preferences can also be registered by third parties, if the Designated Expert determines that an unregistered preference is widely deployed and not likely to be registered in a timely manner π
the registration template is:
- Preference: (A value for the Prefer request header field that conforms to the syntax rule given in Section 2)
- Value: (An enumeration or description of possible values for the preference token).
- Optional Parameters: (An enumeration of optional parameters, and their values, associated with the preference token).
- Description:
- Reference:
- Notes: [optional]
the "Value" and "Optional Parameters" fields MAY be omitted from the registration template if the specific preference token definition does not define either π«§
registration requests should be sent to the <ietf-http-wg@w3.org> mailing list, clearly marked in the subject line (for example, "NEW PREFERENCE - example" to register an "example" preference) π¨ Within at most 14 days of the request, the Designated Expert(s) will either approve or deny the registration request, communicating that decision to the review list and IANA β° Denials should include an explanation and, if applicable, suggestions for how to make the request successful π‘
the Expert Reviewer shall ensure:
- That the requested preference name conforms to the token rule in Section 2 and that it is not identical to any other registered preference name;
- That any associated value, parameter names, and values conform to the relevant ABNF grammar specifications in Section 2;
- That the name is appropriate to the specificity of the preference; i.e., if the semantics are highly specific to a particular application, the name should reflect that, so that more general names remain available for less specific uses. π§
- That requested preferences do not constrain servers, clients, or any intermediaries to any behavior required for successful processing; and
- That the specification document defining the preference includes a proper and complete discussion of any security considerations relevant to the use of the preference. π
5.2. Initial Registry Contents
the "HTTP Preferences" registry's initial contents are:
- Preference: respond-async
- Description: Indicates that the client prefers that the server respond asynchronously to a request.
- Reference: [this specification], Section 4.1
- Preference: return
- Value: One of either "minimal" or "representation"
- Description: When the value is "minimal", it indicates that the client prefers that the server return a minimal response to a request. When the value is "representation", it indicates that the client prefers that the server include a representation of the current state of the resource in response to a request.
- Reference: [this specification], Section 4.2
- Preference: wait
- Description: Indicates an upper bound to the length of time the client expects it will take for the server to process the request once it has been received.
- Reference: [this specification], Section 4.3
- Preference: handling
- Value: One of either "strict" or "lenient"
- Description: When value is "strict", it indicates that the client wishes the server to apply strict validation and error handling to the processing of a request. When the value is "lenient", it indicates that the client wishes the server to apply lenient validation and error handling to the processing of the request.
- Reference: [this specification], Section 4.4
6. Security Considerations πβ¨
okay bestie, this section is lowkey the most important one for keeping our servers safe, so pay attention ππ
Specific preferences a client asks for can bring in security considerations and concerns that go beyond what's covered in HTTP/1.1 [RFC7230] and its related specs (check [RFC7230] for the full list of associated works) π. Implementers need to look at the specifications and descriptions of each preference to figure out which security considerations apply to each one π§π.
A server could end up paying more to try to follow a certain preference πΈ. For example, it might cost extra to send back a representation in a response that wouldn't normally have one, or it might need to commit resources to keep track of state for an asynchronous response π. If a server has to comply with every preference no matter what, then preferences could be abused for denial of service π¨π. A server is allowed to ignore a preference it's been sent if it doesn't want to spend resources on it πβ¨. That's the escape hatch, periodt π .
7. References ππ¦
7.1. Normative References π
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration Procedures for Message Header Fields", BCP 90, RFC 3864, September 2004.
- [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA Considerations Section in RFCs", BCP 26, RFC 5226, May 2008.
- [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", STD 68, RFC 5234, January 2008.
- [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing", RFC 7230, June 2014.
- [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, June 2014.
7.2. Informative References π
Author's Address ποΈπ
James M Snell
EMail: jasnell@gmail.com
π¦ where this page comes from
- ietf: rfc7240 2014-06
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms