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.46. The latest version is available from http://tools.ietf.org/tools/rfcdiff/