| < draft-fielding-http-key-02.txt | draft-fielding-http-key-03.txt > | |||
|---|---|---|---|---|
| Network Working Group R. Fielding | Network Working Group R. Fielding | |||
| Internet-Draft Adobe Systems Incorporated | Internet-Draft Adobe Systems Incorporated | |||
| Intended status: Informational M. Nottingham | Intended status: Informational M. Nottingham | |||
| Expires: August 23, 2013 February 19, 2013 | Expires: March 27, 2016 September 24, 2015 | |||
| The Key HTTP Response Header Field | The Key HTTP Response Header Field | |||
| draft-fielding-http-key-02 | draft-fielding-http-key-03 | |||
| Abstract | Abstract | |||
| The 'Key' header field for HTTP responses allows an origin server to | The 'Key' header field for HTTP responses allows an origin server to | |||
| describe the cache key for a negotiated response: a short algorithm | describe the secondary cache key ([RFC7234], section 4.1) for a | |||
| that can be used upon later requests to determine if the same | resource, by conveying what is effectively a short algorithm that can | |||
| response is reusable. | be used upon later requests to determine if a stored response is | |||
| reusable for a given request. | ||||
| Key has the advantage of avoiding an additional round trip for | Key has the advantage of avoiding an additional round trip for | |||
| validation whenever a new request differs slightly, but not | validation whenever a new request differs slightly, but not | |||
| significantly, from prior requests. | significantly, from prior requests. | |||
| Key also informs user agents of the request characteristics that | Key also informs user agents of the request characteristics that | |||
| might result in different content, which can be useful if the user | might result in different content, which can be useful if the user | |||
| agent is not sending Accept* fields in order to reduce the risk of | agent is not sending request header fields in order to reduce the | |||
| fingerprinting. | risk of fingerprinting. | |||
| Status of this Memo | Note to Readers | |||
| The issues list for this draft can be found at | ||||
| https://github.com/mnot/I-D/labels/key . | ||||
| Status of This Memo | ||||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on August 23, 2013. | This Internet-Draft will expire on March 27, 2016. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2013 IETF Trust and the persons identified as the | Copyright (c) 2015 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 | |||
| 1.1. Notational Conventions . . . . . . . . . . . . . . . . . . 3 | 1.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 2. The "Key" Response Header Field . . . . . . . . . . . . . . . 3 | 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 | |||
| 2.1. Header Matching . . . . . . . . . . . . . . . . . . . . . 4 | 2. The "Key" Response Header Field . . . . . . . . . . . . . . . 4 | |||
| 2.2. Key Modifiers . . . . . . . . . . . . . . . . . . . . . . 6 | 2.1. Relationship with Vary . . . . . . . . . . . . . . . . . 5 | |||
| 2.2.1. "w": Word Match Modifier . . . . . . . . . . . . . . . 6 | 2.2. Calculating a Secondary Cache Key . . . . . . . . . . . . 6 | |||
| 2.2.2. "s": Substring Match Modifier . . . . . . . . . . . . 6 | 2.2.1. Creating a Header Field Value . . . . . . . . . . . . 8 | |||
| 2.2.3. "b": Beginning Substring Match Modifier . . . . . . . 6 | 2.2.2. Failing Parameter Processing . . . . . . . . . . . . 9 | |||
| 2.2.4. "p": Parameter Prefix Match Modifier . . . . . . . . . 6 | 2.3. Key Parameters . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 2.2.5. "pr": Parameter Range Modifier . . . . . . . . . . . . 7 | 2.3.1. div . . . . . . . . . . . . . . . . . . . . . . . . . 9 | |||
| 2.2.6. "c": Case Sensitivity Flag . . . . . . . . . . . . . . 8 | 2.3.2. partition . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 2.2.7. "n": Not Flag . . . . . . . . . . . . . . . . . . . . 8 | 2.3.3. match . . . . . . . . . . . . . . . . . . . . . . . . 11 | |||
| 2.3. Examples . . . . . . . . . . . . . . . . . . . . . . . . . 8 | 2.3.4. substr . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 2.4. Relationship to Vary . . . . . . . . . . . . . . . . . . . 9 | 2.3.5. param . . . . . . . . . . . . . . . . . . . . . . . . 13 | |||
| 3. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 | 3. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 4. Security Considerations . . . . . . . . . . . . . . . . . . . 9 | 3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 5. Normative References . . . . . . . . . . . . . . . . . . . . . 9 | 3.2. Registrations . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 10 | 4. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | |||
| 5. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 | ||||
| 5.1. Normative References . . . . . . . . . . . . . . . . . . 16 | ||||
| 5.2. Informative References . . . . . . . . . . . . . . . . . 16 | ||||
| Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 17 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 17 | ||||
| 1. Introduction | 1. Introduction | |||
| In HTTP caching [I-D.ietf-httpbis-p6-cache], the Vary response header | In HTTP caching [RFC7234], the Vary response header field effectively | |||
| field effectively modifies the key used to store and access a | modifies the key used to store and access a response to include | |||
| response to include information from the request's headers. This | information from the request's headers. This "secondary cache key" | |||
| allows proactive content negotiation [I-D.ietf-httpbis-p2-semantics] | allows proactive content negotiation [RFC7231] to work with caches. | |||
| to work with caches. | ||||
| However, Vary's operation is coarse-grained; although caches are | Vary's operation is generic; it works well when caches understand the | |||
| allowed to normalise the values of headers based upon their | semantics of the selecting headers. For example, the Accept-Language | |||
| semantics, doing so requires the cache to understand those semantics, | request header field has a well-defined syntax for expressing the | |||
| and is still quite limited. | client's preferences; a cache that understands this header field can | |||
| select the appropriate response (based upon its Content-Language | ||||
| header field) and serve it to a client, without any knowledge of the | ||||
| underlying resource. | ||||
| For example, if a response is cached with the response header field: | Vary does not work as well when the criteria for selecting a response | |||
| are specific to the resource. For example, if the nature of the | ||||
| response depends upon the presence or absence of a particular Cookie | ||||
| ([RFC6265]) in a request, Vary doesn't have a mechanism to offer | ||||
| enough fine-grained, resource-specific information to aid a cache's | ||||
| selection of the appropriate response. | ||||
| Vary: Accept-Encoding | This document defines a new response header field, "Key", that allows | |||
| resources to describe the secondary cache key in a fine-grained, | ||||
| resource-specific manner, leading to improved cache efficiency when | ||||
| responses depend upon such headers. | ||||
| and and its associated request is: | 1.1. Examples | |||
| Accept-Encoding: gzip | For example, this response header field: | |||
| then a subsequent request with the following header is (in a strict | Key: cookie;param=_sess;param=ID | |||
| reading of HTTP) not a match, resulting in a cache miss: | ||||
| Accept-Encoding: identity, gzip | indicates that the selected response depends upon the "_sess" and | |||
| "ID" cookie values. | ||||
| This document defines a new response header field, "Key", that allows | This Key: | |||
| servers to describe the cache key in a much more fine-grained manner, | ||||
| leading to improved cache efficiency. | ||||
| 1.1. Notational Conventions | Key: user-agent;substr=MSIE | |||
| indicates that there are two possible secondary cache keys for this | ||||
| resource; one for requests whose User-Agent header field contains | ||||
| "MSIE", and another for those that don't. | ||||
| A more complex example: | ||||
| Key: user-agent;substr=MSIE;Substr="mobile", Cookie;param="ID" | ||||
| indicates that the selected response depends on the presence of two | ||||
| strings in the User-Agent request header field, as well as the value | ||||
| of the "ID" cookie request header field. | ||||
| 1.2. Notational Conventions | ||||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", | |||
| "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this | |||
| document are to be interpreted as described in [RFC2119]. | document are to be interpreted as described in [RFC2119]. | |||
| This document uses the Augmented Backus-Naur Form (ABNF) notation of | This document uses the Augmented Backus-Naur Form (ABNF) notation of | |||
| [RFC5234] with the list rule extension defined in | [RFC5234] (including the DQUOTE rule), and the list rule extension | |||
| [I-D.ietf-httpbis-p1-messaging], Appendix B. It includes by | defined in [RFC7230], Section 7. It includes by reference the field- | |||
| reference the OWS, field-name and quoted-string rules from that | name, quoted-string and quoted-pair rules from that document, and the | |||
| document, and the parameter and attribute rules from | parameter rule from [RFC7231]. | |||
| [I-D.ietf-httpbis-p2-semantics]. | ||||
| 2. The "Key" Response Header Field | 2. The "Key" Response Header Field | |||
| The "Key" response header field describes the request attributes that | The "Key" response header field describes the portions of the request | |||
| the server has used to select the current representation. | that the resource currently uses to select representations. | |||
| As such, its semantics are similar to the "Vary" response header | As such, its semantics are similar to the "Vary" response header | |||
| field, but it allows more fine-grained description, using "key | field, but it allows more fine-grained description, using "key | |||
| modifiers". | parameters". | |||
| Caches can use this information as part of determining whether a | Caches can use this information as part of determining whether a | |||
| stored response can be used to satisfy a given request. When a cache | stored response can be used to satisfy a given request. When a cache | |||
| fully implements this mechanism, it MAY ignore the Vary response | knows and fully understands the Key header field for a given | |||
| header field. | resource, it MAY ignore the Vary response header field in any stored | |||
| responses for it. | ||||
| Additionally, user agents can use this information to discover if | Additionally, user agents can use Key to discover if additional | |||
| additional request header fields might influence the resulting | request header fields might influence the resource's selection of | |||
| response. | responses. | |||
| The Key field-value is a comma-delimited list of selecting header | The Key field-value is a comma-delimited list of selecting header | |||
| fields (similar to Vary), with zero to many modifiers to each, | fields (similar to Vary), with zero to many parameters each, | |||
| delimited by semicolons. Whitespace is not allowed in the field- | delimited by semicolons. Whitespace is not allowed in the field- | |||
| value between each field-name and its parameter set. | value between each field-name and its parameter set. | |||
| Key = 1#field-name *( ";" parameter ) | Key = 1#field-name *( ";" parameter ) | |||
| The following header fields therefore have identical semantics: | Note that, as per [RFC7231], parameter names are case-insensitive, | |||
| and parameter values can be double-quoted strings (potentially with | ||||
| ""-escaped characters inside). | ||||
| Vary: Accept-Encoding, Accept-Language | The following header fields have the same effect: | |||
| Key: Accept-Encoding, Accept-Language | ||||
| However, Key's use of modifiers allows: | Vary: Accept-Encoding, Cookie | |||
| Key: Accept-Encoding, Cookie | ||||
| Key: Accept-Encoding;w="gzip", Accept-Language;b="fr" | However, Key's use of parameters allows: | |||
| to indicate that the response it occurs in is allowed to be reused | Key: Accept-Encoding, Cookie;param=foo | |||
| for requests that contain the token "gzip" (in any case) in the | ||||
| Accept-Encoding header field and an Accept-Language header field | ||||
| value that starts with "fr" (in any case). | ||||
| Note that both the field-name and modifier names themselves are case | to indicate that the secondary cache key depends upon the Accept- | |||
| insensitive. | Encoding header field and the "foo" Cookie. | |||
| 2.1. Header Matching | One important difference between Vary and Key is how they are | |||
| applied. Vary is specified to be specific to the response it occurs | ||||
| within, whereas Key is specific to the resource (as identified by the | ||||
| request URL) it is associated with. The most recent key you receive | ||||
| for a given resource is applicable to all responses from that | ||||
| resource. | ||||
| This difference allows more efficient implementation (and reflects | ||||
| practices that many caches use in implementing Vary already). | ||||
| This specification defines a selection of Key parameters to address | ||||
| common use cases such as selection upon individual Cookie header | ||||
| fields, User-Agent substrings and numerical ranges. Future | ||||
| parameters may define further capabilities. | ||||
| 2.1. Relationship with Vary | ||||
| Origin servers SHOULD still send Vary when using Key, to ensure | ||||
| backwards compatibility. | ||||
| For example, | ||||
| Vary: User-Agent | ||||
| Key: User-Agent;substr="mozilla" | ||||
| Note that, in some cases, it may be better to explicitly use "Vary: | ||||
| *" if clients and caches don't have any practical way to use the Vary | ||||
| header field's value. For example, | ||||
| Vary: * | ||||
| Key: Cookie;param="ID" | ||||
| Except when Vary: * is used, the set of headers used in Key SHOULD | ||||
| reflect the same request header fields as Vary does, even if they | ||||
| don't have parameters. For example, | ||||
| Vary: Accept-Encoding, User-Agent | ||||
| Key: Accept-Encoding, User-Agent;substr="mozilla" | ||||
| Here, Accept-Encoding is included in Key without parameters; caches | ||||
| MAY treat these as they do values in the Vary header, relying upon | ||||
| knowledge of their generic semantics to select an appropriate | ||||
| response. | ||||
| 2.2. Calculating a Secondary Cache Key | ||||
| When used by a cache to determine whether a stored response can be | When used by a cache to determine whether a stored response can be | |||
| used to satisfy a presented request, each field-name identifies a | used to satisfy a presented request, each field-name in Key | |||
| potential request header, just as with the Vary response header | identifies a potential request header, just as with the Vary response | |||
| field. | header field. | |||
| However, each of these can have zero to many "key modifiers" that | However, each of these can have zero to many key parameters that | |||
| change how the response selection process (as defined in | change how the response selection process (as defined in [RFC7234], | |||
| [I-D.ietf-httpbis-p6-cache], Section 4.3)) works. | Section 4.3)) works. | |||
| In particular, a cache that implements the Key header field MUST NOT | In particular, when a cache fully implements this specification, it | |||
| use a stored response unless all of the selecting header fields | creates a secondary cache key for every request by following the | |||
| nominated by the Key header field match in both the original request | instructions in the Key header field, ignoring the Vary header for | |||
| (i.e., that associated with the stored response) and the presented | this purpose. | |||
| request. | ||||
| Modifiers operate on a list of zero to many field-values. This list | Then, when a new request is presented, the secondary cache key | |||
| is constructed by: | generated for that request can be compared to the stored one to find | |||
| the appropriate response, to determine if it can be selected. | ||||
| 1. Starting with the field-values of all header fields that have the | To generate a secondary cache key for a given request (including that | |||
| given field-name. | which is stored with a response) using Key, the following steps are | |||
| 2. Splitting each field-value on commas, excluding any that occur | taken: | |||
| inside of a quoted-string production. | ||||
| 3. Flattening the list of lists into a single list that represents | ||||
| the individual header field-values. | ||||
| 4. Case-normalising each value in both lists to lowercase. | ||||
| 5. Trimming any OWS from the start and end of the field-values. | ||||
| For example, given the set of headers: | 1. If the Key header field is not present on the most recent | |||
| cacheable (as per [RFC7234], Section 3)) response seen for the | ||||
| resource, abort this algorithm (i.e., fall back to using Vary to | ||||
| determine the secondary cache key). | ||||
| Foo: 1 | 2. Let "key_value" be the most recently seen Key header field value | |||
| Bar: z | for the resource, as the result of Creating a Header Field Value | |||
| Foo: 2, a="b,c" | (Section 2.2.1). | |||
| A modifier for "Foo" would operate on the list of presented values | 3. Let "secondary_key" be an empty string. | |||
| '1', '2', 'a="b,c"'. | ||||
| Note that step 2 of this algorithm optimistically assumes that | 4. Create "key_list" by splitting "key_value" on "," characters. | |||
| double-quotes in a header field value denote the use of the quoted- | ||||
| string as defined by [I-D.ietf-httpbis-p1-messaging]; the cache does | ||||
| not need to "understand" the specific header field. | ||||
| Once the appropriate header fields from both the original request and | 5. For "key_item" in "key_list": | |||
| the stored request are processed in this manner, the result is two | ||||
| (possibly empty) lists of values for each specified header field. | ||||
| The key modifiers (as specified in the Key header field) are then | 1. Remove any leading and trailing WSP from "key_item". | |||
| applied to the lists in the order they appear in Key (left to right). | ||||
| If any modifier does not return a match (as per its definition), the | ||||
| headers are said not to match. If all of the modifiers return a | ||||
| match, the headers are said to match. | ||||
| Note that some types of modifiers are said to always match; they can | 2. If "key_item" does not contain a ";" character, fail | |||
| be used to alter the input lists, or to alter the semantics of | parameter processing (Section 2.2.2) and skip to the next | |||
| subsequent matches. | "key_item". | |||
| Unrecognised modifiers MUST result in a failure to match. | 3. Let "field_name" be the string before the first ";" character | |||
| in "key_item". | ||||
| 2.2. Key Modifiers | 4. Let "field_value" be the result of Creating a Header Field | |||
| Value (Section 2.2.1) with "field_name" as the | ||||
| "target_field_name" and the request header list as | ||||
| "header_list". | ||||
| This document defines the following key modifiers: | 5. Let "parameters" be the string after the first ";" character | |||
| in "key_item". | ||||
| 2.2.1. "w": Word Match Modifier | 6. Create "param_list" by splitting "parameters" on ";" | |||
| characters, excepting ";" characters within quoted strings, | ||||
| as per [RFC7230] Section 3.2.6. | ||||
| The "w" modifier matches if the parameter value (after unquoting) | 7. For "parameter" in "param_list": | |||
| matches (character-for-character) at least one whole member in both | ||||
| lists. | ||||
| 2.2.2. "s": Substring Match Modifier | 1. If "parameter" does not contain a "=", fail parameter | |||
| processing (Section 2.2.2) and skip to the next | ||||
| "key_item". | ||||
| The "s" modifier matches if the parameter value (after unquoting) is | 2. Let "param_name" be the string before the first "=" | |||
| contained as a sequence of characters in at least one member of both | character in "parameter", case-normalized to lowercase. | |||
| lists. | ||||
| 2.2.3. "b": Beginning Substring Match Modifier | 3. If "param_name" does not identify a Key parameter | |||
| processing algorithm that is implemented, fail parameter | ||||
| processing (Section 2.2.2) and skip to the next | ||||
| "key_item". | ||||
| The "b" modifier matches if both lists contain at least one member | 4. Let "param_value" be the string after the first "=" | |||
| that begins with the same sequence of characters as the parameter | character in "parameter". | |||
| value (after unquoting). | ||||
| 2.2.4. "p": Parameter Prefix Match Modifier | 5. If the first and last characters of "param_value" are | |||
| both DQUOTE: | ||||
| The "p" modifier matches if both lists contain at least one member | 1. Remove the first and last characters of | |||
| whose sequence of characters up to (but not including) the first | "param_value". | |||
| semi-colon (";") matches the parameter value, case insensitively, | ||||
| after whitespace is removed. | ||||
| For example, given the key: | 2. Replace quoted-pairs within "param_value" with the | |||
| octet following the backslash, as per [RFC7230] | ||||
| Section 3.2.6. | ||||
| Key: Accept;p="text/html" | 6. If "param_value" does not conform to the syntax defined | |||
| for it by the parameter definition, fail parameter | ||||
| processing Section 2.2.2 and skip to the next "key_item". | ||||
| then each of the following header fields is a match: | 7. Run the identified processing algorithm on "field_value" | |||
| with the "param_value", and append the result to | ||||
| "secondary_key". If parameter processing fails | ||||
| Section 2.2.2, skip to the next "key_item". | ||||
| Accept: text/html | 8. Append a separator character (e.g., NULL) to | |||
| Accept: text/HTML; q=0.5 | "secondary_key". | |||
| Accept: text/html;q=0.1 | ||||
| Accept: text/html; foo="bar" | ||||
| but does not match: | 6. Return "secondary_key". | |||
| Accept: text/plain | Note that this specification does not require that exact algorithm to | |||
| Accept: text/plain; type="text/html" | be implemented. However, implementations' observable behavior MUST | |||
| be identical to running it. This includes parameter processing | ||||
| algorithms; implementations MAY use different internal artefacts for | ||||
| secondary cache keys, as long as the results are the same. | ||||
| 2.2.5. "pr": Parameter Range Modifier | Likewise, while the secondary cache key associated with both stored | |||
| and presented requests is required to use the most recently seen Key | ||||
| header field for the resource in question, this can be achieved using | ||||
| a variety of implementation strategies, including (but not limited | ||||
| to): | ||||
| The "pr" modifier matches if both lists contain at least one member | o Generating a new secondary cache key for every stored response | |||
| with the indicated attribute, and its value falls within a specified | associated with the resource upon each request. | |||
| numeric range. | ||||
| This modifier assumes that list members have a "attribute=value" | o Caching the secondary cache key with the stored request/response | |||
| format (following the parameter rule in | pair and re-generating it when the Key header field is observed to | |||
| [I-D.ietf-httpbis-p2-semantics]). | change. | |||
| In the modifier, the indicated attribute is conveyed using the | o Caching the secondary cache key with the stored response and | |||
| characters before the colon character in the parameter value; the | invalidating the stored response(s) when the Key header field is | |||
| range is that afterwards. | observed to change. | |||
| Formally, the syntax is: | 2.2.1. Creating a Header Field Value | |||
| parameter_range = attribute ":" "[" [ range_num ] ":" [ range_num ] "]" | Given a header field name "target_field_name" and "header_list", a | |||
| range_num = [ "-" ] 1*DIGIT | list of ("field_name", "field_value") tuples: | |||
| For example, given the key: | 1. Let "target_field_values" be an empty list. | |||
| Key: Foo;pr=bar[20:30] | 2. For each ("field_name", "field_value") tuple in "header_list": | |||
| the indicated attribute is 'bar', and the range is from 20 to 30 | 1. If "field_name" does not match "target_field_name", skip to | |||
| (inclusive). Thus, each of the following headers would match: | the next tuple. | |||
| Foo: bar=20 | 2. Strip leading and trailing WSP from "field_value" and append | |||
| Foo: BAr=25 | it to "target_field_values". | |||
| Foo: bar=30, baz=100 | ||||
| Foo: baz=10, bar=50, bar=10 | ||||
| whilst the following would not: | 3. If "target_field_values" is empty, return an empty string. | |||
| Foo: bar=19 | 4. Return the concatenation of "target_field_values", separating | |||
| Foo: bar= | each with "," characters. | |||
| Foo: bar=-30 | ||||
| Foo: bar= 25 | ||||
| Foo: thing=100 | ||||
| Foo: bar | ||||
| Note that the indicated attribute is always case-insensitive. | 2.2.2. Failing Parameter Processing | |||
| The range can be incomplete on either side; for example, given: | In some cases, a key parameter cannot determine a secondary cache key | |||
| corresponding to its nominated header field value. When this | ||||
| happens, Key processing needs to fail safely, so that the correct | ||||
| behavior is observed. | ||||
| Key: Foo;pr=bar[:30] | When this happens, implementations MUST either behave as if the Key | |||
| header was not present, or assure that the nominated header fields | ||||
| being compared match, as per [RFC7234], Section 4.1. | ||||
| each of the following headers would match: | 2.3. Key Parameters | |||
| Foo: bar=20 | A Key parameter associates a name with a specific processing | |||
| Foo: bar=1, baz=wibble | algorithm that takes two inputs; a HTTP header value "header_value" | |||
| Foo: bar=0 | (as described in Section 2.2.1), and "parameter_value", a string that | |||
| Foo: bar=-500 | indicates how the identified header should be processed. | |||
| 2.2.6. "c": Case Sensitivity Flag | The set of key parameters (and their associated processing | |||
| algorithms) is extensible; see Section 3. This document defines the | ||||
| following key parameters: | ||||
| The "c" modifier always matches, and has the side effect of reverting | 2.3.1. div | |||
| the case normalisation of the header lists (see #4 in the list | ||||
| above), so that subsequent matches become case sensitive. | ||||
| 2.2.7. "n": Not Flag | The "div" parameter normalizes positive integer header values into | |||
| groups by dividing them by a configured value. | ||||
| The "n" modifier always matches, and has the side effect of modifying | Its value's syntax is: | |||
| the semantics of subsequent modifiers (i.e., the match modifiers to | ||||
| its right, lexically) so that they will be considered to match if | ||||
| they do not, and likewise they will be considered not to match if | ||||
| they do. | ||||
| For example, given a response with: | div = 1*DIGIT | |||
| Key: Foo;w="a";n;w="b" | To process a set of header fields against a div parameter, follow | |||
| these steps (or their equivalent): | ||||
| then the presented header: | 1. If "parameter_value" is "0", fail parameter processing | |||
| Section 2.2.2. | ||||
| Foo: a, c | 2. If "header_value" is the empty string, return "none". | |||
| would match, while | 3. If "header_value" contains a ",", remove it and all subsequent | |||
| characters. | ||||
| Foo: a, b | 4. Remove all WSP characters from "header_value". | |||
| would not (because it contains "b"). | 5. If "header_value" does not match the div ABNF rule, fail | |||
| parameter processing (Section 2.2.2). | ||||
| 2.3. Examples | 6. Return the quotient of "header_value" / "parameter_value" | |||
| (omitting the modulus). | ||||
| For example, this response header field: | For example, the Key: | |||
| Key: cookie;w="_sess=fhd378";c;w="ID=\"Roy\"", | Key: Bar;div=5 | |||
| Accept-Encoding;w="gzip" | ||||
| would allow the cache to reuse the response it occurs in if the | indicates that the "Bar" header's field value should be partitioned | |||
| presented request contains: | into groups of 5. Thus, the following field values would be | |||
| considered the same (because, divided by 5, they all result in 1): | ||||
| o A Cookie header containing both ID="Roy" (in that case) and | Bar: 1 | |||
| _sess=fhd378 (evaluated case insensitively), and | Bar: 3 , 42 | |||
| o An Accept-Encoding header containing the token "gzip" (evaluated | Bar: 4, 1 | |||
| case insensitively). | ||||
| Less convoluted examples include matching any request with a User- | whereas these would be considered to be in a different group | |||
| Agent field value containing "MSIE" in any combination of case: | (because, divided by 5, they all result in 2); | |||
| Key: user-agent;s="MSIE" | Bar: 12 | |||
| Bar: 10 | ||||
| Bar: 14, 1 | ||||
| And an Accept-Language field value for French: | 2.3.2. partition | |||
| Key: accept-language;b="fr" | The "partition" parameter normalizes positive numeric header values | |||
| into pre-defined segments. | ||||
| 2.4. Relationship to Vary | Its value's syntax is: | |||
| Origin servers SHOULD still send Vary as normal with Key, to | partition = [ segment ] *( ":" [ segment ] ) | |||
| accommodate implementations that do not (yet) understand it. For | segment = [ 0*DIGIT "." ] 1*DIGIT | |||
| example, | ||||
| Vary: Accept-Encoding | To process a set of header fields against a partition parameter, | |||
| Key: Accept-Encoding;w="gzip" | follow these steps (or their equivalent): | |||
| 1. If "header_value" is the empty string, return "none". | ||||
| 2. If "header_value" contains a ",", remove it and all subsequent | ||||
| characters. | ||||
| 3. Remove all WSP characters from "header_value". | ||||
| 4. If "header_value" does not match the segment ABNF rule, fail | ||||
| parameter processing (Section 2.2.2). | ||||
| 5. Let "segment_id" be 0. | ||||
| 6. Create a list "segment_list" by splitting "parameter_value" on | ||||
| ":" characters. | ||||
| 7. For each "segment_value" in "segment_list": | ||||
| 1. If "header_value" is less than "segment_value" when they are | ||||
| numerically compared, skip to step 7. | ||||
| 2. Increment "segment_id" by 1. | ||||
| 8. Return "segment_id". | ||||
| For example, the Key: | ||||
| Key: Foo;partition=20:30:40 | ||||
| indicates that the "Foo" header's field value should be divided into | ||||
| four segments: | ||||
| o less than 20 | ||||
| o 20 to less than 30 | ||||
| o 30 to less than 40 | ||||
| o forty or greater | ||||
| Thus, the following headers would all be normalized to the first | ||||
| segment: | ||||
| Foo: 1 | ||||
| Foo: 0 | ||||
| Foo: 4, 54 | ||||
| Foo: 19.9 | ||||
| whereas the following would fall into the second segment: | ||||
| Foo: 20 | ||||
| Foo: 29.999 | ||||
| Foo: 24 , 10 | ||||
| 2.3.3. match | ||||
| The "match" parameter is used to determine if an exact value occurs | ||||
| in a list of header values. It is case-sensitive. | ||||
| Its value's syntax is: | ||||
| match = ( token / quoted-string ) | ||||
| To process a set of header fields against a match parameter, follow | ||||
| these steps (or their equivalent): | ||||
| 1. If "header_value" is the empty string, return "none". | ||||
| 2. Create "header_list" by splitting "header_value" on "," | ||||
| characters. | ||||
| 3. For each "header_item" in "header_list": | ||||
| 1. Remove leading and trailing WSP characters in "header_item". | ||||
| 2. If the value of "header_item" is character-for-character | ||||
| identical to "parameter_value", return "1". | ||||
| 4. Return "0". | ||||
| For example, the Key: | ||||
| Key: Baz;match="charlie" | ||||
| Would return "1" for the following header field values: | ||||
| Baz: charlie | ||||
| Baz: foo, charlie | ||||
| Baz: bar, charlie , abc | ||||
| and "0" for these: | ||||
| Baz: theodore | ||||
| Baz: joe, sam | ||||
| Baz: "charlie" | ||||
| Baz: Charlie | ||||
| Baz: cha rlie | ||||
| Baz: charlie2 | ||||
| 2.3.4. substr | ||||
| The "substr" parameter is used to determine if a value occurs as a | ||||
| substring of an item in a list of header values. It is case- | ||||
| sensitive. | ||||
| Its value's syntax is: | ||||
| substr = ( token / quoted-string ) | ||||
| To process a set of header fields against a substr parameter, follow | ||||
| these steps (or their equivalent): | ||||
| 1. If "header_value" is the empty string, return "none". | ||||
| 2. Create "header_list" by splitting "header_value" on "," | ||||
| characters. | ||||
| 3. For each "header_item" in "header_list": | ||||
| 1. Remove leading and trailing WSP characters in "header_item". | ||||
| 2. If the value of "parameter_value" is character-for-character | ||||
| present as a substring of "header_value", return "1". | ||||
| 4. Return "0". | ||||
| For example, the Key: | ||||
| Key: Abc;substr=bennet | ||||
| Would return "1" for the following header field values: | ||||
| Abc: bennet | ||||
| Abc: foo, bennet | ||||
| Abc: abennet00 | ||||
| Abc: bar, 99bennet , abc | ||||
| Abc: "bennet" | ||||
| and "0" for these: | ||||
| Abc: theodore | ||||
| Abc: joe, sam | ||||
| Abc: Bennet | ||||
| Abc: Ben net | ||||
| 2.3.5. param | ||||
| The "param" parameter considers the request header field as a list of | ||||
| key=value parameters, and uses the nominated key's value as the | ||||
| secondary cache key. | ||||
| Its value's syntax is: | ||||
| param = ( token / quoted-string ) | ||||
| To process a list of header fields against a param parameter, follow | ||||
| these steps (or their equivalent): | ||||
| 1. Let "header_list" be an empty list. | ||||
| 2. Create "header_list_tmp1" by splitting header_value on "," | ||||
| characters. | ||||
| 3. For each "header_item_tmp1" in "header_list_tmp1": | ||||
| 1. Create "header_list_tmp2" by splitting "header_item_tmp1" on | ||||
| ";" characters. | ||||
| 2. For each "header_item_tmp2" in "header_list_tmp2": | ||||
| 1. Remove leading and trailing WSP from "header_item_tmp2". | ||||
| 2. Append "header_item_tmp2" to header_list. | ||||
| 4. For each "header_item" in "header_list": | ||||
| 1. If the "=" character does not occur within "header_item", | ||||
| skip to the next "header_item". | ||||
| 2. Let "item_name" be the string occurring before the first "=" | ||||
| character in "header_item". | ||||
| 3. If "item_name" does not case-insensitively match | ||||
| "parameter_value", skip to the next "header_item". | ||||
| 4. Return the string occurring after the first "=" character in | ||||
| "header_item". | ||||
| 5. Return the empty string. | ||||
| Note that steps 2 and 3 accommodate semicolon-separated values, so | ||||
| that it can be used with the Cookie request header field. | ||||
| For example, the Key: | ||||
| Key: Def;param=liam | ||||
| The following headers would return the string (surrounded in single | ||||
| quotes) indicated: | ||||
| Def: liam=123 // '123' | ||||
| Def: mno=456 // '' | ||||
| Def: // '' | ||||
| Def: abc=123; liam=890 // '890' | ||||
| Def: liam="678" // '"678"' | ||||
| 3. IANA Considerations | 3. IANA Considerations | |||
| TBD | This specification defines the HTTP Key Parameter Registry, | |||
| maintained at http://www.iana.org/assignments/http-parameters/http- | ||||
| parameters.xhtml#key . | ||||
| 3.1. Procedure | ||||
| Key Parameter registrations MUST include the following fields: | ||||
| o Parameter Name: [name] | ||||
| o Reference: [Pointer to specification text] | ||||
| Values to be added to this namespace require IETF Review (see | ||||
| Section 4.1 of [RFC5226]) and MUST conform to the purpose of content | ||||
| coding defined in this section. | ||||
| 3.2. Registrations | ||||
| This specification makes the following entries in the HTTP Key | ||||
| Parameter Registry: | ||||
| +----------------+---------------+ | ||||
| | Parameter Name | Reference | | ||||
| +----------------+---------------+ | ||||
| | div | Section 2.3.1 | | ||||
| | partition | Section 2.3.2 | | ||||
| | match | Section 2.3.3 | | ||||
| | substr | Section 2.3.4 | | ||||
| | param | Section 2.3.5 | | ||||
| +----------------+---------------+ | ||||
| 4. Security Considerations | 4. Security Considerations | |||
| TBD | Because Key is an alternative to Vary, it is possible for caches to | |||
| behave differently based upon whether they implement Key. Likewise, | ||||
| because support for any one Key parameter is not required, it is | ||||
| possible for different implementations of Key to behave differently. | ||||
| In both cases, an attacker might be able to exploit these | ||||
| differences. | ||||
| 5. Normative References | This risk is mitigated by the requirement to fall back to Vary when | |||
| unsupported parameters are encountered, coupled with the requirement | ||||
| that servers that use Key also include a relevant Vary header. | ||||
| [I-D.ietf-httpbis-p1-messaging] | An attacker with the ability to inject response headers might be able | |||
| Fielding, R. and J. Reschke, "Hypertext Transfer Protocol | to perform a cache poisoning attack that tailors a response to a | |||
| (HTTP/1.1): Message Syntax and Routing", | specific user (e.g., by Keying to a Cookie that's specific to them). | |||
| draft-ietf-httpbis-p1-messaging-21 (work in progress), | While the attack is still possible without Key, the ability to tailor | |||
| October 2012. | is new. | |||
| [I-D.ietf-httpbis-p2-semantics] | When implemented, Key might result in a larger number of stored | |||
| Fielding, R. and J. Reschke, "Hypertext Transfer Protocol | responses for a given resource in caches; this, in turn, might be | |||
| (HTTP/1.1): Semantics and Content", | used to create an attack upon the cache itself. Good cache | |||
| draft-ietf-httpbis-p2-semantics-21 (work in progress), | replacement algorithms and denial of service monitoring in cache | |||
| October 2012. | implementations are reasonable mitigations against this risk. | |||
| [I-D.ietf-httpbis-p6-cache] | 5. References | |||
| Fielding, R., Nottingham, M., and J. Reschke, "Hypertext | ||||
| Transfer Protocol (HTTP/1.1): Caching", | 5.1. Normative References | |||
| draft-ietf-httpbis-p6-cache-21 (work in progress), | ||||
| October 2012. | ||||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | |||
| Requirement Levels", BCP 14, RFC 2119, March 1997. | Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/ | |||
| RFC2119, March 1997, | ||||
| <http://www.rfc-editor.org/info/rfc2119>. | ||||
| [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax | [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | |||
| Specifications: ABNF", STD 68, RFC 5234, January 2008. | Specifications: ABNF", STD 68, RFC 5234, DOI 10.17487/ | |||
| RFC5234, January 2008, | ||||
| <http://www.rfc-editor.org/info/rfc5234>. | ||||
| [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | ||||
| Protocol (HTTP/1.1): Message Syntax and Routing", RFC | ||||
| 7230, DOI 10.17487/RFC7230, June 2014, | ||||
| <http://www.rfc-editor.org/info/rfc7230>. | ||||
| [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer | ||||
| Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI | ||||
| 10.17487/RFC7231, June 2014, | ||||
| <http://www.rfc-editor.org/info/rfc7231>. | ||||
| [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | ||||
| Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", | ||||
| RFC 7234, DOI 10.17487/RFC7234, June 2014, | ||||
| <http://www.rfc-editor.org/info/rfc7234>. | ||||
| 5.2. Informative References | ||||
| [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, | ||||
| DOI 10.17487/RFC6265, April 2011, | ||||
| <http://www.rfc-editor.org/info/rfc6265>. | ||||
| Appendix A. Acknowledgements | ||||
| Thanks to Ilya Grigorik, Amos Jeffries and Yoav Weiss for their | ||||
| feedback. | ||||
| Authors' Addresses | Authors' Addresses | |||
| Roy T. Fielding | Roy T. Fielding | |||
| Adobe Systems Incorporated | Adobe Systems Incorporated | |||
| Email: fielding@gbiv.com | Email: fielding@gbiv.com | |||
| URI: http://roy.gbiv.com/ | URI: http://roy.gbiv.com/ | |||
| Mark Nottingham | Mark Nottingham | |||
| End of changes. 108 change blocks. | ||||
| 241 lines changed or deleted | 593 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||