draft-ietf-httpbis-variants-04.txt   draft-ietf-httpbis-variants-latest.txt 
HTTP Working Group M. Nottingham HTTP Working Group M. Nottingham
Internet-Draft Fastly Internet-Draft Fastly
Updates: 7234 (if approved) October 22, 2018 Updates: 7234 (if approved) February 19, 2019
Intended status: Standards Track Intended status: Standards Track
Expires: April 25, 2019 Expires: August 23, 2019
HTTP Representation Variants HTTP Representation Variants
draft-ietf-httpbis-variants-04 draft-ietf-httpbis-variants-latest
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 April 25, 2019. This Internet-Draft will expire on August 23, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2019 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
carefully, as they describe your rights and restrictions with respect carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 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 . . . . . . . . . . . . . . . . . . 7
3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 7 3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 7
3.1. Generating a Variant-Key List . . . . . . . . . . . . . . 7 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 9
4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 4.1. Compute Possible Keys . . . . . . . . . . . . . . . . . . 10
4.1. Compute Possible Keys . . . . . . . . . . . . . . . . . . 9 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 11
4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10
4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 11 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 11
5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 12 4.3.1. A Variant Missing From the Cache . . . . . . . . . . 12
5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 12 4.3.2. Variants That Don't Overlap the Client's Request . . 13
5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 12 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 13
5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 13 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 14
5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 14 5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 14
6. Defining Content Negotiation Using Variants . . . . . . . . . 14 5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 15
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 15 5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 15
8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 6. Defining Content Negotiation Using Variants . . . . . . . . . 16
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16
9.1. Normative References . . . . . . . . . . . . . . . . . . 16 8. Security Considerations . . . . . . . . . . . . . . . . . . . 17
9.2. Informative References . . . . . . . . . . . . . . . . . 16 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 17
9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 17 9.1. Normative References . . . . . . . . . . . . . . . . . . 17
Appendix A. Variants for Existing Content Negotiation Mechanisms 17 9.2. Informative References . . . . . . . . . . . . . . . . . 18
A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 17 9.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 18
A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 18 Appendix A. Variants for Existing Content Negotiation Mechanisms 19
A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 19 A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 19
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 19 A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 20
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 20
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 21
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 21
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
Accept-Language and for newer ones (for example, see Accept-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 5, line 6 skipping to change at page 5, line 6
1.1. Notational Conventions 1.1. Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in BCP "OPTIONAL" in this document are to be interpreted as described in BCP
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] but relies on Structured Headers from
[RFC7230], that allows for compact definition of comma-separated [I-D.ietf-httpbis-header-structure] for parsing.
lists using a '#' operator (similar to how the '*' operator indicates
repetition).
Additionally, it uses the "field-name", "OWS" and "token" rules from Additionally, it uses the "field-name" rule from [RFC7230], and
[RFC7230], and "type", "subtype", "content-coding" and "language- "type", "subtype", "content-coding" and "language-range" from
range" from [RFC7231]. [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 is a Structured Header [I-D.ietf-httpbis-header-structure].
variant-item = field-name *( OWS ";" OWS available-value ) Its value MUST be a list-of-lists (Section 3.3 of
available-value = token [I-D.ietf-httpbis-header-structure]) whose members are strings
/ "/" / "?" / "\" / "[" / "]" (Section 3.8 of [I-D.ietf-httpbis-header-structure]) or tokens
/ ":" / "@" / "(" / ")" (Section 3.9 of [I-D.ietf-httpbis-header-structure]). Its ABNF is:
Each "variant-item" indicates a request header field that carries a Variants = sh-list-of-lists
value that clients might proactively negotiate for; each parameter on
it indicates a value for which there is an available representation If Structured Header parsing fails or a list-member has the wrong
on the origin server. type, the client MUST treat the representation as having no Variants
header field.
The Variants header field represents an ordered list of "variant-
axes", each of which consists of a request header "field-name" string
and a list of "available-value" strings. Each inner-list in the
Variants header field value is parsed into a variant-axis. The first
list-member of the inner-list is interpreted as the field-name, and
the remaining list-members are the available-values. Any list-member
that is a token (Section 3.9 of [I-D.ietf-httpbis-header-structure])
is interpreted as a string containing the same characters.
Field-names in the Variants header field value MUST match the field-
name production (Section 3.2 of [RFC7230]). Clients receiving an
invalid field-name MUST NOT match it to any content negotiating
mechanism.
So, given this example header field: So, given this example header field:
Variants: Accept-Encoding;gzip Variants: Accept-Encoding;gzip
a recipient can infer that the only content-coding available for that a recipient can infer that the only content-coding available for that
resource is "gzip" (along with the "identity" non-encoding; see resource is "gzip" (along with the "identity" non-encoding; see
Appendix A.2). Appendix A.2).
Given: Given:
skipping to change at page 6, line 4 skipping to change at page 6, line 15
Given: Given:
Variants: accept-encoding Variants: accept-encoding
a recipient can infer that no content-codings (beyond identity) are a recipient can infer that no content-codings (beyond identity) are
supported. Note that as always, field-name is case-insensitive. supported. Note that as always, field-name is case-insensitive.
A more complex example: A more complex example:
Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr
Here, recipients can infer that two content-codings in addition to Here, recipients can infer that two content-codings in addition to
"identity" are available, as well as two content languages. Note "identity" are available, as well as two content languages. Note
that, as with all HTTP header fields that use the "#" list rule (see that, as with all Structured Header lists, they might occur in the
[RFC7230], Section 7), they might occur in the same header field or same header field or separately, like this:
separately, like this:
Variants: Accept-Encoding;gzip;brotli Variants: Accept-Encoding;gzip;brotli
Variants: Accept-Language;en ;fr Variants: Accept-Language;en ;fr
The ordering of available-values after the field-name is significant, The ordering of available-values after the field-name is significant,
as it might be used by the header's algorithm for selecting a as it might be used by the header's algorithm for selecting a
response (in this example, the first language is the default; see response (in this example, the first language is the default; see
Appendix A.3). Appendix A.3).
The ordering of the request header fields themselves indicates The ordering of the request header fields themselves indicates
skipping to change at page 6, line 33 skipping to change at page 6, line 44
Origin servers SHOULD consistently send Variant header fields on all Origin servers SHOULD consistently send Variant header fields on all
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.
_RFC EDITOR: Please remove the next paragraph before publication._
Implementations of drafts of this specification MUST implement an
HTTP header field named "Variants-##" instead of the "Variants"
header field specified by the final RFC, with "##" replaced by the
draft number being implemented. For example, implementations of
draft-ietf-httpbis-variants-05 would implement "Variants-05".
2.1. Relationship to Vary 2.1. Relationship to Vary
This specification updates [RFC7234] to allow caches that implement This specification updates [RFC7234] to allow caches that implement
it to ignore request header fields in the Vary header for the it to ignore request header fields in the Vary header for the
purposes of secondary cache key calculation ([RFC7234], Section 4.1) purposes of secondary cache key calculation ([RFC7234], Section 4.1)
when their semantics are implemented as per this specification and when their semantics are implemented as per this specification and
their corresponding 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
skipping to change at page 7, line 7 skipping to change at page 7, line 27
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 identifies a set of
values from the Variants header field that identify the variants provided by the representation it occurs within. A variant
representation it occurs within. is identified by a selection of one available-value from each
variant-axis from the Variants header field.
Variant-Key = 1#available-values Variant-Key is a Structured Header
available-values = available-value *( ";" available-value ) [I-D.ietf-httpbis-header-structure]. Its value MUST be a list-of-
lists (Section 3.3 of [I-D.ietf-httpbis-header-structure]) whose
members are strings (Section 3.8 of
[I-D.ietf-httpbis-header-structure]) or tokens (Section 3.9 of
[I-D.ietf-httpbis-header-structure]). Its ABNF is:
Each member of the list contains a set of selected available-value(s) Variant-Key = sh-list-of-lists
that identify this representation, in the same order as the variants
listed in the Variants header field.
Therefore, each member of Variant-Key MUST be the same length (in If Structured Header parsing fails or a list-member has the wrong
semicolon-separated members) as Variants, and each member's type, the client MUST treat the representation as having no Variant-
available-values MUST correspond in position to their companions in Key header field.
Variants.
Each inner-list MUST have the same number of list-members as there
are variant-axes in the representation's Variants header field. If
not, the client MUST treat the representation as having no Variant-
Key header field.
Each list-member is treated as identifying an available-value for the
corresponding variant-axis' field-name. Any list-member that is a
token (Section 3.9 of [I-D.ietf-httpbis-header-structure]) is
interpreted as a string containing the same characters. These
available-values do not need to explicitly appear in the Variants
header field. For example, Accept-Encoding defines an implicit
"identity" available-value (Appendix A.2).
For example: For example:
Variants: Accept-Encoding;gzip;br, Accept-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.
If the response can be used to satisfy more than one request), they If the response can be used to satisfy more than one request, they
can be listed in additional members. For example: can be listed in additional members. For example:
Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr
Variant-Key: gzip;fr, identity;fr Variant-Key: gzip;fr, "identity";fr
indicates that this response can be used for requests whose Accept- indicates that this response can be used for requests whose Accept-
Encoding algorithm selects "gzip" or "identity", as long as the Encoding algorithm selects "gzip" or "identity", as long as the
Accept-Language algorithm selects "fr" - perhaps because there is no Accept-Language algorithm selects "fr" - perhaps because there is no
gzip-compressed French representation. gzip-compressed French representation.
When more than one Variant-Key value is in a response, the first one When more than one Variant-Key value is in a response, the first one
present MUST indicate the variant-key for the response it occurs present MUST correspond to the request that caused that response to
within. be generated.
3.1. Generating a Variant-Key List
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
normalised list of variant-keys for that message can be generated by
following this algorithm:
1. Let variant-keys be an empty list. Parsing is strict. For example:
2. Let variant-key-header be a string, the result of selecting all Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr
field-values of stored-headers whose field-name is "Variant-Key" Variant-Key: gzip;fr, identity;fr, br;fr;oops
and joining them with a comma (",").
3. Let value-list be the result of splitting variant-key-header on is treated as if the Variant-Key header were completely absent, which
commas (","). will tend to disable caching for the representation that contains it.
4. For each value in value-list: Note that in
1. Remove all whitespace from value. Variant-Key: gzip ;fr
Variant-Key: "gzip ";fr
2. Append value to variant-keys. The whitespace after "gzip" in the first header field value is
excluded by the token parsing algorithm, but the whitespace in the
second header field value is included by the string parsing
algorithm. This will likely cause the second header field value to
fail to match client requests.
5. Return variant-keys. _RFC EDITOR: Please remove the next paragraph before publication._
Implementations of drafts of this specification MUST implement an
HTTP header field named "Variant-Key-##" instead of the "Variant-Key"
header field specified by the final RFC, with "##" replaced by the
draft number being implemented. For example, implementations of
draft-ietf-httpbis-variants-05 would implement "Variant-Key-05".
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-names 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 values), and stored-responses (a list of stored responses suitable
for reuse as defined in Section 4 of [RFC7234], excepting the for reuse as defined in Section 4 of [RFC7234], excepting the
requirement to 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) that
successfully parse according to Section 2:
1. Select one member of stored-responses and let variants-header
be its "Variants" header field-value(s). This SHOULD be the
most recent response, but MAY be from an older one as long as
it is still fresh.
2. For each variant in variants-header, parsed according to the 1. Select one member of stored-responses with a "Variants"
ABNF: header field-value(s) that successfully parses according to
Section 2 and let variants-header be this parsed value. This
SHOULD be the most recent response, but MAY be from an older
one as long as it is still fresh.
1. If variant's field-name corresponds to the request header 2. For each variant-axis in variants-header:
field identified by a content negotiation mechanism that
the implementation supports:
1. Let request-value be the field-value(s) associated 1. If variant-axis' field-name corresponds to the request
with field-name in incoming-request. header field identified by a content negotiation
mechanism that the implementation supports:
2. Let available-values be a list containing all 1. Let request-value be the field-value associated with
available-value for variant. field-name in incoming-request (after being combined
as allowed by Section 3.2.2 of [RFC7230]), or null if
field-name is not in incoming-request.
3. Let sorted-values be the result of running the 2. Let sorted-values be the result of running the
algorithm defined by the content negotiation algorithm defined by the content negotiation
mechanism with request-value and available-values. mechanism with request-value and variant-axis'
available-values.
4. Append sorted-values to sorted-variants. 3. 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-axis
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 Compute Possible 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 list and an empty list.
This returns a list of strings suitable for comparing to normalised This returns a list of lists of strings suitable for comparing to the
Variant-Keys (Section 3.1) that represent possible responses on the parsed Variant-Keys (Section 3) that represent possible responses on
server that can be used to satisfy the request, in preference order, the server that can be used to satisfy the request, in preference
provided that their secondary cache key (after removing the headers order, provided that their secondary cache key (after removing the
covered by Variants) matches. Section 4.2 illustrates one way to do headers covered by Variants) matches. Section 4.2 illustrates one
this. way to do this.
4.1. Compute Possible Keys 4.1. Compute Possible Keys
This algorithm computes the cross-product of the elements of key- This algorithm computes the cross-product of the elements of key-
facets. facets.
Given key-facets (a list of lists), and key-stub (a string Given key-facets (a list of lists of strings), and key-stub (a list
representing a partial key), and possible-keys (a list): of strings representing a partial key), and possible-keys (a list of
lists of strings):
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. Let remaining-facets be a copy of all of the members of key-
facets except the first.
1. If key-stub is an empty string, let this-key be a copy of
value.
2. Otherwise:
1. Let this-key be a copy of key-stub.
2. Append a semicolon (";") to this-key. 3. For each value in values:
3. Append value to this-key. 1. Let this-key be a copy of key-stub.
3. Let remaining-facets be a copy of all of the members of key- 2. Append value to this-key.
facets except the first.
4. If remaining-facets is empty, append this-key to possible- 3. If remaining-facets is empty, append this-key to possible-
keys. keys.
5. Otherwise, run Compute Possible Keys on remaining-facets, 4. Otherwise, run Compute Possible Keys on remaining-facets,
this-key and possible-keys. this-key and possible-keys.
3. Return possible-keys. 4. 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 stored-response (a 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
skipping to change at page 11, line 31 skipping to change at page 12, line 10
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
["gzip", "identity"] // prefers gzip encoding, will accept identity ["gzip", "identity"] // prefers gzip encoding, will accept identity
] ]
Which means that the sorted-keys would be: Which means that the result of the Cache Behaviour algorithm would
be:
[ [
'fr gzip', ["fr", "gzip"],
'fr identity', ["fr", "identity"],
'en gzip', ["en", "gzip"],
'en identity' ["en", "identity"]
] ]
Representing a first preference of a French, gzip'd response. Thus, Representing a first preference of a French, gzip'd response. Thus,
if a cache has a response with: if a cache has a response with:
Variant-Key: fr, gzip Variant-Key: fr; gzip
it could be used to satisfy the first preference. If not, responses it could be used to satisfy the first preference. If not, responses
corresponding to the other keys could be returned, or the request corresponding to the other keys could be returned, or the request
could be forwarded towards the origin. could be forwarded towards the origin.
4.3.1. A Variant Missing From the Cache
If the selected variants-header was:
Variants: Accept-Language;en;fr;de
And a request comes in with the following headers:
Accept-Language: de;q=1.0, es;q=0.8
Then sorted-variants in Cache Behaviour is:
[
["de"] // prefers German; will not accept English
]
If the cache contains responses with the following Variant-Keys:
Variant-Key: fr
Variant-Key: en
Then the cache needs to forward the request to the origin server,
since Variants indicates that "de" is available, and that is
acceptable to the client.
4.3.2. Variants That Don't Overlap the Client's Request
If the selected variants-header was:
Variants: Accept-Language;en;fr;de
And a request comes in with the following headers:
Accept-Language: es;q=1.0, ja;q=0.8
Then sorted-variants in Cache Behaviour are:
[
["en"]
]
This allows the cache to return a "Variant-Key: en" response even
though it's not in the set the client prefers.
5. Origin Server Behaviour 5. Origin Server Behaviour
Origin servers that wish to take advantage of Variants will need to Origin servers that wish to take advantage of Variants will need to
generate both the Variants (Section 2) and Variant-Key (Section 3) generate both the Variants (Section 2) and Variant-Key (Section 3)
header fields in all cacheable responses for a given resource. If header fields in all cacheable responses for a given resource. If
either is omitted and the response is stored, it will have the effect either is omitted and the response is stored, it will have the effect
of disabling caching for that resource until it is no longer stored of disabling caching for that resource until it is no longer stored
(e.g., it expires, or is evicted). (e.g., it expires, or is evicted).
Likewise, origin servers will need to assure that the members of both Likewise, origin servers will need to assure that the members of both
skipping to change at page 14, line 48 skipping to change at page 16, line 33
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 an available-value 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 (or null if the request header is absent) and an
header. If the result is an empty list, it implies that the cache available-values list from the Variants header. If the result is
cannot satisfy the request. an empty list, it implies that the cache cannot satisfy the
request.
Appendix A fulfils these requirements for some existing proactive Appendix A fulfils these requirements for some existing proactive
content negotiation mechanisms in HTTP. content negotiation mechanisms in HTTP.
7. IANA Considerations 7. IANA Considerations
This specification registers the following entry in the Permanent This specification registers the following entry in the Permanent
Message Header Field Names registry established by [RFC3864]: Message Header Field Names registry established by [RFC3864]:
o Header field name: Variants o Header field name: Variants
skipping to change at page 16, line 9 skipping to change at page 17, line 39
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. References 9. References
9.1. Normative References 9.1. Normative References
[I-D.ietf-httpbis-header-structure]
Nottingham, M. and P. Kamp, "Structured Headers for HTTP",
draft-ietf-httpbis-header-structure-09 (work in progress),
December 2018.
[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>.
[RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax
skipping to change at page 17, line 40 skipping to change at page 19, line 25
The syntax of an available-value for Accept is: The syntax of an available-value for Accept is:
accept-available-value = type "/" subtype 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 Section 5.3.2 (or the empty list if request-value is null), ordered by their
of [RFC7231] (omitting any coding with a weight of 0). If weight, highest to lowest, as per Section 5.3.2 of [RFC7231]
"Accept" is not present or empty, preferred-types will be empty. (omitting any coding with a weight of 0). If a type lacks an
If a type lacks an explicit weight, an implementation MAY assign explicit weight, an implementation MAY assign one.
one.
3. If the first member of available-values is not a member of
preferred-types, append it to preferred-types (thus making it the
default).
4. For each preferred-type in preferred-types: 3. 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
Section 5.3.2 of [RFC7231] (which is case-insensitive), Section 5.3.2 of [RFC7231] (which is case-insensitive),
append those members of available-values to preferred- append those members of available-values to preferred-
available (preserving the precedence order implied by the available (preserving the precedence order implied by the
media ranges' specificity). media ranges' specificity).
4. If preferred-available is empty, append the first member of
available-values to preferred-available. This makes the first
available-value the default when none of the client's preferences
are available.
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 variant handling for the Accept-Encoding request This section defines variant handling for the Accept-Encoding request
header (section 5.3.4 of [RFC7231]). header (section 5.3.4 of [RFC7231]).
The syntax of an available-value for Accept-Encoding is: The syntax of an available-value for Accept-Encoding is:
accept-encoding-available-value = content-coding / "identity" 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 (or the empty list if request-value is null), ordered by
Section 5.3.1 of [RFC7231] (omitting any coding with a weight of their weight, highest to lowest, as per Section 5.3.1 of
0). If "Accept-Encoding" is not present or empty, preferred- [RFC7231] (omitting any coding with a weight of 0). If a coding
codings will be empty. If a coding lacks an explicit weight, an 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
skipping to change at page 19, line 24 skipping to change at page 21, line 8
The syntax of an available-value for Accept-Language is: The syntax of an available-value for Accept-Language is:
accept-encoding-available-value = language-range 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 (or the empty list if request-value is null),
Section 5.3.1 of [RFC7231] (omitting any language-range with a ordered by their weight, highest to lowest, as per Section 5.3.1
weight of 0). If a language-range lacks a weight, an of [RFC7231] (omitting any language-range with a weight of 0).
implementation MAY assign one. If a language-range lacks a weight, an implementation MAY assign
one.
3. If the first member of available-values is not a member of
preferred-langs, append it to preferred-langs (thus making it the
default).
4. For each preferred-lang in preferred-langs: 3. 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 Section 3.3 of [RFC4647], append those members of in Section 3.3 of [RFC4647], append those members of
available-values to preferred-available (preserving their available-values to preferred-available (preserving their
order). order).
4. If preferred-available is empty, append the first member of
available-values to preferred-available. This makes the first
available-value the default when none of the client's preferences
are available.
5. Return preferred-available. 5. Return preferred-available.
Acknowledgements Acknowledgements
This protocol is conceptually similar to, but simpler than, This protocol is conceptually similar to, but simpler than,
Transparent Content Negotiation [RFC2295]. Thanks to its authors for Transparent Content Negotiation [RFC2295]. Thanks to its authors for
their inspiration. their inspiration.
It is also a generalisation of a Fastly VCL feature designed by It is also a generalisation of a Fastly VCL feature designed by
Rogier 'DocWilco' Mulhuijzen. Rogier 'DocWilco' Mulhuijzen.
 End of changes. 62 change blocks. 
160 lines changed or deleted 244 lines changed or added

This html diff was produced by rfcdiff 1.44jr. The latest version is available from http://tools.ietf.org/tools/rfcdiff/