| < draft-ietf-httpbis-variants-01.txt | draft-ietf-httpbis-variants-02.txt > | |||
|---|---|---|---|---|
| HTTP M. Nottingham | HTTP M. Nottingham | |||
| Internet-Draft Fastly | Internet-Draft Fastly | |||
| Updates: 7234 (if approved) May 1, 2018 | Updates: 7234 (if approved) June 5, 2018 | |||
| Intended status: Standards Track | Intended status: Standards Track | |||
| Expires: November 2, 2018 | Expires: December 7, 2018 | |||
| HTTP Representation Variants | HTTP Representation Variants | |||
| draft-ietf-httpbis-variants-01 | draft-ietf-httpbis-variants-02 | |||
| Abstract | Abstract | |||
| This specification introduces an alternative way to communicate a | This specification introduces an alternative way to communicate a | |||
| secondary cache key for a HTTP resource, using the HTTP "Variants" | secondary cache key for a HTTP resource, using the HTTP "Variants" | |||
| and "Variant-Key" response header fields. Its aim is to make HTTP | and "Variant-Key" response header fields. Its aim is to make HTTP | |||
| proactive content negotiation more cache-friendly. | proactive content negotiation more cache-friendly. | |||
| Note to Readers | Note to Readers | |||
| skipping to change at page 1, line 49 ¶ | skipping to change at page 1, line 49 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at https://datatracker.ietf.org/drafts/current/. | Drafts is at https://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on November 2, 2018. | This Internet-Draft will expire on December 7, 2018. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2018 IETF Trust and the persons identified as the | Copyright (c) 2018 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (https://trustee.ietf.org/license-info) in effect on the date of | (https://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| skipping to change at page 2, line 26 ¶ | skipping to change at page 2, line 26 ¶ | |||
| 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 . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 | 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 | |||
| 2. The "Variants" HTTP Header Field . . . . . . . . . . . . . . 5 | 2. The "Variants" HTTP Header Field . . . . . . . . . . . . . . 5 | |||
| 2.1. Relationship to Vary . . . . . . . . . . . . . . . . . . 6 | 2.1. Relationship to Vary . . . . . . . . . . . . . . . . . . 6 | |||
| 3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 6 | 3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 7 | |||
| 3.1. Generating a Variant-Key List . . . . . . . . . . . . . . 7 | 3.1. Generating a Variant-Key List . . . . . . . . . . . . . . 7 | |||
| 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 | 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.1. Compute Possible Keys . . . . . . . . . . . . . . . . . . 9 | 4.1. Compute Possible Keys . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 | 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 11 | 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 11 | |||
| 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 11 | 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 12 | |||
| 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 12 | 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 12 | |||
| 5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 12 | 5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 12 | |||
| 5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 13 | 5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 13 | |||
| 5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 13 | 5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 14 | |||
| 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 | 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 | |||
| 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | |||
| 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 | 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | 9.1. Normative References . . . . . . . . . . . . . . . . . . 16 | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 16 | 9.2. Informative References . . . . . . . . . . . . . . . . . 16 | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 16 | 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 17 | ||||
| Appendix A. Variants for Existing Content Negotiation Mechanisms 17 | Appendix A. Variants for Existing Content Negotiation Mechanisms 17 | |||
| A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 17 | A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 17 | |||
| A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 18 | A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 18 | |||
| A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 18 | A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 19 | |||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 | Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 | ||||
| 1. Introduction | 1. Introduction | |||
| HTTP proactive content negotiation ([RFC7231], Section 3.4.1) is | HTTP proactive content negotiation ([RFC7231], Section 3.4.1) is | |||
| seeing renewed interest, both for existing request headers like | seeing renewed interest, both for existing request headers like | |||
| Content-Language and for newer ones (for example, see | Content-Language and for newer ones (for example, see | |||
| [I-D.ietf-httpbis-client-hints]). | [I-D.ietf-httpbis-client-hints]). | |||
| Successfully reusing negotiated responses that have been stored in a | Successfully reusing negotiated responses that have been stored in a | |||
| HTTP cache requires establishment of a secondary cache key | HTTP cache requires establishment of a secondary cache key | |||
| skipping to change at page 3, line 36 ¶ | skipping to change at page 3, line 36 ¶ | |||
| For example, if a cache has stored the following request/response | For example, if a cache has stored the following request/response | |||
| pair: | pair: | |||
| GET /foo HTTP/1.1 | GET /foo HTTP/1.1 | |||
| Host: www.example.com | Host: www.example.com | |||
| Accept-Language: en;q=0.5, fr;q=1.0 | Accept-Language: en;q=0.5, fr;q=1.0 | |||
| HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
| Content-Type: text/html | Content-Type: text/html | |||
| Content-Language: fr | Content-Language: en | |||
| Vary: Accept-Language | Vary: Accept-Language | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| [French content] | [French content] | |||
| Provided that the cache has full knowledge of the semantics of | Provided that the cache has full knowledge of the semantics of | |||
| Accept-Language and Content-Language, it will know that a French | Accept-Language and Content-Language, it will know that an English | |||
| representation is available and might be able to infer that an | representation is available and might be able to infer that a French | |||
| English representation is not available. But, it does not know (for | representation is not available. But, it does not know (for example) | |||
| example) whether a Japanese representation is available without | whether a Japanese representation is available without making another | |||
| making another request, incurring possibly unnecessary latency. | request, incurring possibly unnecessary latency. | |||
| This specification introduces the HTTP Variants response header field | This specification introduces the HTTP Variants response header field | |||
| (Section 2) to enumerate the available variant representations on the | (Section 2) to enumerate the available variant representations on the | |||
| origin server, to provide clients and caches with enough information | origin server, to provide clients and caches with enough information | |||
| to properly satisfy requests - either by selecting a response from | to properly satisfy requests - either by selecting a response from | |||
| cache or by forwarding the request towards the origin - by following | cache or by forwarding the request towards the origin - by following | |||
| the algorithm defined in Section 4. | the algorithm defined in Section 4. | |||
| Its companion Variant-Key response header field (Section 3) indicates | Its companion Variant-Key response header field (Section 3) indicates | |||
| the applicable key(s) that the response is associated with, so that | the applicable key(s) that the response is associated with, so that | |||
| it can be reliably reused in the future. When this specification is | it can be reliably reused in the future. When this specification is | |||
| in use, the example above might become: | in use, the example above might become: | |||
| GET /foo HTTP/1.1 | GET /foo HTTP/1.1 | |||
| Host: www.example.com | Host: www.example.com | |||
| Accept-Language: en;q=0.5, fr;q=1.0 | Accept-Language: en;q=0.5, fr;q=1.0 | |||
| HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
| Content-Type: text/html | Content-Type: text/html | |||
| Content-Language: fr | Content-Language: en | |||
| Vary: Accept-Language | Vary: Accept-Language | |||
| Variants: Accept-Language;fr;de;en;jp | Variants: Accept-Language;de;en;jp | |||
| Variant-Key: fr | Variant-Key: en | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| [French content] | [French content] | |||
| Proactive content negotiation mechanisms that wish to be used with | Proactive content negotiation mechanisms that wish to be used with | |||
| Variants need to define how to do so explicitly; see Section 6. As a | Variants need to define how to do so explicitly; see Section 6. As a | |||
| result, it is best suited for negotiation over request headers that | result, it is best suited for negotiation over request headers that | |||
| are well-understood. | are well-understood. | |||
| Variants also works best when content negotiation takes place over a | Variants also works best when content negotiation takes place over a | |||
| skipping to change at page 5, line 8 ¶ | skipping to change at page 5, line 12 ¶ | |||
| 14 [RFC2119] [RFC8174] when, and only when, they appear in all | 14 [RFC2119] [RFC8174] when, and only when, they appear in all | |||
| capitals, as shown here. | capitals, as shown here. | |||
| This specification uses the Augmented Backus-Naur Form (ABNF) | This specification uses the Augmented Backus-Naur Form (ABNF) | |||
| notation of [RFC5234] with a list extension, defined in Section 7 of | notation of [RFC5234] with a list extension, defined in Section 7 of | |||
| [RFC7230], that allows for compact definition of comma-separated | [RFC7230], that allows for compact definition of comma-separated | |||
| lists using a '#' operator (similar to how the '*' operator indicates | lists using a '#' operator (similar to how the '*' operator indicates | |||
| repetition). | repetition). | |||
| Additionally, it uses the "field-name", "OWS" and "token" rules from | Additionally, it uses the "field-name", "OWS" and "token" rules from | |||
| [RFC7230]. | [RFC7230], and "type", "subtype", "content-coding" and "language- | |||
| range" from [RFC7231]. | ||||
| 2. The "Variants" HTTP Header Field | 2. The "Variants" HTTP Header Field | |||
| The Variants HTTP response header field indicates what | The Variants HTTP response header field indicates what | |||
| representations are available for a given resource at the time that | representations are available for a given resource at the time that | |||
| the response is produced, by enumerating the request header fields | the response is produced, by enumerating the request header fields | |||
| that it varies on, along with the values that are available for each. | that it varies on, along with the values that are available for each. | |||
| Variants = 1#variant-item | Variants = 1#variant-item | |||
| variant-item = field-name *( OWS ";" OWS available-value ) | variant-item = field-name *( OWS ";" OWS available-value ) | |||
| available-value = token | available-value = token | |||
| / "/" / "?" / "\" / "[" / "]" | ||||
| / ":" / "@" / "(" / ")" | ||||
| Each "variant-item" indicates a request header field that carries a | Each "variant-item" indicates a request header field that carries a | |||
| value that clients might proactively negotiate for; each parameter on | value that clients might proactively negotiate for; each parameter on | |||
| it indicates a value for which there is an available representation | it indicates a value for which there is an available representation | |||
| on the origin server. | on the origin server. | |||
| So, given this example header field: | So, given this example header field: | |||
| Variants: Accept-Encoding;gzip | Variants: Accept-Encoding;gzip | |||
| skipping to change at page 6, line 30 ¶ | skipping to change at page 6, line 35 ¶ | |||
| cacheable (as per [RFC7234], Section 3) responses for a resource, | cacheable (as per [RFC7234], Section 3) responses for a resource, | |||
| since its absence will trigger caches to fall back to Vary | since its absence will trigger caches to fall back to Vary | |||
| processing. | processing. | |||
| Likewise, servers MUST send the Variant-Key response header field | Likewise, servers MUST send the Variant-Key response header field | |||
| when sending Variants, since its absence means that the stored | when sending Variants, since its absence means that the stored | |||
| response will not be reused when this specification is implemented. | response will not be reused when this specification is implemented. | |||
| 2.1. Relationship to Vary | 2.1. Relationship to Vary | |||
| Caches that implement this specification SHOULD ignore request header | This specification updates [RFC7234] to allow caches that implement | |||
| fields in the Vary header for the purposes of secondary cache key | it to ignore request header fields in the Vary header for the | |||
| calculation ([RFC7234], Section 4.1) when their semantics are | purposes of secondary cache key calculation ([RFC7234], Section 4.1) | |||
| implemented as per this specification and their corresponding | when their semantics are implemented as per this specification and | |||
| response header field is listed in Variants. | their corresponding response header field is listed in Variants. | |||
| If any member of the Vary header does not have a corresponding | If any member of the Vary header does not have a corresponding | |||
| variant that is understood by the implementation, it is still subject | variant that is understood by the implementation, it is still subject | |||
| to the requirements there. | to the requirements there. | |||
| See Section 5.1.3 for an example. | See Section 5.1.3 for an example. | |||
| In practice, implementation of Vary varies considerably. As a | In practice, implementation of Vary varies considerably. As a | |||
| result, cache efficiency might drop considerably when Variants does | result, cache efficiency might drop considerably when Variants does | |||
| not contain all of the headers referenced by Vary, because some | not contain all of the headers referenced by Vary, because some | |||
| implementations might choose to disable Variants processing when this | implementations might choose to disable Variants processing when this | |||
| is the case. | is the case. | |||
| 3. The "Variant-Key" HTTP Header Field | 3. The "Variant-Key" HTTP Header Field | |||
| The Variant-Key HTTP response header field is used to indicate the | The Variant-Key HTTP response header field is used to indicate the | |||
| values from the Variants header field that identify the | values from the Variants header field that identify the | |||
| representation it occurs within. | representation it occurs within. | |||
| Variant-Key = available-values | Variant-Key = 1#available-values | |||
| available-values = available-value *( ";" available-value ) | available-values = available-value *( ";" available-value ) | |||
| Each member of the list contains the selected available-value(s), in | Each member of the list contains the selected available-value(s), in | |||
| the same order as the variants listed in the Variants header field. | the same order as the variants listed in the Variants header field. | |||
| Therefore, Variant-Key MUST be the same length (in comma-separated | Therefore, Variant-Key MUST be the same length (in comma-separated | |||
| members) as Variants, and each member MUST correspond in position to | members) as Variants, and each member MUST correspond in position to | |||
| its companion in Variants. | its companion in Variants. | |||
| For example: | For example: | |||
| skipping to change at page 7, line 45 ¶ | skipping to change at page 8, line 5 ¶ | |||
| This highlights an important aspect of Variant-Key; it is only used | This highlights an important aspect of Variant-Key; it is only used | |||
| to indicate what request attributes are associated with the response | to indicate what request attributes are associated with the response | |||
| containing it; this is different from headers like Content-Encoding, | containing it; this is different from headers like Content-Encoding, | |||
| which indicate attributes of the response itself. | which indicate attributes of the response itself. | |||
| 3.1. Generating a Variant-Key List | 3.1. Generating a Variant-Key List | |||
| This algorithm generates a list of normalised strings from Variant- | This algorithm generates a list of normalised strings from Variant- | |||
| Key, suitable for comparison with values generated by Section 4. | Key, suitable for comparison with values generated by Section 4. | |||
| Given stored-headers, a set of headers from a stored response, a | Given stored-headers (a set of headers from a stored response), a | |||
| normalised list of variant-keys for that message can be generated by: | normalised list of variant-keys for that message can be generated by | |||
| following this algorithm: | ||||
| 1. Let variant-keys be an empty list. | 1. Let variant-keys be an empty list. | |||
| 2. Let variant-key-header be a string, the result of selecting all | 2. Let variant-key-header be a string, the result of selecting all | |||
| field-values of stored-headers whose field-name is "Variant-Key" | field-values of stored-headers whose field-name is "Variant-Key" | |||
| and joining them with a comma (","). | and joining them with a comma (","). | |||
| 3. Let value-list be the result of splitting variant-key-header on | 3. Let value-list be the result of splitting variant-key-header on | |||
| commas (","). | commas (","). | |||
| skipping to change at page 8, line 29 ¶ | skipping to change at page 8, line 39 ¶ | |||
| 4. Cache Behaviour | 4. Cache Behaviour | |||
| Caches that implement the Variants header field and the relevant | Caches that implement the Variants header field and the relevant | |||
| semantics of the field-name it contains can use that knowledge to | semantics of the field-name it contains can use that knowledge to | |||
| either select an appropriate stored representation, or forward the | either select an appropriate stored representation, or forward the | |||
| request if no appropriate representation is stored. | request if no appropriate representation is stored. | |||
| They do so by running this algorithm (or its functional equivalent) | They do so by running this algorithm (or its functional equivalent) | |||
| upon receiving a request: | upon receiving a request: | |||
| Given incoming-request, a mapping of field-names to lists of field | Given incoming-request (a mapping of field-names to lists of field | |||
| values, and stored-responses, a list of stored responses suitable for | values), and stored-responses (a list of stored responses suitable | |||
| reuse as defined in [RFC7234] Section 4, excepting the requirement to | for reuse as defined in Section 4 of [RFC7234], excepting the | |||
| calculate a secondary cache key: | requirement to calculate a secondary cache key): | |||
| 1. If stored-responses is empty, return an empty list. | 1. If stored-responses is empty, return an empty list. | |||
| 2. Order stored-responses by the "Date" header field, most recent to | 2. Order stored-responses by the "Date" header field, most recent to | |||
| least recent. | least recent. | |||
| 3. Let sorted-variants be an empty list. | 3. Let sorted-variants be an empty list. | |||
| 4. If the freshest member of stored-responses (as per [RFC7234], | 4. If the freshest member of stored-responses (as per [RFC7234], | |||
| Section 4.2) has one or more "Variants" header field(s): | Section 4.2) has one or more "Variants" header field(s): | |||
| 1. Select one member of stored-responses and let its "Variants" | 1. Select one member of stored-responses and let variants-header | |||
| header field-value(s) be variants-header. This SHOULD be the | be its "Variants" header field-value(s). This SHOULD be the | |||
| most recent response, but MAY be from an older one as long as | most recent response, but MAY be from an older one as long as | |||
| it is still fresh. | it is still fresh. | |||
| 2. For each variant in variants-header: | 2. For each variant in variants-header, parsed according to the | |||
| ABNF: | ||||
| 1. If variant's field-name corresponds to the request header | 1. If variant's field-name corresponds to the request header | |||
| field identified by a content negotiation mechanism that | field identified by a content negotiation mechanism that | |||
| the implementation supports: | the implementation supports: | |||
| 1. Let request-value be the field-value(s) associated | 1. Let request-value be the field-value(s) associated | |||
| with field-name in incoming-request. | with field-name in incoming-request. | |||
| 2. Let available-values be a list containing all | 2. Let available-values be a list containing all | |||
| available-value for variant. | available-value for variant. | |||
| skipping to change at page 9, line 39 ¶ | skipping to change at page 9, line 47 ¶ | |||
| This returns a list of strings suitable for comparing to normalised | This returns a list of strings suitable for comparing to normalised | |||
| Variant-Keys (Section 3.1) that represent possible responses on the | Variant-Keys (Section 3.1) that represent possible responses on the | |||
| server that can be used to satisfy the request, in preference order, | server that can be used to satisfy the request, in preference order, | |||
| provided that their secondary cache key (after removing the headers | provided that their secondary cache key (after removing the headers | |||
| covered by Variants) matches. Section 4.2 illustrates one way to do | covered by Variants) matches. Section 4.2 illustrates one way to do | |||
| this. | this. | |||
| 4.1. Compute Possible Keys | 4.1. Compute Possible Keys | |||
| Given key-facets, a list of lists, and key-stub, a string | This algorithm computes the cross-product of the elements of key- | |||
| representing a partial key, and possible-keys, a list: | facets. | |||
| Given key-facets (a list of lists), and key-stub (a string | ||||
| representing a partial key), and possible-keys (a list): | ||||
| 1. Let values be the first member of key-facets. | 1. Let values be the first member of key-facets. | |||
| 2. For each value in values: | 2. For each value in values: | |||
| 1. If key-stub is an empty string, let this-key be a copy of | 1. If key-stub is an empty string, let this-key be a copy of | |||
| value. | value. | |||
| 2. Otherwise: | 2. Otherwise: | |||
| skipping to change at page 10, line 15 ¶ | skipping to change at page 10, line 26 ¶ | |||
| 2. Append a comma (",") to this-key. | 2. Append a comma (",") to this-key. | |||
| 3. Append value to this-key. | 3. Append value to this-key. | |||
| 3. Let remaining-facets be a copy of all of the members of key- | 3. Let remaining-facets be a copy of all of the members of key- | |||
| facets except the first. | facets except the first. | |||
| 4. If remaining-facets is empty, append this-key to possible- | 4. If remaining-facets is empty, append this-key to possible- | |||
| keys. | keys. | |||
| 5. Otherwise, run Find Available Keys on remaining-facets, this- | 5. Otherwise, run Compute Possible Keys on remaining-facets, | |||
| key and possible-keys. | this-key and possible-keys. | |||
| 3. Return possible-keys. | 3. Return possible-keys. | |||
| 4.2. Check Vary | 4.2. Check Vary | |||
| This algorithm is an example of how an implementation can meet the | This algorithm is an example of how an implementation can meet the | |||
| requirement to apply the members of the Vary header field that are | requirement to apply the members of the Vary header field that are | |||
| not covered by Variants. | not covered by Variants. | |||
| Given a stored response, stored-response: | Given stored-response (a stored response): | |||
| 1. Let filtered-vary be the field-value(s) of stored-response's | 1. Let filtered-vary be the field-value(s) of stored-response's | |||
| "Vary" header field. | "Vary" header field. | |||
| 2. Let processed-variants be a list containing the request header | 2. Let processed-variants be a list containing the request header | |||
| fields that identify the content negotiation mechanisms supported | fields that identify the content negotiation mechanisms supported | |||
| by the implementation. | by the implementation. | |||
| 3. Remove any member of filtered-vary that is a case-insensitive | 3. Remove any member of filtered-vary that is a case-insensitive | |||
| match for a member of processed-variants. | match for a member of processed-variants. | |||
| skipping to change at page 11, line 9 ¶ | skipping to change at page 11, line 19 ¶ | |||
| Note that implementation of the Vary header field varies in practice, | Note that implementation of the Vary header field varies in practice, | |||
| and the algorithm above illustrates only one way to apply it. It is | and the algorithm above illustrates only one way to apply it. It is | |||
| equally viable to forward the request if there is a request header | equally viable to forward the request if there is a request header | |||
| listed in Vary but not Variants. | listed in Vary but not Variants. | |||
| 4.3. Example of Cache Behaviour | 4.3. Example of Cache Behaviour | |||
| For example, if the selected variants-header was: | For example, if the selected variants-header was: | |||
| Variants: Accept-Language;en;fr,de, Accept-Encoding;gzip,br | Variants: Accept-Language;en;fr,de, Accept-Encoding;gzip;br | |||
| and the request contained the headers: | and the request contained the headers: | |||
| Accept-Language: fr;q=1.0, en;q=0.1 | Accept-Language: fr;q=1.0, en;q=0.1 | |||
| Accept-Encoding: gzip | Accept-Encoding: gzip | |||
| Then the sorted-variants would be: | Then the sorted-variants would be: | |||
| [ | [ | |||
| ["fr", "en"] // prefers French, will accept English | ["fr", "en"] // prefers French, will accept English | |||
| skipping to change at page 14, line 33 ¶ | skipping to change at page 14, line 42 ¶ | |||
| 6. Defining Content Negotiation Using Variants | 6. Defining Content Negotiation Using Variants | |||
| To be usable with Variants, proactive content negotiation mechanisms | To be usable with Variants, proactive content negotiation mechanisms | |||
| need to be specified to take advantage of it. Specifically, they: | need to be specified to take advantage of it. Specifically, they: | |||
| o MUST define a request header field that advertises the clients | o MUST define a request header field that advertises the clients | |||
| preferences or capabilities, whose field-name SHOULD begin with | preferences or capabilities, whose field-name SHOULD begin with | |||
| "Accept-". | "Accept-". | |||
| o MUST define the syntax of available-values that will occur in | o MUST define the syntax of an available-value that will occur in | |||
| Variants and Variant-Key. | Variants and Variant-Key. | |||
| o MUST define an algorithm for selecting a result. It MUST return a | o MUST define an algorithm for selecting a result. It MUST return a | |||
| list of available-values that are suitable for the request, in | list of available-values that are suitable for the request, in | |||
| order of preference, given the value of the request header | order of preference, given the value of the request header | |||
| nominated above and an available-values list from the Variants | nominated above and an available-values list from the Variants | |||
| header. If the result is an empty list, it implies that the cache | header. If the result is an empty list, it implies that the cache | |||
| cannot satisfy the request. | cannot satisfy the request. | |||
| Appendix A fulfils these requirements for some existing proactive | Appendix A fulfils these requirements for some existing proactive | |||
| skipping to change at page 15, line 36 ¶ | skipping to change at page 15, line 47 ¶ | |||
| 8. Security Considerations | 8. Security Considerations | |||
| If the number or advertised characteristics of the representations | If the number or advertised characteristics of the representations | |||
| available for a resource are considered sensitive, the Variants | available for a resource are considered sensitive, the Variants | |||
| header by its nature will leak them. | header by its nature will leak them. | |||
| Note that the Variants header is not a commitment to make | Note that the Variants header is not a commitment to make | |||
| representations of a certain nature available; the runtime behaviour | representations of a certain nature available; the runtime behaviour | |||
| of the server always overrides hints like Variants. | of the server always overrides hints like Variants. | |||
| 9. Acknowledgments | 9. References | |||
| 9.1. Normative References | ||||
| This protocol is conceptually similar to, but simpler than, | ||||
| Transparent Content Negotiation [RFC2295]. Thanks to its authors for | ||||
| their inspiration. | ||||
| It is also a generalisation of a Fastly VCL feature designed by | ||||
| Rogier 'DocWilco' Mulhuijzen. | ||||
| Thanks to Hooman Beheshti for his review and input. | ||||
| 10. References | ||||
| 10.1. Normative References | ||||
| [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, | Requirement Levels", BCP 14, RFC 2119, | |||
| DOI 10.17487/RFC2119, March 1997, | DOI 10.17487/RFC2119, March 1997, | |||
| <https://www.rfc-editor.org/info/rfc2119>. | <https://www.rfc-editor.org/info/rfc2119>. | |||
| [RFC4647] Phillips, A. and M. Davis, "Matching of Language Tags", | [RFC4647] Phillips, A. and M. Davis, "Matching of Language Tags", | |||
| BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, | BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, | |||
| <https://www.rfc-editor.org/info/rfc4647>. | <https://www.rfc-editor.org/info/rfc4647>. | |||
| skipping to change at page 16, line 39 ¶ | skipping to change at page 16, line 39 ¶ | |||
| [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, | |||
| Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", | Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", | |||
| RFC 7234, DOI 10.17487/RFC7234, June 2014, | RFC 7234, DOI 10.17487/RFC7234, June 2014, | |||
| <https://www.rfc-editor.org/info/rfc7234>. | <https://www.rfc-editor.org/info/rfc7234>. | |||
| [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC | |||
| 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, | |||
| May 2017, <https://www.rfc-editor.org/info/rfc8174>. | May 2017, <https://www.rfc-editor.org/info/rfc8174>. | |||
| 10.2. Informative References | 9.2. Informative References | |||
| [I-D.ietf-httpbis-client-hints] | [I-D.ietf-httpbis-client-hints] | |||
| Grigorik, I., "HTTP Client Hints", draft-ietf-httpbis- | Grigorik, I., "HTTP Client Hints", draft-ietf-httpbis- | |||
| client-hints-05 (work in progress), January 2018. | client-hints-05 (work in progress), January 2018. | |||
| [RFC2295] Holtman, K. and A. Mutz, "Transparent Content Negotiation | [RFC2295] Holtman, K. and A. Mutz, "Transparent Content Negotiation | |||
| in HTTP", RFC 2295, DOI 10.17487/RFC2295, March 1998, | in HTTP", RFC 2295, DOI 10.17487/RFC2295, March 1998, | |||
| <https://www.rfc-editor.org/info/rfc2295>. | <https://www.rfc-editor.org/info/rfc2295>. | |||
| [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration | [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration | |||
| Procedures for Message Header Fields", BCP 90, RFC 3864, | Procedures for Message Header Fields", BCP 90, RFC 3864, | |||
| DOI 10.17487/RFC3864, September 2004, | DOI 10.17487/RFC3864, September 2004, | |||
| <https://www.rfc-editor.org/info/rfc3864>. | <https://www.rfc-editor.org/info/rfc3864>. | |||
| 10.3. URIs | 9.3. URIs | |||
| [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ | |||
| [2] https://httpwg.github.io/ | [2] https://httpwg.github.io/ | |||
| [3] https://github.com/httpwg/http-extensions/labels/variants | [3] https://github.com/httpwg/http-extensions/labels/variants | |||
| [4] https://github.com/mnot/variants-toy | [4] https://github.com/mnot/variants-toy | |||
| Appendix A. Variants for Existing Content Negotiation Mechanisms | Appendix A. Variants for Existing Content Negotiation Mechanisms | |||
| This appendix defines the required information to use existing | This appendix defines the required information to use existing | |||
| proactive content negotiation mechanisms (as defined in [RFC7231], | proactive content negotiation mechanisms (as defined in [RFC7231], | |||
| Section 5.3) with the Variants header field. | Section 5.3) with the Variants header field. | |||
| A.1. Accept | A.1. Accept | |||
| This section defines handling for Accept variants, as per [RFC7231] | This section defines variant handling for the Accept request header | |||
| Section 5.3.2. | (section 5.3.2 of [RFC7231]). | |||
| The syntax of an available-value for Accept is: | ||||
| accept-available-value = type "/" subtype | ||||
| To perform content negotiation for Accept given a request-value and | To perform content negotiation for Accept given a request-value and | |||
| available-values: | available-values: | |||
| 1. Let preferred-available be an empty list. | 1. Let preferred-available be an empty list. | |||
| 2. Let preferred-types be a list of the types in the request-value, | 2. Let preferred-types be a list of the types in the request-value, | |||
| ordered by their weight, highest to lowest, as per [RFC7231] | ordered by their weight, highest to lowest, as per Section 5.3.2 | |||
| Section 5.3.2 (omitting any coding with a weight of 0). If | of [RFC7231] (omitting any coding with a weight of 0). If | |||
| "Accept" is not present or empty, preferred-types will be empty. | "Accept" is not present or empty, preferred-types will be empty. | |||
| If a type lacks an explicit weight, an implementation MAY assign | If a type lacks an explicit weight, an implementation MAY assign | |||
| one. | one. | |||
| 3. If the first member of available-values is not a member of | 3. If the first member of available-values is not a member of | |||
| preferred-types, append it to preferred-types (thus making it the | preferred-types, append it to preferred-types (thus making it the | |||
| default). | default). | |||
| 4. For each preferred-type in preferred-types: | 4. For each preferred-type in preferred-types: | |||
| 1. If any member of available-values matches preferred-type, | 1. If any member of available-values matches preferred-type, | |||
| using the media-range matching mechanism specified in | using the media-range matching mechanism specified in | |||
| [RFC7231] Section 5.3.2 (which is case-insensitive), append | Section 5.3.2 of [RFC7231] (which is case-insensitive), | |||
| those members of available-values to preferred-available | append those members of available-values to preferred- | |||
| (preserving the precedence order implied by the media ranges' | available (preserving the precedence order implied by the | |||
| specificity). | media ranges' specificity). | |||
| 5. Return preferred-available. | 5. Return preferred-available. | |||
| Note that this algorithm explicitly ignores extension parameters on | Note that this algorithm explicitly ignores extension parameters on | |||
| media types (e.g., "charset"). | media types (e.g., "charset"). | |||
| A.2. Accept-Encoding | A.2. Accept-Encoding | |||
| This section defines handling for Accept-Encoding variants, as per | This section defines variant handling for the Accept-Encoding request | |||
| [RFC7231] Section 5.3.4. | header (section 5.3.4 of [RFC7231]). | |||
| The syntax of an available-value for Accept-Encoding is: | ||||
| accept-encoding-available-value = content-coding / "identity" | ||||
| To perform content negotiation for Accept-Encoding given a request- | To perform content negotiation for Accept-Encoding given a request- | |||
| value and available-values: | value and available-values: | |||
| 1. Let preferred-available be an empty list. | 1. Let preferred-available be an empty list. | |||
| 2. Let preferred-codings be a list of the codings in the request- | 2. Let preferred-codings be a list of the codings in the request- | |||
| value, ordered by their weight, highest to lowest, as per | value, ordered by their weight, highest to lowest, as per | |||
| [RFC7231] Section 5.3.1 (omitting any coding with a weight of 0). | Section 5.3.1 of [RFC7231] (omitting any coding with a weight of | |||
| If "Accept-Encoding" is not present or empty, preferred-codings | 0). If "Accept-Encoding" is not present or empty, preferred- | |||
| will be empty. If a coding lacks an explicit weight, an | codings will be empty. If a coding lacks an explicit weight, an | |||
| implementation MAY assign one. | implementation MAY assign one. | |||
| 3. If "identity" is not a member of preferred-codings, append | 3. If "identity" is not a member of preferred-codings, append | |||
| "identity". | "identity". | |||
| 4. Append "identity" to available-values. | 4. Append "identity" to available-values. | |||
| 5. For each preferred-coding in preferred-codings: | 5. For each preferred-coding in preferred-codings: | |||
| 1. If there is a case-insensitive, character-for-character match | 1. If there is a case-insensitive, character-for-character match | |||
| for preferred-coding in available-values, append that member | for preferred-coding in available-values, append that member | |||
| of available-values to preferred-available. | of available-values to preferred-available. | |||
| 6. Return preferred-available. | 6. Return preferred-available. | |||
| Note that the unencoded variant needs to have a Variant-Key header | Note that the unencoded variant needs to have a Variant-Key header | |||
| field with a value of "identity" (as defined in [RFC7231] | field with a value of "identity" (as defined in Section 5.3.4 of | |||
| Section 5.3.4). | [RFC7231]). | |||
| A.3. Accept-Language | A.3. Accept-Language | |||
| This section defines handling for Accept-Language variants, as per | This section defines variant handling for the Accept-Language request | |||
| [RFC7231] Section 5.3.5. | header (section 5.3.5 of [RFC7231]). | |||
| The syntax of an available-value for Accept-Language is: | ||||
| accept-encoding-available-value = language-range | ||||
| To perform content negotiation for Accept-Language given a request- | To perform content negotiation for Accept-Language given a request- | |||
| value and available-values: | value and available-values: | |||
| 1. Let preferred-available be an empty list. | 1. Let preferred-available be an empty list. | |||
| 2. Let preferred-langs be a list of the language-ranges in the | 2. Let preferred-langs be a list of the language-ranges in the | |||
| request-value, ordered by their weight, highest to lowest, as per | request-value, ordered by their weight, highest to lowest, as per | |||
| [RFC7231] Section 5.3.1 (omitting any language-range with a | Section 5.3.1 of [RFC7231] (omitting any language-range with a | |||
| weight of 0). If a language-range lacks a weight, an | weight of 0). If a language-range lacks a weight, an | |||
| implementation MAY assign one. | implementation MAY assign one. | |||
| 3. If the first member of available-values is not a member of | 3. If the first member of available-values is not a member of | |||
| preferred-langs, append it to preferred-langs (thus making it the | preferred-langs, append it to preferred-langs (thus making it the | |||
| default). | default). | |||
| 4. For each preferred-lang in preferred-langs: | 4. For each preferred-lang in preferred-langs: | |||
| 1. If any member of available-values matches preferred-lang, | 1. If any member of available-values matches preferred-lang, | |||
| using either the Basic or Extended Filtering scheme defined | using either the Basic or Extended Filtering scheme defined | |||
| in [RFC4647] Section 3.3, append those members of available- | in Section 3.3 of [RFC4647], append those members of | |||
| values to preferred-available (preserving their order). | available-values to preferred-available (preserving their | |||
| order). | ||||
| 5. Return preferred-available. | 5. Return preferred-available. | |||
| Acknowledgements | ||||
| This protocol is conceptually similar to, but simpler than, | ||||
| Transparent Content Negotiation [RFC2295]. Thanks to its authors for | ||||
| their inspiration. | ||||
| It is also a generalisation of a Fastly VCL feature designed by | ||||
| Rogier 'DocWilco' Mulhuijzen. | ||||
| Thanks to Hooman Beheshti, Ilya Grigorik and Jeffrey Yasskin for | ||||
| their review and input. | ||||
| Author's Address | Author's Address | |||
| Mark Nottingham | Mark Nottingham | |||
| Fastly | Fastly | |||
| Email: mnot@mnot.net | Email: mnot@mnot.net | |||
| URI: https://www.mnot.net/ | URI: https://www.mnot.net/ | |||
| End of changes. 40 change blocks. | ||||
| 82 lines changed or deleted | 104 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/ | ||||