idnits 2.17.1 draft-ietf-httpbis-key-01.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 : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (March 2, 2016) is 2975 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) ** 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) -- Obsolete informational reference (is this intentional?): RFC 5226 (Obsoleted by RFC 8126) Summary: 3 errors (**), 0 flaws (~~), 1 warning (==), 2 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 HTTP Working Group R. Fielding 3 Internet-Draft Adobe Systems Incorporated 4 Intended status: Standards Track M. Nottingham 5 Expires: September 3, 2016 March 2, 2016 7 The Key HTTP Response Header Field 8 draft-ietf-httpbis-key-01 10 Abstract 12 The 'Key' header field for HTTP responses allows an origin server to 13 describe the secondary cache key (RFC 7234, Section 4.1) for a 14 resource, by conveying what is effectively a short algorithm that can 15 be used upon later requests to determine if a stored response is 16 reusable for a given request. 18 Key has the advantage of avoiding an additional round trip for 19 validation whenever a new request differs slightly, but not 20 significantly, from prior requests. 22 Key also informs user agents of the request characteristics that 23 might result in different content, which can be useful if the user 24 agent is not sending request header fields in order to reduce the 25 risk of fingerprinting. 27 Note to Readers 29 Discussion of this draft takes place on the HTTP working group 30 mailing list (ietf-http-wg@w3.org), which is archived at 31 https://lists.w3.org/Archives/Public/ietf-http-wg/ . 33 Working Group information can be found at http://httpwg.github.io/ ; 34 source code and issues list for this draft can be found at 35 https://github.com/httpwg/http-extensions/labels/key . 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 http://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 September 3, 2016. 54 Copyright Notice 56 Copyright (c) 2016 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 (http://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. Examples . . . . . . . . . . . . . . . . . . . . . . . . 3 73 1.2. Notational Conventions . . . . . . . . . . . . . . . . . 4 74 2. The "Key" Response Header Field . . . . . . . . . . . . . . . 4 75 2.1. Relationship with Vary . . . . . . . . . . . . . . . . . 5 76 2.2. Calculating a Secondary Cache Key . . . . . . . . . . . . 6 77 2.2.1. Creating a Header Field Value . . . . . . . . . . . . 8 78 2.2.2. Failing Parameter Processing . . . . . . . . . . . . 8 79 2.3. Key Parameters . . . . . . . . . . . . . . . . . . . . . 9 80 2.3.1. div . . . . . . . . . . . . . . . . . . . . . . . . . 9 81 2.3.2. partition . . . . . . . . . . . . . . . . . . . . . . 10 82 2.3.3. match . . . . . . . . . . . . . . . . . . . . . . . . 11 83 2.3.4. substr . . . . . . . . . . . . . . . . . . . . . . . 12 84 2.3.5. param . . . . . . . . . . . . . . . . . . . . . . . . 13 85 3. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 14 86 3.1. Procedure . . . . . . . . . . . . . . . . . . . . . . . . 14 87 3.2. Registrations . . . . . . . . . . . . . . . . . . . . . . 14 88 4. Security Considerations . . . . . . . . . . . . . . . . . . . 15 89 5. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 90 5.1. Normative References . . . . . . . . . . . . . . . . . . 15 91 5.2. Informative References . . . . . . . . . . . . . . . . . 16 92 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 16 93 Appendix B. Changes . . . . . . . . . . . . . . . . . . . . . . 16 94 B.1. Since -00 . . . . . . . . . . . . . . . . . . . . . . . . 16 95 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 16 97 1. Introduction 99 In HTTP caching [RFC7234], the Vary response header field effectively 100 modifies the key used to store and access a response to include 101 information from the request's headers. This "secondary cache key" 102 allows proactive content negotiation [RFC7231] to work with caches. 104 Vary's operation is generic; it works well when caches understand the 105 semantics of the selecting headers. For example, the Accept-Language 106 request header field has a well-defined syntax for expressing the 107 client's preferences; a cache that understands this header field can 108 select the appropriate response (based upon its Content-Language 109 header field) and serve it to a client, without any knowledge of the 110 underlying resource. 112 Vary does not work as well when the criteria for selecting a response 113 are specific to the resource. For example, if the nature of the 114 response depends upon the presence or absence of a particular Cookie 115 ([RFC6265]) in a request, Vary doesn't have a mechanism to offer 116 enough fine-grained, resource-specific information to aid a cache's 117 selection of the appropriate response. 119 This document defines a new response header field, "Key", that allows 120 resources to describe the secondary cache key in a fine-grained, 121 resource-specific manner, leading to improved cache efficiency when 122 responses depend upon such headers. 124 1.1. Examples 126 For example, this response header field: 128 Key: cookie;param=_sess;param=ID 130 indicates that the selected response depends upon the "_sess" and 131 "ID" cookie values. 133 This Key: 135 Key: user-agent;substr=MSIE 137 indicates that there are two possible secondary cache keys for this 138 resource; one for requests whose User-Agent header field contains 139 "MSIE", and another for those that don't. 141 A more complex example: 143 Key: user-agent;substr=MSIE;Substr="mobile", Cookie;param="ID" 145 indicates that the selected response depends on the presence of two 146 strings in the User-Agent request header field, as well as the value 147 of the "ID" cookie request header field. 149 1.2. Notational Conventions 151 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 152 "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this 153 document are to be interpreted as described in [RFC2119]. 155 This document uses the Augmented Backus-Naur Form (ABNF) notation of 156 [RFC5234] (including the DQUOTE rule), and the list rule extension 157 defined in [RFC7230], Section 7. It includes by reference the field- 158 name, quoted-string and quoted-pair rules from that document, the OWS 159 rule from [RFC7230] and the parameter rule from [RFC7231]. 161 2. The "Key" Response Header Field 163 The "Key" response header field describes the portions of the request 164 that the resource currently uses to select representations. 166 As such, its semantics are similar to the "Vary" response header 167 field, but it allows more fine-grained description, using "key 168 parameters". 170 Caches can use this information as part of determining whether a 171 stored response can be used to satisfy a given request. When a cache 172 knows and fully understands the Key header field for a given 173 resource, it MAY ignore the Vary response header field in any stored 174 responses for it. 176 Additionally, user agents can use Key to discover if additional 177 request header fields might influence the resource's selection of 178 responses. 180 The Key field-value is a comma-delimited list of selecting header 181 fields (similar to Vary), with zero to many parameters each, 182 delimited by semicolons. 184 Key = 1#key-value 185 key-value = field-name *( OWS ";" OWS parameter ) 187 Note that, as per [RFC7231], parameter names are case-insensitive, 188 and parameter values can be double-quoted strings (potentially with 189 "\"-escaped characters inside). 191 The following header fields have the same effect: 193 Vary: Accept-Encoding, Cookie 194 Key: Accept-Encoding, Cookie 196 However, Key's use of parameters allows: 198 Key: Accept-Encoding, Cookie; param=foo 200 to indicate that the secondary cache key depends upon the Accept- 201 Encoding header field and the "foo" Cookie. 203 One important difference between Vary and Key is how they are 204 applied. Vary is specified to be specific to the response it occurs 205 within, whereas Key is specific to the resource (as identified by the 206 request URL) it is associated with. The most recent key you receive 207 for a given resource is applicable to all responses from that 208 resource. 210 This difference allows more efficient implementation (and reflects 211 practices that many caches use in implementing Vary already). 213 This specification defines a selection of Key parameters to address 214 common use cases such as selection upon individual Cookie header 215 fields, User-Agent substrings and numerical ranges. Future 216 parameters may define further capabilities. 218 2.1. Relationship with Vary 220 Origin servers SHOULD still send Vary when using Key, to ensure 221 backwards compatibility. 223 For example, 225 Vary: User-Agent 226 Key: User-Agent;substr="mozilla" 228 Note that, in some cases, it may be better to explicitly use "Vary: 229 *" if clients and caches don't have any practical way to use the Vary 230 header field's value. For example, 232 Vary: * 233 Key: Cookie;param="ID" 235 Except when Vary: * is used, the set of headers used in Key SHOULD 236 reflect the same request header fields as Vary does, even if they 237 don't have parameters. For example, 239 Vary: Accept-Encoding, User-Agent 240 Key: Accept-Encoding, User-Agent;substr="mozilla" 242 Here, Accept-Encoding is included in Key without parameters; caches 243 MAY treat these as they do values in the Vary header, relying upon 244 knowledge of their generic semantics to select an appropriate 245 response. 247 2.2. Calculating a Secondary Cache Key 249 When used by a cache to determine whether a stored response can be 250 used to satisfy a presented request, each field-name in Key 251 identifies a potential request header, just as with the Vary response 252 header field. 254 However, each of these can have zero to many key parameters that 255 change how the response selection process (as defined in [RFC7234], 256 Section 4.3)) works. 258 In particular, when a cache fully implements this specification, it 259 creates a secondary cache key for every request by following the 260 instructions in the Key header field, ignoring the Vary header for 261 this purpose. 263 Then, when a new request is presented, the secondary cache key 264 generated for that request can be compared to the stored one to find 265 the appropriate response, to determine if it can be selected. 267 To generate a secondary cache key for a given request (including that 268 which is stored with a response) using Key, the following steps are 269 taken: 271 1) If the Key header field is not present on the most recent 272 cacheable (as per [RFC7234], Section 3)) response seen for the 273 resource, abort this algorithm (i.e., fall back to using Vary to 274 determine the secondary cache key). 275 2) Let "key_value" be the result of Creating a Header Field Value 276 (Section 2.2.1) with "key" as the "target_field_name" and the 277 most recently seen response header list for the resource as 278 "header_list". 279 3) Let "secondary_key" be an empty string. 281 4) Create "key_list" by splitting "key_value" on "," characters, 282 excepting "," characters within quoted strings, as per [RFC7230] 283 Section 3.2.6.. 284 5) For "key_item" in "key_list": 286 1) Remove any leading and trailing WSP from "key_item". 287 2) If "key_item" does not contain a ";" character, fail 288 parameter processing (Section 2.2.2) and skip to the next 289 "key_item". 290 3) Let "field_name" be the string before the first ";" character 291 in "key_item", removing any WSP between them. 292 4) Let "field_value" be the result of Creating a Header Field 293 Value (Section 2.2.1) with "field_name" as the 294 "target_field_name" and the request header list as 295 "header_list". 296 5) Let "parameters" be the string after the first ";" character 297 in "key_item", removing any WSP between them. 298 6) Create "param_list" by splitting "parameters" on ";" 299 characters, excepting ";" characters within quoted strings, 300 as per [RFC7230] Section 3.2.6. 301 7) For "parameter" in "param_list": 303 1) If "parameter" does not contain a "=", fail parameter 304 processing (Section 2.2.2) and skip to the next 305 "key_item". 306 2) Remove any WSP at the beginning and/or end of 307 "parameter". 308 3) Let "param_name" be the string before the first "=" 309 character in "parameter", case-normalized to lowercase. 310 4) If "param_name" does not identify a Key parameter 311 processing algorithm that is implemented, fail parameter 312 processing (Section 2.2.2) and skip to the next 313 "key_item". 314 5) Let "param_value" be the string after the first "=" 315 character in "parameter". 316 6) If the first and last characters of "param_value" are 317 both DQUOTE: 319 1) Remove the first and last characters of 320 "param_value". 321 2) Replace quoted-pairs within "param_value" with the 322 octet following the backslash, as per [RFC7230] 323 Section 3.2.6. 324 7) If "param_value" does not conform to the syntax defined 325 for it by the parameter definition, fail parameter 326 processing Section 2.2.2 and skip to the next "key_item". 327 8) Run the identified processing algorithm on "field_value" 328 with the "param_value", and append the result to 329 "secondary_key". If parameter processing fails 330 Section 2.2.2, skip to the next "key_item". 331 9) Append a separator character (e.g., NULL) to 332 "secondary_key". 333 6) Return "secondary_key". 335 Note that this specification does not require that exact algorithm to 336 be implemented. However, implementations' observable behavior MUST 337 be identical to running it. This includes parameter processing 338 algorithms; implementations MAY use different internal artefacts for 339 secondary cache keys, as long as the results are the same. 341 Likewise, while the secondary cache key associated with both stored 342 and presented requests is required to use the most recently seen Key 343 header field for the resource in question, this can be achieved using 344 a variety of implementation strategies, including (but not limited 345 to): 347 o Generating a new secondary cache key for every stored response 348 associated with the resource upon each request. 349 o Caching the secondary cache key with the stored request/response 350 pair and re-generating it when the Key header field is observed to 351 change. 352 o Caching the secondary cache key with the stored response and 353 invalidating the stored response(s) when the Key header field is 354 observed to change. 356 2.2.1. Creating a Header Field Value 358 Given a header field name "target_field_name" and "header_list", a 359 list of ("field_name", "field_value") tuples: 361 1) Let "target_field_values" be an empty list. 362 2) For each ("field_name", "field_value") tuple in "header_list": 364 1) If "field_name" does not match "target_field_name", skip to 365 the next tuple. 366 2) Strip leading and trailing WSP from "field_value" and append 367 it to "target_field_values". 368 3) If "target_field_values" is empty, return an empty string. 369 4) Return the concatenation of "target_field_values", separating 370 each with "," characters. 372 2.2.2. Failing Parameter Processing 374 In some cases, a key parameter cannot determine a secondary cache key 375 corresponding to its nominated header field value. When this 376 happens, Key processing needs to fail safely, so that the correct 377 behavior is observed. 379 When this happens, implementations MUST either behave as if the Key 380 header was not present, or assure that the nominated header fields 381 being compared match, as per [RFC7234], Section 4.1. 383 2.3. Key Parameters 385 A Key parameter associates a name with a specific processing 386 algorithm that takes two inputs; a HTTP header value "header_value" 387 (as described in Section 2.2.1), and "parameter_value", a string that 388 indicates how the identified header should be processed. 390 The set of key parameters (and their associated processing 391 algorithms) is extensible; see Section 3. This document defines the 392 following key parameters: 394 2.3.1. div 396 The "div" parameter normalizes positive integer header values into 397 groups by dividing them by a configured value. 399 Its value's syntax is: 401 div = 1*DIGIT 403 To process a set of header fields against a div parameter, follow 404 these steps (or their equivalent): 406 1) If "parameter_value" is "0", fail parameter processing 407 Section 2.2.2. 408 2) If "header_value" is the empty string, return "none". 409 3) If "header_value" contains a ",", remove it and all subsequent 410 characters. 411 4) Remove all WSP characters from "header_value". 412 5) If "header_value" does not match the div ABNF rule, fail 413 parameter processing (Section 2.2.2). 414 6) Return the quotient of "header_value" / "parameter_value" 415 (omitting the modulus). 417 For example, the Key: 419 Key: Bar;div=5 420 indicates that the "Bar" header's field value should be partitioned 421 into groups of 5. Thus, the following field values would be 422 considered the same (because, divided by 5, they all result in 0): 424 Bar: 1 425 Bar: 3 , 42 426 Bar: 4, 1 428 whereas these would be considered to be in a different group 429 (because, divided by 5, they all result in 2); 431 Bar: 12 432 Bar: 10 433 Bar: 14, 1 435 2.3.2. partition 437 The "partition" parameter normalizes positive numeric header values 438 into pre-defined segments. 440 Its value's syntax is: 442 partition = [ segment ] *( ":" [ segment ] ) 443 segment = [ 0*DIGIT "." ] 1*DIGIT 445 To process a set of header fields against a partition parameter, 446 follow these steps (or their equivalent): 448 1) If "header_value" is the empty string, return "none". 449 2) If "header_value" contains a ",", remove it and all subsequent 450 characters. 451 3) Remove all WSP characters from "header_value". 452 4) If "header_value" does not match the segment ABNF rule, fail 453 parameter processing (Section 2.2.2). 454 5) Let "segment_id" be 0. 455 6) Create a list "segment_list" by splitting "parameter_value" on 456 ":" characters. 457 7) For each "segment_value" in "segment_list": 459 1) If "header_value" is less than "segment_value" when they are 460 numerically compared, skip to step 7. 461 2) Increment "segment_id" by 1. 462 8) Return "segment_id". 464 For example, the Key: 466 Key: Foo;partition=20:30:40 468 indicates that the "Foo" header's field value should be divided into 469 four segments: 471 o less than 20 472 o 20 to less than 30 473 o 30 to less than 40 474 o forty or greater 476 Thus, the following headers would all be normalized to the first 477 segment: 479 Foo: 1 480 Foo: 0 481 Foo: 4, 54 482 Foo: 19.9 484 whereas the following would fall into the second segment: 486 Foo: 20 487 Foo: 29.999 488 Foo: 24 , 10 490 2.3.3. match 492 The "match" parameter is used to determine if an exact value occurs 493 in a list of header values. It is case-sensitive. 495 Its value's syntax is: 497 match = ( token / quoted-string ) 499 To process a set of header fields against a match parameter, follow 500 these steps (or their equivalent): 502 1) If "header_value" is the empty string, return "none". 503 2) Create "header_list" by splitting "header_value" on "," 504 characters. 505 3) For each "header_item" in "header_list": 507 1) Remove leading and trailing WSP characters in "header_item". 508 2) If the value of "header_item" is character-for-character 509 identical to "parameter_value", return "1". 510 4) Return "0". 512 For example, the Key: 514 Key: Baz;match="charlie" 516 Would return "1" for the following header field values: 518 Baz: charlie 519 Baz: foo, charlie 520 Baz: bar, charlie , abc 522 and "0" for these: 524 Baz: theodore 525 Baz: joe, sam 526 Baz: "charlie" 527 Baz: Charlie 528 Baz: cha rlie 529 Baz: charlie2 531 2.3.4. substr 533 The "substr" parameter is used to determine if a value occurs as a 534 substring of an item in a list of header values. It is case- 535 sensitive. 537 Its value's syntax is: 539 substr = ( token / quoted-string ) 541 To process a set of header fields against a substr parameter, follow 542 these steps (or their equivalent): 544 1) If "header_value" is the empty string, return "none". 545 2) Create "header_list" by splitting "header_value" on "," 546 characters. 547 3) For each "header_item" in "header_list": 549 1) Remove leading and trailing WSP characters in "header_item". 550 2) If the value of "parameter_value" is character-for-character 551 present as a substring of "header_value", return "1". 552 4) Return "0". 554 For example, the Key: 556 Key: Abc;substr=bennet 558 Would return "1" for the following header field values: 560 Abc: bennet 561 Abc: foo, bennet 562 Abc: abennet00 563 Abc: bar, 99bennet , abc 564 Abc: "bennet" 566 and "0" for these: 568 Abc: theodore 569 Abc: joe, sam 570 Abc: Bennet 571 Abc: Ben net 573 2.3.5. param 575 The "param" parameter considers the request header field as a list of 576 key=value parameters, and uses the nominated key's value as the 577 secondary cache key. 579 Its value's syntax is: 581 param = ( token / quoted-string ) 583 To process a list of header fields against a param parameter, follow 584 these steps (or their equivalent): 586 1) Let "header_list" be an empty list. 587 2) Create "header_list_tmp1" by splitting header_value on "," 588 characters. 589 3) For each "header_item_tmp1" in "header_list_tmp1": 591 1) Create "header_list_tmp2" by splitting "header_item_tmp1" on 592 ";" characters. 593 2) For each "header_item_tmp2" in "header_list_tmp2": 595 1) Remove leading and trailing WSP from "header_item_tmp2". 596 2) Append "header_item_tmp2" to header_list. 597 4) For each "header_item" in "header_list": 599 1) If the "=" character does not occur within "header_item", 600 skip to the next "header_item". 602 2) Let "item_name" be the string occurring before the first "=" 603 character in "header_item". 604 3) If "item_name" does not case-insensitively match 605 "parameter_value", skip to the next "header_item". 606 4) Return the string occurring after the first "=" character in 607 "header_item". 608 5) Return the empty string. 610 Note that steps 2 and 3 accommodate semicolon-separated values, so 611 that it can be used with the Cookie request header field. 613 For example, the Key: 615 Key: Def;param=liam 617 The following headers would return the string (surrounded in single 618 quotes) indicated: 620 Def: liam=123 // '123' 621 Def: mno=456 // '' 622 Def: // '' 623 Def: abc=123; liam=890 // '890' 624 Def: liam="678" // '"678"' 626 3. IANA Considerations 628 This specification defines the HTTP Key Parameter Registry, 629 maintained at http://www.iana.org/assignments/http-parameters/http- 630 parameters.xhtml#key . 632 3.1. Procedure 634 Key Parameter registrations MUST include the following fields: 636 o Parameter Name: [name] 637 o Reference: [Pointer to specification text] 639 Values to be added to this namespace require IETF Review (see 640 Section 4.1 of [RFC5226]) and MUST conform to the purpose of content 641 coding defined in this section. 643 3.2. Registrations 645 This specification makes the following entries in the HTTP Key 646 Parameter Registry: 648 +----------------+---------------+ 649 | Parameter Name | Reference | 650 +----------------+---------------+ 651 | div | Section 2.3.1 | 652 | partition | Section 2.3.2 | 653 | match | Section 2.3.3 | 654 | substr | Section 2.3.4 | 655 | param | Section 2.3.5 | 656 +----------------+---------------+ 658 4. Security Considerations 660 Because Key is an alternative to Vary, it is possible for caches to 661 behave differently based upon whether they implement Key. Likewise, 662 because support for any one Key parameter is not required, it is 663 possible for different implementations of Key to behave differently. 664 In both cases, an attacker might be able to exploit these 665 differences. 667 This risk is mitigated by the requirement to fall back to Vary when 668 unsupported parameters are encountered, coupled with the requirement 669 that servers that use Key also include a relevant Vary header. 671 An attacker with the ability to inject response headers might be able 672 to perform a cache poisoning attack that tailors a response to a 673 specific user (e.g., by Keying to a Cookie that's specific to them). 674 While the attack is still possible without Key, the ability to tailor 675 is new. 677 When implemented, Key might result in a larger number of stored 678 responses for a given resource in caches; this, in turn, might be 679 used to create an attack upon the cache itself. Good cache 680 replacement algorithms and denial of service monitoring in cache 681 implementations are reasonable mitigations against this risk. 683 5. References 685 5.1. Normative References 687 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 688 Requirement Levels", BCP 14, RFC 2119, 689 DOI 10.17487/RFC2119, March 1997, 690 . 692 [RFC5234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax 693 Specifications: ABNF", STD 68, RFC 5234, 694 DOI 10.17487/RFC5234, January 2008, 695 . 697 [RFC7230] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 698 Protocol (HTTP/1.1): Message Syntax and Routing", 699 RFC 7230, DOI 10.17487/RFC7230, June 2014, 700 . 702 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 703 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 704 DOI 10.17487/RFC7231, June 2014, 705 . 707 [RFC7234] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, 708 Ed., "Hypertext Transfer Protocol (HTTP/1.1): Caching", 709 RFC 7234, DOI 10.17487/RFC7234, June 2014, 710 . 712 5.2. Informative References 714 [RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an 715 IANA Considerations Section in RFCs", BCP 26, RFC 5226, 716 DOI 10.17487/RFC5226, May 2008, 717 . 719 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, 720 DOI 10.17487/RFC6265, April 2011, 721 . 723 Appendix A. Acknowledgements 725 Thanks to Ilya Grigorik, Amos Jeffries and Yoav Weiss for their 726 feedback. 728 Appendix B. Changes 730 B.1. Since -00 732 o Issue 108 (field-name cardinality) closed with no action. 733 o Issue 104 (Support "Or" operator) closed with no action. 734 o Issue 107 (Whitespace requirement) addressed by allowing 735 whitespace around parameters. 736 o Issue 106 (Policy for Key parameter registry) closed with no 737 action. 739 Authors' Addresses 740 Roy T. Fielding 741 Adobe Systems Incorporated 743 Email: fielding@gbiv.com 744 URI: http://roy.gbiv.com/ 746 Mark Nottingham 748 Email: mnot@mnot.net 749 URI: https://www.mnot.net/