idnits 2.17.1 draft-nottingham-variants-02.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], [5], [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 (February 13, 2018) is 2265 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 749 -- Looks like a reference, but probably isn't: '2' on line 751 -- Looks like a reference, but probably isn't: '3' on line 753 -- Looks like a reference, but probably isn't: '4' on line 755 -- Looks like a reference, but probably isn't: '5' on line 757 ** 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 (==), 8 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group M. Nottingham 3 Internet-Draft Fastly 4 Updates: 7234 (if approved) February 13, 2018 5 Intended status: Standards Track 6 Expires: August 17, 2018 8 HTTP Representation Variants 9 draft-nottingham-variants-02 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 The issues list for this draft can be found at 23 https://github.com/mnot/I-D/labels/variants [1]. 25 The most recent (often, unpublished) draft is at 26 https://mnot.github.io/I-D/variants/ [2]. 28 Recent changes are listed at https://github.com/mnot/I-D/commits/gh- 29 pages/variants [3]. 31 See also the draft's current status in the IETF datatracker, at 32 https://datatracker.ietf.org/doc/draft-nottingham-variants/ [4]. 34 There is a prototype implementation of the algorithms herein at 35 https://github.com/mnot/variants-toy [5]. 37 Status of This Memo 39 This Internet-Draft is submitted in full conformance with the 40 provisions of BCP 78 and BCP 79. 42 Internet-Drafts are working documents of the Internet Engineering 43 Task Force (IETF). Note that other groups may also distribute 44 working documents as Internet-Drafts. The list of current Internet- 45 Drafts is at https://datatracker.ietf.org/drafts/current/. 47 Internet-Drafts are draft documents valid for a maximum of six months 48 and may be updated, replaced, or obsoleted by other documents at any 49 time. It is inappropriate to use Internet-Drafts as reference 50 material or to cite them other than as "work in progress." 52 This Internet-Draft will expire on August 17, 2018. 54 Copyright Notice 56 Copyright (c) 2018 IETF Trust and the persons identified as the 57 document authors. All rights reserved. 59 This document is subject to BCP 78 and the IETF Trust's Legal 60 Provisions Relating to IETF Documents 61 (https://trustee.ietf.org/license-info) in effect on the date of 62 publication of this document. Please review these documents 63 carefully, as they describe your rights and restrictions with respect 64 to this document. Code Components extracted from this document must 65 include Simplified BSD License text as described in Section 4.e of 66 the Trust Legal Provisions and are provided without warranty as 67 described in the Simplified BSD License. 69 Table of Contents 71 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 72 1.1. Notational Conventions . . . . . . . . . . . . . . . . . 4 73 2. The "Variants" HTTP Header Field . . . . . . . . . . . . . . 5 74 2.1. Relationship to Vary . . . . . . . . . . . . . . . . . . 6 75 3. The "Variant-Key" HTTP Header Field . . . . . . . . . . . . . 7 76 3.1. Generating a Normalised Variant-Key . . . . . . . . . . . 7 77 4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . . . 8 78 4.1. Find Available Keys . . . . . . . . . . . . . . . . . . . 9 79 4.2. Check Vary . . . . . . . . . . . . . . . . . . . . . . . 10 80 4.3. Example of Cache Behaviour . . . . . . . . . . . . . . . 10 81 5. Origin Server Behaviour . . . . . . . . . . . . . . . . . . . 11 82 5.1. Examples . . . . . . . . . . . . . . . . . . . . . . . . 12 83 5.1.1. Single Variant . . . . . . . . . . . . . . . . . . . 12 84 5.1.2. Multiple Variants . . . . . . . . . . . . . . . . . . 13 85 5.1.3. Partial Coverage . . . . . . . . . . . . . . . . . . 13 86 6. Defining Content Negotiation Using Variants . . . . . . . . . 14 87 7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 88 8. Security Considerations . . . . . . . . . . . . . . . . . . . 15 89 9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 15 90 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 91 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 92 10.2. Informative References . . . . . . . . . . . . . . . . . 16 93 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 16 94 Appendix A. Variants for Existing Content Negotiation Mechanisms 17 95 A.1. Accept . . . . . . . . . . . . . . . . . . . . . . . . . 17 96 A.2. Accept-Encoding . . . . . . . . . . . . . . . . . . . . . 17 97 A.3. Accept-Language . . . . . . . . . . . . . . . . . . . . . 18 98 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 100 1. Introduction 102 HTTP proactive content negotiation ([RFC7231], Section 3.4.1) is 103 seeing renewed interest, both for existing request headers like 104 Content-Language and for newer ones (for example, see 105 [I-D.ietf-httpbis-client-hints]). 107 Successfully reusing negotiated responses that have been stored in a 108 HTTP cache requires establishment of a secondary cache key 109 ([RFC7234], Section 4.1). Currently, the Vary header ([RFC7231], 110 Section 7.1.4) does this by nominating a set of request headers. 112 HTTP's caching model allows a certain amount of latitude in 113 normalising those request header field values, so as to increase the 114 chances of a cache hit while still respecting the semantics of that 115 header. However, normalisation is not formally defined, leading to 116 divergence in cache behaviours. 118 Even when the headers' semantics are understood, a cache does not 119 know enough about the possible alternative representations available 120 on the origin server to make an appropriate decision. 122 For example, if a cache has stored the following request/response 123 pair: 125 GET /foo HTTP/1.1 126 Host: www.example.com 127 Accept-Language: en;q=1.0, fr;q=0.5 129 HTTP/1.1 200 OK 130 Content-Type: text/html 131 Content-Language: fr 132 Vary: Accept-Language 133 Transfer-Encoding: chunked 135 [French content] 137 Provided that the cache has full knowledge of the semantics of 138 Accept-Language and Content-Language, it will know that a French 139 representation is available and might be able to infer that an 140 English representation is not available. But, it does not know (for 141 example) whether a Japanese representation is available without 142 making another request, incurring possibly unnecessary latency. 144 This specification introduces the HTTP Variants response header field 145 (Section 2) to enumerate the available variant representations on the 146 origin server, to provide clients and caches with enough information 147 to properly satisfy requests - either by selecting a response from 148 cache or by forwarding the request towards the origin - by following 149 the algorithm defined in Section 4. 151 Its companion the Variant-Key response header field (Section 3) 152 indicates which representation was selected, so that it can be 153 reliably reused in the future. When this specification is in use, 154 the example above might become: 156 GET /foo HTTP/1.1 157 Host: www.example.com 158 Accept-Language: en;q=1.0, fr;q=0.5 160 HTTP/1.1 200 OK 161 Content-Type: text/html 162 Content-Language: fr 163 Vary: Accept-Language 164 Variants: Accept-Language;fr;de;en;jp 165 Variant-Key: fr 166 Transfer-Encoding: chunked 168 [French content] 170 Proactive content negotiation mechanisms that wish to be used with 171 Variants need to define how to do so explicitly; see Section 6. As a 172 result, it is best suited for negotiation over request headers that 173 are well-understood. 175 Variants also works best when content negotiation takes place over a 176 constrained set of representations; since each variant needs to be 177 listed in the header field, it is ill-suited for open-ended sets of 178 representations. 180 Variants can be seen as a simpler version of the Alternates header 181 field introduced by [RFC2295]; unlike that mechanism, Variants does 182 not require specification of each combination of attributes, and does 183 not assume that each combination has a unique URL. 185 1.1. Notational Conventions 187 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 188 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 189 "OPTIONAL" in this document are to be interpreted as described in BCP 190 14 [RFC2119] [RFC8174] when, and only when, they appear in all 191 capitals, as shown here. 193 This specification uses the Augmented Backus-Naur Form (ABNF) 194 notation of [RFC5234] with a list extension, defined in Section 7 of 195 [RFC7230], that allows for compact definition of comma-separated 196 lists using a '#' operator (similar to how the '*' operator indicates 197 repetition). 199 Additionally, it uses the "field-name", "OWS" and "token" rules from 200 [RFC7230]. 202 2. The "Variants" HTTP Header Field 204 The Variants HTTP response header field indicates what 205 representations are available for a given resource at the time that 206 the response is produced, by enumerating the request header fields 207 that it varies on, along with the values that are available for each. 209 Variants = 1#variant-item 210 variant-item = field-name *( OWS ";" OWS available-value ) 211 available-value = token 213 Each "variant-item" indicates a request header field that carries a 214 value that clients might proactively negotiate for; each parameter on 215 it indicates a value for which there is an available representation 216 on the origin server. 218 So, given this example header field: 220 Variants: Accept-Encoding;gzip 222 a recipient can infer that the only content-coding available for that 223 resource is "gzip" (along with the "identity" non-encoding; see 224 Appendix A.2). 226 Given: 228 Variants: accept-encoding 230 a recipient can infer that no content-codings (beyond identity) are 231 supported. Note that as always, field-name is case-insensitive. 233 A more complex example: 235 Variants: Accept-Encoding;gzip;br, Accept-Language;en ;fr 237 Here, recipients can infer that two content-codings in addition to 238 "identity" are available, as well as two content languages. Note 239 that, as with all HTTP header fields that use the "#" list rule (see 241 [RFC7230], Section 7), they might occur in the same header field or 242 separately, like this: 244 Variants: Accept-Encoding;gzip;brotli 245 Variants: Accept-Language;en ;fr 247 The ordering of available-values after the field-name is significant, 248 as it might be used by the header's algorithm for selecting a 249 response (in this example, the first language is the default; see 250 Appendix A.3). 252 The ordering of the request header fields themselves indicates 253 descending application of preferences; in the example above, a cache 254 that has all of the possible permutations stored will honour the 255 client's preferences for Accept-Encoding before honouring Accept- 256 Language. 258 Origin servers SHOULD consistently send Variant header fields on all 259 cacheable (as per [RFC7234], Section 3) responses for a resource, 260 since its absence will trigger caches to fall back to Vary 261 processing. 263 Likewise, servers MUST send the Variant-Key response header field 264 when sending Variants, since its absence means that the stored 265 response will not be reused when this specification is implemented. 267 2.1. Relationship to Vary 269 Caches that implement this specification SHOULD ignore request header 270 fields in the Vary header for the purposes of secondary cache key 271 calculation ([RFC7234], Section 4.1) when their semantics are 272 implemented as per this specification and their corresponding 273 response header field is listed in Variants. 275 If any member of the Vary header does not have a corresponding 276 variant that is understood by the implementation, it is still subject 277 to the requirements there. 279 See Section 5.1.3 for an example. 281 In practice, implementation of Vary varies considerably. As a 282 result, cache efficiency might drop considerably when Variants does 283 not contain all of the headers referenced by Vary, because some 284 implementations might choose to disable Variants processing when this 285 is the case. 287 3. The "Variant-Key" HTTP Header Field 289 The Variant-Key HTTP response header field is used to indicate the 290 value(s) from the Variants header field that identify the 291 representation it occurs within. 293 Variant-Key = 1#available-value 295 Each value indicates the selected available-value, in the same order 296 as the variants listed in the Variants header field. 298 Therefore, Variant-Key MUST be the same length (in comma-separated 299 members) as Variants, and each member MUST correspond in position to 300 its companion in Variants. 302 For example: 304 Variants: Content-Encoding;gzip;br, Content-Language;en ;fr 305 Variant-Key: gzip, fr 307 This header pair indicates that the representation has a "gzip" 308 content-coding and "fr" content-language. 310 Note that Variant-Key is only used to indicate what request 311 attributes are associated with the response containing it; this is 312 different from headers like Content-Encoding, which indicate 313 attributes of the response itself. In the example above, it might be 314 that a gzip'd version of the French content is not available, in 315 which case the response will include: 317 Variant-Key: gzip, fr 319 even though Content-Encoding does not contain "gzip". 321 3.1. Generating a Normalised Variant-Key 323 This algorithm generates a normalised string for Variant-Key, 324 suitable for comparison with values generated by Section 4. 326 Given stored-headers, a set of headers from a stored response, a 327 normalised variant-key for that message can be generated by: 329 1. Let variant-key-header be a string, the result of selecting all 330 field-values of stored-headers whose field-name is "Variant-Key" 331 and joining them with a comma (","). 333 2. Remove all whitespace from variant-key-header. 335 3. Return variant-key-header. 337 4. Cache Behaviour 339 Caches that implement the Variants header field and the relevant 340 semantics of the field-name it contains can use that knowledge to 341 either select an appropriate stored representation, or forward the 342 request if no appropriate representation is stored. 344 They do so by running this algorithm (or its functional equivalent) 345 upon receiving a request: 347 Given incoming-request, a mapping of field-names to lists of field 348 values, and stored-responses, a list of stored responses suitable for 349 reuse as defined in [RFC7234] Section 4, excepting the requirement to 350 calculate a secondary cache key: 352 1. If stored-responses is empty, return an empty list. 354 2. Order stored-responses by the "Date" header field, most recent to 355 least recent. 357 3. Let sorted-variants be an empty list. 359 4. If the freshest member of stored-responses (as per [RFC7234], 360 Section 4.2) has one or more "Variants" header field(s): 362 1. Select one member of stored-responses and let its "Variants" 363 header field-value(s) be variants-header. This SHOULD be the 364 most recent response, but MAY be from an older one as long as 365 it is still fresh. 367 2. For each variant in variants-header: 369 1. If variant's field-name corresponds to the request header 370 field identified by a content negotiation mechanism that 371 the implementation supports: 373 1. Let request-value be the field-value(s) associated 374 with field-name in incoming-request. 376 2. Let available-values be a list containing all 377 available-value for variant. 379 3. Let sorted-values be the result of running the 380 algorithm defined by the content negotiation 381 mechanism with request-value and available-values. 383 4. Append sorted-values to sorted-variants. 385 At this point, sorted-variants will be a list of lists, each 386 member of the top-level list corresponding to a variant-item 387 in the Variants header field-value, containing zero or more 388 items indicating available-values that are acceptable to the 389 client, in order of preference, greatest to least. 391 5. Return result of running Find Available Keys (Section 4.1) on 392 sorted-variants, an empty string and an empty list. 394 This returns a list of strings suitable for comparing to normalised 395 Variant-Keys (Section 3.1) that represent possible responses on the 396 server that can be used to satisfy the request, in preference order, 397 provided that their secondary cache key (after removing the headers 398 covered by Variants) matches. Section 4.2 illustrates one way to do 399 this. 401 4.1. Find Available Keys 403 Given sorted-variants, a list of lists, and key-stub, a string 404 representing a partial key, and possible-keys, a list: 406 1. Let sorted-values be the first member of sorted-variants. 408 2. For each sorted-value in sorted-values: 410 1. If key-stub is an empty string, let this-key be a copy of 411 sorted-value. 413 2. Otherwise: 415 1. Let this-key be a copy of key-stub. 417 2. Append a comma (",") to this-key. 419 3. Append sorted-value to this-key. 421 3. Let remaining-variants be a copy of all of the members of 422 sorted-variants except the first. 424 4. If remaining-variants is empty, append this-key to possible- 425 keys. 427 5. Otherwise, run Find Available Keys on remaining-variants, 428 this-key and possible-keys. 430 3. Return possible-keys. 432 4.2. Check Vary 434 This algorithm is an example of how an implementation can meet the 435 requirement to apply the members of the Vary header field that are 436 not covered by Variants. 438 Given a stored response, stored-response: 440 1. Let filtered-vary be the field-value(s) of stored-response's 441 "Vary" header field. 443 2. Let processed-variants be a list containing the request header 444 fields that identify the content negotiation mechanisms supported 445 by the implementation. 447 3. Remove any member of filtered-vary that is a case-insensitive 448 match for a member of processed-variants. 450 4. If the secondary cache key (as calculated in [RFC7234], 451 Section 4.1) for stored_response matches incoming-request, using 452 filtered-vary for the value of the "Vary" response header, return 453 True. 455 5. Return False. 457 This returns a Boolean that indicates whether stored-response can be 458 used to satisfy the request. 460 Note that implementation of the Vary header field varies in practice, 461 and the algorithm above illustrates only one way to apply it. It is 462 equally viable to forward the request if there is a request header 463 listed in Vary but not Variants. 465 4.3. Example of Cache Behaviour 467 For example, if the selected variants-header was: 469 Variants: Accept-Language;en;fr,de, Accept-Encoding;gzip,br 471 and the request contained the headers: 473 Accept-Language: fr;q=1.0, en;q=0.1 474 Accept-Encoding: gzip 476 Then the sorted-variants would be: 478 [ 479 ["fr", "en"] // prefers French, will accept English 480 ["gzip", "identity"] // prefers gzip encoding, will accept identity 481 ] 483 Which means that the sorted-keys would be: 485 [ 486 'fr gzip', 487 'fr identity', 488 'en gzip', 489 'en identity' 490 ] 492 Representing a first preference of a French, gzip'd response. Thus, 493 if a cache has a response with: 495 Variant-Key: fr, gzip 497 it could be used to satisfy the first preference. If not, responses 498 corresponding to the other keys could be returned, or the request 499 could be forwarded towards the origin. 501 5. Origin Server Behaviour 503 Origin servers that wish to take advantage of Variants will need to 504 generate both the Variants (Section 2) and Variant-Key (Section 3) 505 header fields in all cacheable responses for a given resource. If 506 either is omitted and the response is stored, it will have the effect 507 of disabling caching for that resource until it is no longer stored 508 (e.g., it expires, or is evicted). 510 Likewise, origin servers will need to assure that the members of both 511 header field values are in the same order and have the same length, 512 since discrepancies will cause caches to avoid using the responses 513 they occur in. 515 The value of the Variants header should be relatively stable for a 516 given resource over time; when it changes, it can have the effect of 517 invalidating previously stored responses. 519 As per Section 2.1, the Vary header is required to be set 520 appropriately when Variants is in use, so that caches that do not 521 implement this specification still operate correctly. 523 Origin servers are advised to carefully consider which content 524 negotiation mechanisms to enumerate in Variants; if a mechanism is 525 not supported by a receiving cache, it will "downgrade" to Vary 526 handling, which can negatively impact cache efficiency. 528 5.1. Examples 530 The operation of Variants is illustrated by the examples below. 532 5.1.1. Single Variant 534 Given a request/response pair: 536 GET /clancy HTTP/1.1 537 Host: www.example.com 538 Accept-Language: en;q=1.0, fr;q=0.5 540 HTTP/1.1 200 OK 541 Content-Type: image/gif 542 Content-Language: en 543 Cache-Control: max-age=3600 544 Variants: Content-Language;en;de 545 Variant-Key: en 546 Vary: Accept-Language 547 Transfer-Encoding: chunked 549 Upon receipt of this response, the cache knows that two 550 representations of this resource are available, one with a Content- 551 Language of "en", and another whose Content-Language is "de". 553 Subsequent requests (while this response is fresh) will cause the 554 cache to either reuse this response or forward the request, depending 555 on what the selection algorithm determines. 557 So, if a request with "en" in Accept-Language is received and its 558 q-value indicates that it is acceptable, the stored response is used. 559 A request that indicates that "de" is acceptable will be forwarded to 560 the origin, thereby populating the cache. A cache receiving a 561 request that indicates both languages are acceptable will use the 562 q-value to make a determination of what response to return. 564 A cache receiving a request that does not list either language as 565 acceptable (or does not contain an Accept-Language at all) will 566 return the "en" representation (possibly fetching it from the 567 origin), since it is listed first in the Variants list. 569 Note that Accept-Language is listed in Vary, to assure backwards- 570 compatibility with caches that do not support Variants. 572 5.1.2. Multiple Variants 574 A more complicated request/response pair: 576 GET /murray HTTP/1.1 577 Host: www.example.net 578 Accept-Language: en;q=1.0, fr;q=0.5 579 Accept-Encoding: gzip, br 581 HTTP/1.1 200 OK 582 Content-Type: image/gif 583 Content-Language: en 584 Content-Encoding: br 585 Variants: Content-Language;en;jp;de 586 Variants: Content-Encoding;br;gzip 587 Variant-Key: en, br 588 Vary: Accept-Language, Accept-Encoding 589 Transfer-Encoding: chunked 591 Here, the cache knows that there are two axes that the response 592 varies upon; Content-Language and Content-Encoding. Thus, there are 593 a total of nine possible representations for the resource (including 594 the identity encoding), and the cache needs to consider the selection 595 algorithms for both axes. 597 Upon a subsequent request, if both selection algorithms return a 598 stored representation, it can be served from cache; otherwise, the 599 request will need to be forwarded to origin. 601 5.1.3. Partial Coverage 603 Now, consider the previous example, but where only one of the Vary'd 604 axes is listed in Variants: 606 GET /bar HTTP/1.1 607 Host: www.example.net 608 Accept-Language: en;q=1.0, fr;q=0.5 609 Accept-Encoding: gzip, br 611 HTTP/1.1 200 OK 612 Content-Type: image/gif 613 Content-Language: en 614 Content-Encoding: br 615 Variants: Content-Encoding;br;gzip 616 Variant-Key: br 617 Vary: Accept-Language, Accept-Encoding 618 Transfer-Encoding: chunked 619 Here, the cache will need to calculate a secondary cache key as per 620 [RFC7234], Section 4.1 - but considering only Accept-Language to be 621 in its field-value - and then continue processing Variants for the 622 set of stored responses that the algorithm described there selects. 624 6. Defining Content Negotiation Using Variants 626 To be usable with Variants, proactive content negotiation mechanisms 627 need to be specified to take advantage of it. Specifically, they: 629 o MUST define a request header field that advertises the clients 630 preferences or capabilities, whose field-name SHOULD begin with 631 "Accept-". 633 o MUST define the syntax of available-values that will occur in 634 Variants and Variant-Key. 636 o MUST define an algorithm for selecting a result. It MUST return a 637 list of available-values that are suitable for the request, in 638 order of preference, given the value of the request header 639 nominated above and an available-values list from the Variants 640 header. If the result is an empty list, it implies that the cache 641 cannot satisfy the request. 643 Appendix A fulfils these requirements for some existing proactive 644 content negotiation mechanisms in HTTP. 646 7. IANA Considerations 648 This specification registers two values in the Permanent Message 649 Header Field Names registry established by [RFC3864]: 651 o Header field name: Variants 653 o Applicable protocol: http 655 o Status: standard 657 o Author/Change Controller: IETF 659 o Specification document(s): [this document] 661 o Related information: 663 o Header field name: Variant-Key 665 o Applicable protocol: http 666 o Status: standard 668 o Author/Change Controller: IETF 670 o Specification document(s): [this document] 672 o Related information: 674 8. Security Considerations 676 If the number or advertised characteristics of the representations 677 available for a resource are considered sensitive, the Variants 678 header by its nature will leak them. 680 Note that the Variants header is not a commitment to make 681 representations of a certain nature available; the runtime behaviour 682 of the server always overrides hints like Variants. 684 9. Acknowledgments 686 This protocol is conceptually similar to, but simpler than, 687 Transparent Content Negotiation [RFC2295]. Thanks to its authors for 688 their inspiration. 690 It is also a generalisation of a Fastly VCL feature designed by 691 Rogier 'DocWilco' Mulhuijzen. 693 Thanks to Hooman Beheshti for his review and input. 695 10. References 697 10.1. Normative References 699 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 700 Requirement Levels", BCP 14, RFC 2119, 701 DOI 10.17487/RFC2119, March 1997, 702 . 704 [RFC4647] Phillips, A. and M. Davis, "Matching of Language Tags", 705 BCP 47, RFC 4647, DOI 10.17487/RFC4647, September 2006, 706 . 708 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 709 Specifications: ABNF", STD 68, RFC 5234, 710 DOI 10.17487/RFC5234, January 2008, 711 . 713 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 714 Protocol (HTTP/1.1): Message Syntax and Routing", 715 RFC 7230, DOI 10.17487/RFC7230, June 2014, 716 . 718 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 719 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 720 DOI 10.17487/RFC7231, June 2014, 721 . 723 [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, 724 Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", 725 RFC 7234, DOI 10.17487/RFC7234, June 2014, 726 . 728 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 729 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 730 May 2017, . 732 10.2. Informative References 734 [I-D.ietf-httpbis-client-hints] 735 Grigorik, I., "HTTP Client Hints", draft-ietf-httpbis- 736 client-hints-05 (work in progress), January 2018. 738 [RFC2295] Holtman, K. and A. Mutz, "Transparent Content Negotiation 739 in HTTP", RFC 2295, DOI 10.17487/RFC2295, March 1998, 740 . 742 [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration 743 Procedures for Message Header Fields", BCP 90, RFC 3864, 744 DOI 10.17487/RFC3864, September 2004, 745 . 747 10.3. URIs 749 [1] https://github.com/mnot/I-D/labels/variants 751 [2] https://mnot.github.io/I-D/variants/ 753 [3] https://github.com/mnot/I-D/commits/gh-pages/variants 755 [4] https://datatracker.ietf.org/doc/draft-nottingham-variants/ 757 [5] https://github.com/mnot/variants-toy 759 Appendix A. Variants for Existing Content Negotiation Mechanisms 761 This appendix defines the required information to use existing 762 proactive content negotiation mechanisms (as defined in [RFC7231], 763 Section 5.3) with the Variants header field. 765 A.1. Accept 767 This section defines handling for Accept variants, as per [RFC7231] 768 Section 5.3.2. 770 To perform content negotiation for Accept given a request-value and 771 available-values: 773 1. Let preferred-available be an empty list. 775 2. Let preferred-types be a list of the types in the request-value, 776 ordered by their weight, highest to lowest, as per [RFC7231] 777 Section 5.3.2 (omitting any coding with a weight of 0). If 778 "Accept" is not present or empty, preferred-types will be empty. 779 If a type lacks an explicit weight, an implementation MAY assign 780 one. 782 3. If the first member of available-values is not a member of 783 preferred-types, append it to preferred-types (thus making it the 784 default). 786 4. For each preferred-type in preferred-types: 788 1. If any member of available-values matches preferred-type, 789 using the media-range matching mechanism specified in 790 [RFC7231] Section 5.3.2 (which is case-insensitive), append 791 those members of available-values to preferred-available 792 (preserving the precedence order implied by the media ranges' 793 specificity). 795 5. Return preferred-available. 797 Note that this algorithm explicitly ignores extension parameters on 798 media types (e.g., "charset"). 800 A.2. Accept-Encoding 802 This section defines handling for Accept-Encoding variants, as per 803 [RFC7231] Section 5.3.4. 805 To perform content negotiation for Accept-Encoding given a request- 806 value and available-values: 808 1. Let preferred-available be an empty list. 810 2. Let preferred-codings be a list of the codings in the request- 811 value, ordered by their weight, highest to lowest, as per 812 [RFC7231] Section 5.3.1 (omitting any coding with a weight of 0). 813 If "Accept-Encoding" is not present or empty, preferred-codings 814 will be empty. If a coding lacks an explicit weight, an 815 implementation MAY assign one. 817 3. If "identity" is not a member of preferred-codings, append 818 "identity". 820 4. Append "identity" to available-values. 822 5. For each preferred-coding in preferred-codings: 824 1. If there is a case-insensitive, character-for-character match 825 for preferred-coding in available-values, append that member 826 of available-values to preferred-available. 828 6. Return preferred-available. 830 Note that the unencoded variant needs to have a Variant-Key header 831 field with a value of "identity". 833 A.3. Accept-Language 835 This section defines handling for Accept-Language variants, as per 836 [RFC7231] Section 5.3.5. 838 To perform content negotiation for Accept-Language given a request- 839 value and available-values: 841 1. Let preferred-available be an empty list. 843 2. Let preferred-langs be a list of the language-ranges in the 844 request-value, ordered by their weight, highest to lowest, as per 845 [RFC7231] Section 5.3.1 (omitting any language-range with a 846 weight of 0). If a language-range lacks a weight, an 847 implementation MAY assign one. 849 3. If the first member of available-values is not a member of 850 preferred-langs, append it to preferred-langs (thus making it the 851 default). 853 4. For each preferred-lang in preferred-langs: 855 1. If any member of available-values matches preferred-lang, 856 using either the Basic or Extended Filtering scheme defined 857 in [RFC4647] Section 3.3, append those members of available- 858 values to preferred-available (preserving their order). 860 5. Return preferred-available. 862 Author's Address 864 Mark Nottingham 865 Fastly 867 Email: mnot@mnot.net 868 URI: https://www.mnot.net/