| < draft-ietf-httpbis-variants-00.txt | draft-ietf-httpbis-variants-01.txt > | |||
|---|---|---|---|---|
| HTTP M. Nottingham | HTTP M. Nottingham | |||
| Internet-Draft Fastly | Internet-Draft Fastly | |||
| Updates: 7234 (if approved) April 1, 2018 | Updates: 7234 (if approved) May 1, 2018 | |||
| Intended status: Standards Track | Intended status: Standards Track | |||
| Expires: October 3, 2018 | Expires: November 2, 2018 | |||
| HTTP Representation Variants | HTTP Representation Variants | |||
| draft-ietf-httpbis-variants-00 | draft-ietf-httpbis-variants-01 | |||
| 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 October 3, 2018. | This Internet-Draft will expire on November 2, 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 27 ¶ | skipping to change at page 2, line 27 ¶ | |||
| 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 . . . . . . . . . . . . . 6 | |||
| 3.1. Generating a Normalised Variant-Key . . . . . . . . . . . 7 | 3.1. Generating a Variant-Key List . . . . . . . . . . . . . . 7 | |||
| 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 | 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 | |||
| 4.1. Find Available Keys . . . . . . . . . . . . . . . . . . . 9 | 4.1. Compute Possible Keys . . . . . . . . . . . . . . . . . . 9 | |||
| 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 | 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 | |||
| 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 10 | 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 11 | |||
| 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 11 | 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 11 | |||
| 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 . . . . . . . . . . . . . . . . . . 13 | |||
| 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 | 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 | |||
| 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 | |||
| 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 | |||
| 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 | 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 | |||
| 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 16 | |||
| 10.2. Informative References . . . . . . . . . . . . . . . . . 16 | 10.2. Informative References . . . . . . . . . . . . . . . . . 16 | |||
| 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 16 | 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 . . . . . . . . . . . . . . . . . . . . . 17 | A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 18 | |||
| A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 18 | A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 18 | |||
| Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 | Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 | |||
| 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]). | |||
| skipping to change at page 3, line 32 ¶ | skipping to change at page 3, line 32 ¶ | |||
| Even when the headers' semantics are understood, a cache does not | Even when the headers' semantics are understood, a cache does not | |||
| know enough about the possible alternative representations available | know enough about the possible alternative representations available | |||
| on the origin server to make an appropriate decision. | on the origin server to make an appropriate decision. | |||
| 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=1.0, fr;q=0.5 | 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: fr | |||
| 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 | |||
| skipping to change at page 4, line 7 ¶ | skipping to change at page 4, line 7 ¶ | |||
| example) whether a Japanese representation is available without | example) whether a Japanese representation is available without | |||
| making another request, incurring possibly unnecessary latency. | making another 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 the Variant-Key response header field (Section 3) | Its companion Variant-Key response header field (Section 3) indicates | |||
| indicates which representation was selected, so that it can be | the applicable key(s) that the response is associated with, so that | |||
| reliably reused in the future. When this specification is in use, | it can be reliably reused in the future. When this specification is | |||
| 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=1.0, fr;q=0.5 | 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: fr | |||
| Vary: Accept-Language | Vary: Accept-Language | |||
| Variants: Accept-Language;fr;de;en;jp | Variants: Accept-Language;fr;de;en;jp | |||
| Variant-Key: fr | Variant-Key: fr | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| [French content] | [French content] | |||
| skipping to change at page 6, line 51 ¶ | skipping to change at page 6, line 51 ¶ | |||
| 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 | |||
| value(s) 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 = 1#available-value | Variant-Key = available-values | |||
| available-values = available-value *( ";" available-value ) | ||||
| Each value indicates the selected available-value, in the same order | Each member of the list contains the selected available-value(s), in | |||
| 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: | |||
| Variants: Content-Encoding;gzip;br, Content-Language;en ;fr | Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr | |||
| Variant-Key: gzip, fr | Variant-Key: gzip, fr | |||
| This header pair indicates that the representation has a "gzip" | This header pair indicates that the representation has a "gzip" | |||
| content-coding and "fr" content-language. | content-coding and "fr" content-language. | |||
| Note that Variant-Key is only used to indicate what request | A more complex example involves listing multiple available-values in | |||
| attributes are associated with the response containing it; this is | a list member, to indicate that the response can be used to satisfy | |||
| different from headers like Content-Encoding, which indicate | requests with any of those values. For example: | |||
| attributes of the response itself. In the example above, it might be | ||||
| that a gzip'd version of the French content is not available, in | ||||
| which case the response will include: | ||||
| Variant-Key: gzip, fr | Variants: Content-Encoding;gzip;br, Content-Language;en ;fr | |||
| Variant-Key: gzip;identity, fr | ||||
| even though Content-Encoding does not contain "gzip". | indicates that this response can be used for requests whose Content- | |||
| Encoding algorithm selects "gzip" or "identity", as long as the | ||||
| Content-Language algorithm selects "fr" - perhaps because there is no | ||||
| gzip-compressed French representation. | ||||
| 3.1. Generating a Normalised Variant-Key | This highlights an important aspect of Variant-Key; it is only used | |||
| to indicate what request attributes are associated with the response | ||||
| containing it; this is different from headers like Content-Encoding, | ||||
| which indicate attributes of the response itself. | ||||
| This algorithm generates a normalised string for Variant-Key, | 3.1. Generating a Variant-Key List | |||
| suitable for comparison with values generated by Section 4. | ||||
| This algorithm generates a list of normalised strings from Variant- | ||||
| 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 variant-key for that message can be generated by: | normalised list of variant-keys for that message can be generated by: | |||
| 1. Let variant-key-header be a string, the result of selecting all | 1. Let variant-keys be an empty list. | |||
| 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 (","). | |||
| 2. Remove all whitespace from variant-key-header. | 3. Let value-list be the result of splitting variant-key-header on | |||
| commas (","). | ||||
| 3. Return variant-key-header. | 4. For each value in value-list: | |||
| 1. Remove all whitespace from value. | ||||
| 2. Let items be the result of splitting value on ";". | ||||
| 3. append items to variant-keys. | ||||
| 5. Return the result of running Compute Possible Keys (Section 4.1) | ||||
| on variant-keys, an empty string and an empty list. | ||||
| 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: | |||
| skipping to change at page 9, line 11 ¶ | skipping to change at page 9, line 27 ¶ | |||
| mechanism with request-value and available-values. | mechanism with request-value and available-values. | |||
| 4. Append sorted-values to sorted-variants. | 4. Append sorted-values to sorted-variants. | |||
| At this point, sorted-variants will be a list of lists, each | At this point, sorted-variants will be a list of lists, each | |||
| member of the top-level list corresponding to a variant-item | member of the top-level list corresponding to a variant-item | |||
| in the Variants header field-value, containing zero or more | in the Variants header field-value, containing zero or more | |||
| items indicating available-values that are acceptable to the | items indicating available-values that are acceptable to the | |||
| client, in order of preference, greatest to least. | client, in order of preference, greatest to least. | |||
| 5. Return result of running Find Available Keys (Section 4.1) on | 5. Return result of running Compute Possible Keys (Section 4.1) on | |||
| sorted-variants, an empty string and an empty list. | sorted-variants, an empty string and an empty list. | |||
| 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. Find Available Keys | 4.1. Compute Possible Keys | |||
| Given sorted-variants, a list of lists, and key-stub, a string | Given key-facets, a list of lists, and key-stub, a string | |||
| representing a partial key, and possible-keys, a list: | representing a partial key, and possible-keys, a list: | |||
| 1. Let sorted-values be the first member of sorted-variants. | 1. Let values be the first member of key-facets. | |||
| 2. For each sorted-value in sorted-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 | |||
| sorted-value. | value. | |||
| 2. Otherwise: | 2. Otherwise: | |||
| 1. Let this-key be a copy of key-stub. | 1. Let this-key be a copy of key-stub. | |||
| 2. Append a comma (",") to this-key. | 2. Append a comma (",") to this-key. | |||
| 3. Append sorted-value to this-key. | 3. Append value to this-key. | |||
| 3. Let remaining-variants be a copy of all of the members of | 3. Let remaining-facets be a copy of all of the members of key- | |||
| sorted-variants except the first. | facets except the first. | |||
| 4. If remaining-variants 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-variants, | 5. Otherwise, run Find Available Keys on remaining-facets, this- | |||
| this-key and possible-keys. | 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 a stored response, stored-response: | |||
| skipping to change at page 12, line 23 ¶ | skipping to change at page 12, line 36 ¶ | |||
| Given a request/response pair: | Given a request/response pair: | |||
| GET /clancy HTTP/1.1 | GET /clancy HTTP/1.1 | |||
| Host: www.example.com | Host: www.example.com | |||
| Accept-Language: en;q=1.0, fr;q=0.5 | Accept-Language: en;q=1.0, fr;q=0.5 | |||
| HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
| Content-Type: image/gif | Content-Type: image/gif | |||
| Content-Language: en | Content-Language: en | |||
| Cache-Control: max-age=3600 | Cache-Control: max-age=3600 | |||
| Variants: Content-Language;en;de | Variants: Accept-Language;en;de | |||
| Variant-Key: en | Variant-Key: en | |||
| Vary: Accept-Language | Vary: Accept-Language | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| Upon receipt of this response, the cache knows that two | Upon receipt of this response, the cache knows that two | |||
| representations of this resource are available, one with a Content- | representations of this resource are available, one with a Content- | |||
| Language of "en", and another whose Content-Language is "de". | Language of "en", and another whose Content-Language is "de". | |||
| Subsequent requests (while this response is fresh) will cause the | Subsequent requests (while this response is fresh) will cause the | |||
| cache to either reuse this response or forward the request, depending | cache to either reuse this response or forward the request, depending | |||
| skipping to change at page 13, line 18 ¶ | skipping to change at page 13, line 29 ¶ | |||
| GET /murray HTTP/1.1 | GET /murray HTTP/1.1 | |||
| Host: www.example.net | Host: www.example.net | |||
| Accept-Language: en;q=1.0, fr;q=0.5 | Accept-Language: en;q=1.0, fr;q=0.5 | |||
| Accept-Encoding: gzip, br | Accept-Encoding: gzip, br | |||
| HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
| Content-Type: image/gif | Content-Type: image/gif | |||
| Content-Language: en | Content-Language: en | |||
| Content-Encoding: br | Content-Encoding: br | |||
| Variants: Content-Language;en;jp;de | Variants: Accept-Language;en;jp;de | |||
| Variants: Content-Encoding;br;gzip | Variants: Accept-Encoding;br;gzip | |||
| Variant-Key: en, br | Variant-Key: en, br | |||
| Vary: Accept-Language, Accept-Encoding | Vary: Accept-Language, Accept-Encoding | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| Here, the cache knows that there are two axes that the response | Here, the cache knows that there are two axes that the response | |||
| varies upon; Content-Language and Content-Encoding. Thus, there are | varies upon; Content-Language and Content-Encoding. Thus, there are | |||
| a total of nine possible representations for the resource (including | a total of nine possible representations for the resource (including | |||
| the identity encoding), and the cache needs to consider the selection | the identity encoding), and the cache needs to consider the selection | |||
| algorithms for both axes. | algorithms for both axes. | |||
| Upon a subsequent request, if both selection algorithms return a | Upon a subsequent request, if both selection algorithms return a | |||
| stored representation, it can be served from cache; otherwise, the | stored representation, it can be served from cache; otherwise, the | |||
| request will need to be forwarded to origin. | request will need to be forwarded to origin. | |||
| 5.1.3. Partial Coverage | 5.1.3. Partial Coverage | |||
| Now, consider the previous example, but where only one of the Vary'd | Now, consider the previous example, but where only one of the Vary'd | |||
| axes is listed in Variants: | axes (Content-Encoding) is listed in Variants: | |||
| GET /bar HTTP/1.1 | GET /bar HTTP/1.1 | |||
| Host: www.example.net | Host: www.example.net | |||
| Accept-Language: en;q=1.0, fr;q=0.5 | Accept-Language: en;q=1.0, fr;q=0.5 | |||
| Accept-Encoding: gzip, br | Accept-Encoding: gzip, br | |||
| HTTP/1.1 200 OK | HTTP/1.1 200 OK | |||
| Content-Type: image/gif | Content-Type: image/gif | |||
| Content-Language: en | Content-Language: en | |||
| Content-Encoding: br | Content-Encoding: br | |||
| Variants: Content-Encoding;br;gzip | Variants: Accept-Encoding;br;gzip | |||
| Variant-Key: br | Variant-Key: br | |||
| Vary: Accept-Language, Accept-Encoding | Vary: Accept-Language, Accept-Encoding | |||
| Transfer-Encoding: chunked | Transfer-Encoding: chunked | |||
| Here, the cache will need to calculate a secondary cache key as per | Here, the cache will need to calculate a secondary cache key as per | |||
| [RFC7234], Section 4.1 - but considering only Accept-Language to be | [RFC7234], Section 4.1 - but considering only Accept-Language to be | |||
| in its field-value - and then continue processing Variants for the | in its field-value - and then continue processing Variants for the | |||
| set of stored responses that the algorithm described there selects. | set of stored responses that the algorithm described there selects. | |||
| 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: | |||
| End of changes. 41 change blocks. | ||||
| 53 lines changed or deleted | 73 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/ | ||||