idnits 2.17.1 draft-ietf-httpbis-variants-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([2], [3], [4], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. -- The draft header indicates that this document updates RFC7234, but the abstract doesn't seem to mention this, which it should. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year (Using the creation date from RFC7234, updated by this document, for RFC5378 checks: 2007-12-21) -- The document seems to lack a disclaimer for pre-RFC5378 work, but may have content which was first submitted before 10 November 2008. If you have contacted all the original authors and they are all willing to grant the BCP78 rights to the IETF Trust, then this is fine, and you can ignore this comment. If not, you may need to add the pre-RFC5378 disclaimer. (See the Legal Provisions document at https://trustee.ietf.org/license-info for more information.) -- The document date (April 1, 2018) is 2179 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 744 -- Looks like a reference, but probably isn't: '2' on line 746 -- Looks like a reference, but probably isn't: '3' on line 748 -- Looks like a reference, but probably isn't: '4' on line 750 ** Obsolete normative reference: RFC 7230 (Obsoleted by RFC 9110, RFC 9112) ** Obsolete normative reference: RFC 7231 (Obsoleted by RFC 9110) ** Obsolete normative reference: RFC 7234 (Obsoleted by RFC 9111) == Outdated reference: A later version (-15) exists of draft-ietf-httpbis-client-hints-05 Summary: 4 errors (**), 0 flaws (~~), 2 warnings (==), 7 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 HTTP M. Nottingham 3 Internet-Draft Fastly 4 Updates: 7234 (if approved) April 1, 2018 5 Intended status: Standards Track 6 Expires: October 3, 2018 8 HTTP Representation Variants 9 draft-ietf-httpbis-variants-00 11 Abstract 13 This specification introduces an alternative way to communicate a 14 secondary cache key for a HTTP resource, using the HTTP "Variants" 15 and "Variant-Key" response header fields. Its aim is to make HTTP 16 proactive content negotiation more cache-friendly. 18 Note to Readers 20 _RFC EDITOR: please remove this section before publication_ 22 Discussion of this draft takes place on the HTTP working group 23 mailing list (ietf-http-wg@w3.org), which is archived at 24 https://lists.w3.org/Archives/Public/ietf-http-wg/ [1]. 26 Working Group information can be found at https://httpwg.github.io/ 27 [2]; source code and issues list for this draft can be found at 28 https://github.com/httpwg/http-extensions/labels/variants [3]. 30 There is a prototype implementation of the algorithms herein at 31 https://github.com/mnot/variants-toy [4]. 33 Status of This Memo 35 This Internet-Draft is submitted in full conformance with the 36 provisions of BCP 78 and BCP 79. 38 Internet-Drafts are working documents of the Internet Engineering 39 Task Force (IETF). Note that other groups may also distribute 40 working documents as Internet-Drafts. The list of current Internet- 41 Drafts is at https://datatracker.ietf.org/drafts/current/. 43 Internet-Drafts are draft documents valid for a maximum of six months 44 and may be updated, replaced, or obsoleted by other documents at any 45 time. It is inappropriate to use Internet-Drafts as reference 46 material or to cite them other than as "work in progress." 48 This Internet-Draft will expire on October 3, 2018. 50 Copyright Notice 52 Copyright (c) 2018 IETF Trust and the persons identified as the 53 document authors. All rights reserved. 55 This document is subject to BCP 78 and the IETF Trust's Legal 56 Provisions Relating to IETF Documents 57 (https://trustee.ietf.org/license-info) in effect on the date of 58 publication of this document. Please review these documents 59 carefully, as they describe your rights and restrictions with respect 60 to this document. Code Components extracted from this document must 61 include Simplified BSD License text as described in Section 4.e of 62 the Trust Legal Provisions and are provided without warranty as 63 described in the Simplified BSD License. 65 Table of Contents 67 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 68 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 69 2. The "Variants" HTTP Header Field . . . . . . . . . . . . . . 5 70 2.1. Relationship to Vary . . . . . . . . . . . . . . . . . . 6 71 3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 6 72 3.1. Generating a Normalised Variant-Key . . . . . . . . . . . 7 73 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 74 4.1. Find Available Keys . . . . . . . . . . . . . . . . . . . 9 75 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 76 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 10 77 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 11 78 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 12 79 5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 12 80 5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 13 81 5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 13 82 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 83 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 84 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 85 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 86 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 87 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 88 10.2. Informative References . . . . . . . . . . . . . . . . . 16 89 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 16 90 Appendix A. Variants for Existing Content Negotiation Mechanisms 17 91 A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 17 92 A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 17 93 A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 18 94 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 96 1. Introduction 98 HTTP proactive content negotiation ([RFC7231], Section 3.4.1) is 99 seeing renewed interest, both for existing request headers like 100 Content-Language and for newer ones (for example, see 101 [I-D.ietf-httpbis-client-hints]). 103 Successfully reusing negotiated responses that have been stored in a 104 HTTP cache requires establishment of a secondary cache key 105 ([RFC7234], Section 4.1). Currently, the Vary header ([RFC7231], 106 Section 7.1.4) does this by nominating a set of request headers. 108 HTTP's caching model allows a certain amount of latitude in 109 normalising those request header field values, so as to increase the 110 chances of a cache hit while still respecting the semantics of that 111 header. However, normalisation is not formally defined, leading to 112 divergence in cache behaviours. 114 Even when the headers' semantics are understood, a cache does not 115 know enough about the possible alternative representations available 116 on the origin server to make an appropriate decision. 118 For example, if a cache has stored the following request/response 119 pair: 121 GET /foo HTTP/1.1 122 Host: www.example.com 123 Accept-Language: en;q=1.0, fr;q=0.5 125 HTTP/1.1 200 OK 126 Content-Type: text/html 127 Content-Language: fr 128 Vary: Accept-Language 129 Transfer-Encoding: chunked 131 [French content] 133 Provided that the cache has full knowledge of the semantics of 134 Accept-Language and Content-Language, it will know that a French 135 representation is available and might be able to infer that an 136 English representation is not available. But, it does not know (for 137 example) whether a Japanese representation is available without 138 making another request, incurring possibly unnecessary latency. 140 This specification introduces the HTTP Variants response header field 141 (Section 2) to enumerate the available variant representations on the 142 origin server, to provide clients and caches with enough information 143 to properly satisfy requests - either by selecting a response from 144 cache or by forwarding the request towards the origin - by following 145 the algorithm defined in Section 4. 147 Its companion the Variant-Key response header field (Section 3) 148 indicates which representation was selected, so that it can be 149 reliably reused in the future. When this specification is in use, 150 the example above might become: 152 GET /foo HTTP/1.1 153 Host: www.example.com 154 Accept-Language: en;q=1.0, fr;q=0.5 156 HTTP/1.1 200 OK 157 Content-Type: text/html 158 Content-Language: fr 159 Vary: Accept-Language 160 Variants: Accept-Language;fr;de;en;jp 161 Variant-Key: fr 162 Transfer-Encoding: chunked 164 [French content] 166 Proactive content negotiation mechanisms that wish to be used with 167 Variants need to define how to do so explicitly; see Section 6. As a 168 result, it is best suited for negotiation over request headers that 169 are well-understood. 171 Variants also works best when content negotiation takes place over a 172 constrained set of representations; since each variant needs to be 173 listed in the header field, it is ill-suited for open-ended sets of 174 representations. 176 Variants can be seen as a simpler version of the Alternates header 177 field introduced by [RFC2295]; unlike that mechanism, Variants does 178 not require specification of each combination of attributes, and does 179 not assume that each combination has a unique URL. 181 1.1. Notational Conventions 183 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 184 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 185 "OPTIONAL" in this document are to be interpreted as described in BCP 186 14 [RFC2119] [RFC8174] when, and only when, they appear in all 187 capitals, as shown here. 189 This specification uses the Augmented Backus-Naur Form (ABNF) 190 notation of [RFC5234] with a list extension, defined in Section 7 of 191 [RFC7230], that allows for compact definition of comma-separated 192 lists using a '#' operator (similar to how the '*' operator indicates 193 repetition). 195 Additionally, it uses the "field-name", "OWS" and "token" rules from 196 [RFC7230]. 198 2. The "Variants" HTTP Header Field 200 The Variants HTTP response header field indicates what 201 representations are available for a given resource at the time that 202 the response is produced, by enumerating the request header fields 203 that it varies on, along with the values that are available for each. 205 Variants = 1#variant-item 206 variant-item = field-name *( OWS ";" OWS available-value ) 207 available-value = token 209 Each "variant-item" indicates a request header field that carries a 210 value that clients might proactively negotiate for; each parameter on 211 it indicates a value for which there is an available representation 212 on the origin server. 214 So, given this example header field: 216 Variants: Accept-Encoding;gzip 218 a recipient can infer that the only content-coding available for that 219 resource is "gzip" (along with the "identity" non-encoding; see 220 Appendix A.2). 222 Given: 224 Variants: accept-encoding 226 a recipient can infer that no content-codings (beyond identity) are 227 supported. Note that as always, field-name is case-insensitive. 229 A more complex example: 231 Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr 233 Here, recipients can infer that two content-codings in addition to 234 "identity" are available, as well as two content languages. Note 235 that, as with all HTTP header fields that use the "#" list rule (see 236 [RFC7230], Section 7), they might occur in the same header field or 237 separately, like this: 239 Variants: Accept-Encoding;gzip;brotli 240 Variants: Accept-Language;en ;fr 242 The ordering of available-values after the field-name is significant, 243 as it might be used by the header's algorithm for selecting a 244 response (in this example, the first language is the default; see 245 Appendix A.3). 247 The ordering of the request header fields themselves indicates 248 descending application of preferences; in the example above, a cache 249 that has all of the possible permutations stored will honour the 250 client's preferences for Accept-Encoding before honouring Accept- 251 Language. 253 Origin servers SHOULD consistently send Variant header fields on all 254 cacheable (as per [RFC7234], Section 3) responses for a resource, 255 since its absence will trigger caches to fall back to Vary 256 processing. 258 Likewise, servers MUST send the Variant-Key response header field 259 when sending Variants, since its absence means that the stored 260 response will not be reused when this specification is implemented. 262 2.1. Relationship to Vary 264 Caches that implement this specification SHOULD ignore request header 265 fields in the Vary header for the purposes of secondary cache key 266 calculation ([RFC7234], Section 4.1) when their semantics are 267 implemented as per this specification and their corresponding 268 response header field is listed in Variants. 270 If any member of the Vary header does not have a corresponding 271 variant that is understood by the implementation, it is still subject 272 to the requirements there. 274 See Section 5.1.3 for an example. 276 In practice, implementation of Vary varies considerably. As a 277 result, cache efficiency might drop considerably when Variants does 278 not contain all of the headers referenced by Vary, because some 279 implementations might choose to disable Variants processing when this 280 is the case. 282 3. The "Variant-Key" HTTP Header Field 284 The Variant-Key HTTP response header field is used to indicate the 285 value(s) from the Variants header field that identify the 286 representation it occurs within. 288 Variant-Key = 1#available-value 290 Each value indicates the selected available-value, in the same order 291 as the variants listed in the Variants header field. 293 Therefore, Variant-Key MUST be the same length (in comma-separated 294 members) as Variants, and each member MUST correspond in position to 295 its companion in Variants. 297 For example: 299 Variants: Content-Encoding;gzip;br, Content-Language;en ;fr 300 Variant-Key: gzip, fr 302 This header pair indicates that the representation has a "gzip" 303 content-coding and "fr" content-language. 305 Note that Variant-Key is only used to indicate what request 306 attributes are associated with the response containing it; this is 307 different from headers like Content-Encoding, which indicate 308 attributes of the response itself. In the example above, it might be 309 that a gzip'd version of the French content is not available, in 310 which case the response will include: 312 Variant-Key: gzip, fr 314 even though Content-Encoding does not contain "gzip". 316 3.1. Generating a Normalised Variant-Key 318 This algorithm generates a normalised string for Variant-Key, 319 suitable for comparison with values generated by Section 4. 321 Given stored-headers, a set of headers from a stored response, a 322 normalised variant-key for that message can be generated by: 324 1. Let variant-key-header be a string, the result of selecting all 325 field-values of stored-headers whose field-name is "Variant-Key" 326 and joining them with a comma (","). 328 2. Remove all whitespace from variant-key-header. 330 3. Return variant-key-header. 332 4. Cache Behaviour 334 Caches that implement the Variants header field and the relevant 335 semantics of the field-name it contains can use that knowledge to 336 either select an appropriate stored representation, or forward the 337 request if no appropriate representation is stored. 339 They do so by running this algorithm (or its functional equivalent) 340 upon receiving a request: 342 Given incoming-request, a mapping of field-names to lists of field 343 values, and stored-responses, a list of stored responses suitable for 344 reuse as defined in [RFC7234] Section 4, excepting the requirement to 345 calculate a secondary cache key: 347 1. If stored-responses is empty, return an empty list. 349 2. Order stored-responses by the "Date" header field, most recent to 350 least recent. 352 3. Let sorted-variants be an empty list. 354 4. If the freshest member of stored-responses (as per [RFC7234], 355 Section 4.2) has one or more "Variants" header field(s): 357 1. Select one member of stored-responses and let its "Variants" 358 header field-value(s) be variants-header. This SHOULD be the 359 most recent response, but MAY be from an older one as long as 360 it is still fresh. 362 2. For each variant in variants-header: 364 1. If variant's field-name corresponds to the request header 365 field identified by a content negotiation mechanism that 366 the implementation supports: 368 1. Let request-value be the field-value(s) associated 369 with field-name in incoming-request. 371 2. Let available-values be a list containing all 372 available-value for variant. 374 3. Let sorted-values be the result of running the 375 algorithm defined by the content negotiation 376 mechanism with request-value and available-values. 378 4. Append sorted-values to sorted-variants. 380 At this point, sorted-variants will be a list of lists, each 381 member of the top-level list corresponding to a variant-item 382 in the Variants header field-value, containing zero or more 383 items indicating available-values that are acceptable to the 384 client, in order of preference, greatest to least. 386 5. Return result of running Find Available Keys (Section 4.1) on 387 sorted-variants, an empty string and an empty list. 389 This returns a list of strings suitable for comparing to normalised 390 Variant-Keys (Section 3.1) that represent possible responses on the 391 server that can be used to satisfy the request, in preference order, 392 provided that their secondary cache key (after removing the headers 393 covered by Variants) matches. Section 4.2 illustrates one way to do 394 this. 396 4.1. Find Available Keys 398 Given sorted-variants, a list of lists, and key-stub, a string 399 representing a partial key, and possible-keys, a list: 401 1. Let sorted-values be the first member of sorted-variants. 403 2. For each sorted-value in sorted-values: 405 1. If key-stub is an empty string, let this-key be a copy of 406 sorted-value. 408 2. Otherwise: 410 1. Let this-key be a copy of key-stub. 412 2. Append a comma (",") to this-key. 414 3. Append sorted-value to this-key. 416 3. Let remaining-variants be a copy of all of the members of 417 sorted-variants except the first. 419 4. If remaining-variants is empty, append this-key to possible- 420 keys. 422 5. Otherwise, run Find Available Keys on remaining-variants, 423 this-key and possible-keys. 425 3. Return possible-keys. 427 4.2. Check Vary 429 This algorithm is an example of how an implementation can meet the 430 requirement to apply the members of the Vary header field that are 431 not covered by Variants. 433 Given a stored response, stored-response: 435 1. Let filtered-vary be the field-value(s) of stored-response's 436 "Vary" header field. 438 2. Let processed-variants be a list containing the request header 439 fields that identify the content negotiation mechanisms supported 440 by the implementation. 442 3. Remove any member of filtered-vary that is a case-insensitive 443 match for a member of processed-variants. 445 4. If the secondary cache key (as calculated in [RFC7234], 446 Section 4.1) for stored_response matches incoming-request, using 447 filtered-vary for the value of the "Vary" response header, return 448 True. 450 5. Return False. 452 This returns a Boolean that indicates whether stored-response can be 453 used to satisfy the request. 455 Note that implementation of the Vary header field varies in practice, 456 and the algorithm above illustrates only one way to apply it. It is 457 equally viable to forward the request if there is a request header 458 listed in Vary but not Variants. 460 4.3. Example of Cache Behaviour 462 For example, if the selected variants-header was: 464 Variants: Accept-Language;en;fr,de, Accept-Encoding;gzip,br 466 and the request contained the headers: 468 Accept-Language: fr;q=1.0, en;q=0.1 469 Accept-Encoding: gzip 471 Then the sorted-variants would be: 473 [ 474 ["fr", "en"] // prefers French, will accept English 475 ["gzip", "identity"] // prefers gzip encoding, will accept identity 476 ] 478 Which means that the sorted-keys would be: 480 [ 481 'fr gzip', 482 'fr identity', 483 'en gzip', 484 'en identity' 485 ] 487 Representing a first preference of a French, gzip'd response. Thus, 488 if a cache has a response with: 490 Variant-Key: fr, gzip 492 it could be used to satisfy the first preference. If not, responses 493 corresponding to the other keys could be returned, or the request 494 could be forwarded towards the origin. 496 5. Origin Server Behaviour 498 Origin servers that wish to take advantage of Variants will need to 499 generate both the Variants (Section 2) and Variant-Key (Section 3) 500 header fields in all cacheable responses for a given resource. If 501 either is omitted and the response is stored, it will have the effect 502 of disabling caching for that resource until it is no longer stored 503 (e.g., it expires, or is evicted). 505 Likewise, origin servers will need to assure that the members of both 506 header field values are in the same order and have the same length, 507 since discrepancies will cause caches to avoid using the responses 508 they occur in. 510 The value of the Variants header should be relatively stable for a 511 given resource over time; when it changes, it can have the effect of 512 invalidating previously stored responses. 514 As per Section 2.1, the Vary header is required to be set 515 appropriately when Variants is in use, so that caches that do not 516 implement this specification still operate correctly. 518 Origin servers are advised to carefully consider which content 519 negotiation mechanisms to enumerate in Variants; if a mechanism is 520 not supported by a receiving cache, it will "downgrade" to Vary 521 handling, which can negatively impact cache efficiency. 523 5.1. Examples 525 The operation of Variants is illustrated by the examples below. 527 5.1.1. Single Variant 529 Given a request/response pair: 531 GET /clancy HTTP/1.1 532 Host: www.example.com 533 Accept-Language: en;q=1.0, fr;q=0.5 535 HTTP/1.1 200 OK 536 Content-Type: image/gif 537 Content-Language: en 538 Cache-Control: max-age=3600 539 Variants: Content-Language;en;de 540 Variant-Key: en 541 Vary: Accept-Language 542 Transfer-Encoding: chunked 544 Upon receipt of this response, the cache knows that two 545 representations of this resource are available, one with a Content- 546 Language of "en", and another whose Content-Language is "de". 548 Subsequent requests (while this response is fresh) will cause the 549 cache to either reuse this response or forward the request, depending 550 on what the selection algorithm determines. 552 So, if a request with "en" in Accept-Language is received and its 553 q-value indicates that it is acceptable, the stored response is used. 554 A request that indicates that "de" is acceptable will be forwarded to 555 the origin, thereby populating the cache. A cache receiving a 556 request that indicates both languages are acceptable will use the 557 q-value to make a determination of what response to return. 559 A cache receiving a request that does not list either language as 560 acceptable (or does not contain an Accept-Language at all) will 561 return the "en" representation (possibly fetching it from the 562 origin), since it is listed first in the Variants list. 564 Note that Accept-Language is listed in Vary, to assure backwards- 565 compatibility with caches that do not support Variants. 567 5.1.2. Multiple Variants 569 A more complicated request/response pair: 571 GET /murray HTTP/1.1 572 Host: www.example.net 573 Accept-Language: en;q=1.0, fr;q=0.5 574 Accept-Encoding: gzip, br 576 HTTP/1.1 200 OK 577 Content-Type: image/gif 578 Content-Language: en 579 Content-Encoding: br 580 Variants: Content-Language;en;jp;de 581 Variants: Content-Encoding;br;gzip 582 Variant-Key: en, br 583 Vary: Accept-Language, Accept-Encoding 584 Transfer-Encoding: chunked 586 Here, the cache knows that there are two axes that the response 587 varies upon; Content-Language and Content-Encoding. Thus, there are 588 a total of nine possible representations for the resource (including 589 the identity encoding), and the cache needs to consider the selection 590 algorithms for both axes. 592 Upon a subsequent request, if both selection algorithms return a 593 stored representation, it can be served from cache; otherwise, the 594 request will need to be forwarded to origin. 596 5.1.3. Partial Coverage 598 Now, consider the previous example, but where only one of the Vary'd 599 axes is listed in Variants: 601 GET /bar HTTP/1.1 602 Host: www.example.net 603 Accept-Language: en;q=1.0, fr;q=0.5 604 Accept-Encoding: gzip, br 606 HTTP/1.1 200 OK 607 Content-Type: image/gif 608 Content-Language: en 609 Content-Encoding: br 610 Variants: Content-Encoding;br;gzip 611 Variant-Key: br 612 Vary: Accept-Language, Accept-Encoding 613 Transfer-Encoding: chunked 614 Here, the cache will need to calculate a secondary cache key as per 615 [RFC7234], Section 4.1 - but considering only Accept-Language to be 616 in its field-value - and then continue processing Variants for the 617 set of stored responses that the algorithm described there selects. 619 6. Defining Content Negotiation Using Variants 621 To be usable with Variants, proactive content negotiation mechanisms 622 need to be specified to take advantage of it. Specifically, they: 624 o MUST define a request header field that advertises the clients 625 preferences or capabilities, whose field-name SHOULD begin with 626 "Accept-". 628 o MUST define the syntax of available-values that will occur in 629 Variants and Variant-Key. 631 o MUST define an algorithm for selecting a result. It MUST return a 632 list of available-values that are suitable for the request, in 633 order of preference, given the value of the request header 634 nominated above and an available-values list from the Variants 635 header. If the result is an empty list, it implies that the cache 636 cannot satisfy the request. 638 Appendix A fulfils these requirements for some existing proactive 639 content negotiation mechanisms in HTTP. 641 7. IANA Considerations 643 This specification registers two values in the Permanent Message 644 Header Field Names registry established by [RFC3864]: 646 o Header field name: Variants 648 o Applicable protocol: http 650 o Status: standard 652 o Author/Change Controller: IETF 654 o Specification document(s): [this document] 656 o Related information: 658 o Header field name: Variant-Key 660 o Applicable protocol: http 661 o Status: standard 663 o Author/Change Controller: IETF 665 o Specification document(s): [this document] 667 o Related information: 669 8. Security Considerations 671 If the number or advertised characteristics of the representations 672 available for a resource are considered sensitive, the Variants 673 header by its nature will leak them. 675 Note that the Variants header is not a commitment to make 676 representations of a certain nature available; the runtime behaviour 677 of the server always overrides hints like Variants. 679 9. Acknowledgments 681 This protocol is conceptually similar to, but simpler than, 682 Transparent Content Negotiation [RFC2295]. Thanks to its authors for 683 their inspiration. 685 It is also a generalisation of a Fastly VCL feature designed by 686 Rogier 'DocWilco' Mulhuijzen. 688 Thanks to Hooman Beheshti for his review and input. 690 10. References 692 10.1. Normative References 694 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 695 Requirement Levels", BCP 14, RFC 2119, 696 DOI 10.17487/RFC2119, March 1997, 697 . 699 [RFC4647] Phillips, A. and M. Davis, "Matching of Language Tags", 700 BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, 701 . 703 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 704 Specifications: ABNF", STD 68, RFC 5234, 705 DOI 10.17487/RFC5234, January 2008, 706 . 708 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 709 Protocol (HTTP/1.1): Message Syntax and Routing", 710 RFC 7230, DOI 10.17487/RFC7230, June 2014, 711 . 713 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 714 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 715 DOI 10.17487/RFC7231, June 2014, 716 . 718 [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, 719 Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", 720 RFC 7234, DOI 10.17487/RFC7234, June 2014, 721 . 723 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 724 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 725 May 2017, . 727 10.2. Informative References 729 [I-D.ietf-httpbis-client-hints] 730 Grigorik, I., "HTTP Client Hints", draft-ietf-httpbis- 731 client-hints-05 (work in progress), January 2018. 733 [RFC2295] Holtman, K. and A. Mutz, "Transparent Content Negotiation 734 in HTTP", RFC 2295, DOI 10.17487/RFC2295, March 1998, 735 . 737 [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration 738 Procedures for Message Header Fields", BCP 90, RFC 3864, 739 DOI 10.17487/RFC3864, September 2004, 740 . 742 10.3. URIs 744 [1] https://lists.w3.org/Archives/Public/ietf-http-wg/ 746 [2] https://httpwg.github.io/ 748 [3] https://github.com/httpwg/http-extensions/labels/variants 750 [4] https://github.com/mnot/variants-toy 752 Appendix A. Variants for Existing Content Negotiation Mechanisms 754 This appendix defines the required information to use existing 755 proactive content negotiation mechanisms (as defined in [RFC7231], 756 Section 5.3) with the Variants header field. 758 A.1. Accept 760 This section defines handling for Accept variants, as per [RFC7231] 761 Section 5.3.2. 763 To perform content negotiation for Accept given a request-value and 764 available-values: 766 1. Let preferred-available be an empty list. 768 2. Let preferred-types be a list of the types in the request-value, 769 ordered by their weight, highest to lowest, as per [RFC7231] 770 Section 5.3.2 (omitting any coding with a weight of 0). If 771 "Accept" is not present or empty, preferred-types will be empty. 772 If a type lacks an explicit weight, an implementation MAY assign 773 one. 775 3. If the first member of available-values is not a member of 776 preferred-types, append it to preferred-types (thus making it the 777 default). 779 4. For each preferred-type in preferred-types: 781 1. If any member of available-values matches preferred-type, 782 using the media-range matching mechanism specified in 783 [RFC7231] Section 5.3.2 (which is case-insensitive), append 784 those members of available-values to preferred-available 785 (preserving the precedence order implied by the media ranges' 786 specificity). 788 5. Return preferred-available. 790 Note that this algorithm explicitly ignores extension parameters on 791 media types (e.g., "charset"). 793 A.2. Accept-Encoding 795 This section defines handling for Accept-Encoding variants, as per 796 [RFC7231] Section 5.3.4. 798 To perform content negotiation for Accept-Encoding given a request- 799 value and available-values: 801 1. Let preferred-available be an empty list. 803 2. Let preferred-codings be a list of the codings in the request- 804 value, ordered by their weight, highest to lowest, as per 805 [RFC7231] Section 5.3.1 (omitting any coding with a weight of 0). 806 If "Accept-Encoding" is not present or empty, preferred-codings 807 will be empty. If a coding lacks an explicit weight, an 808 implementation MAY assign one. 810 3. If "identity" is not a member of preferred-codings, append 811 "identity". 813 4. Append "identity" to available-values. 815 5. For each preferred-coding in preferred-codings: 817 1. If there is a case-insensitive, character-for-character match 818 for preferred-coding in available-values, append that member 819 of available-values to preferred-available. 821 6. Return preferred-available. 823 Note that the unencoded variant needs to have a Variant-Key header 824 field with a value of "identity" (as defined in [RFC7231] 825 Section 5.3.4). 827 A.3. Accept-Language 829 This section defines handling for Accept-Language variants, as per 830 [RFC7231] Section 5.3.5. 832 To perform content negotiation for Accept-Language given a request- 833 value and available-values: 835 1. Let preferred-available be an empty list. 837 2. Let preferred-langs be a list of the language-ranges in the 838 request-value, ordered by their weight, highest to lowest, as per 839 [RFC7231] Section 5.3.1 (omitting any language-range with a 840 weight of 0). If a language-range lacks a weight, an 841 implementation MAY assign one. 843 3. If the first member of available-values is not a member of 844 preferred-langs, append it to preferred-langs (thus making it the 845 default). 847 4. For each preferred-lang in preferred-langs: 849 1. If any member of available-values matches preferred-lang, 850 using either the Basic or Extended Filtering scheme defined 851 in [RFC4647] Section 3.3, append those members of available- 852 values to preferred-available (preserving their order). 854 5. Return preferred-available. 856 Author's Address 858 Mark Nottingham 859 Fastly 861 Email: mnot@mnot.net 862 URI: https://www.mnot.net/