| rfc9111.original.xml | rfc9111.xml | |||
|---|---|---|---|---|
| <?xml version="1.0" encoding="UTF-8"?> | <?xml version="1.0" encoding="UTF-8"?> | |||
| <!-- | ||||
| This XML document is the output of clean-for-DTD.xslt; a tool that strips | <!-- draft submitted in xml v3 --> | |||
| extensions to RFC 7749 from documents for processing with xml2rfc. | ||||
| <!--TARGET-GENERATOR: 202007--> | <!DOCTYPE rfc [ | |||
| <!--TARGET-VOCABULARY: 3--> | <!ENTITY nbsp " "> | |||
| <?xml-stylesheet type='text/xsl' href='lib/myxml2rfc.xslt'?> | <!ENTITY zwsp "​"> | |||
| <?rfc toc="yes" ?> | <!ENTITY nbhy "‑"> | |||
| <?rfc tocdepth="4" ?> | <!ENTITY wj "⁠"> | |||
| <?rfc symrefs="yes" ?> | ]> | |||
| <?rfc sortrefs="yes" ?> | ||||
| <?rfc compact="yes"?> | ||||
| <?rfc subcompact="no" ?> | ||||
| <?rfc linkmailto="no" ?> | ||||
| <?rfc editing="no" ?> | ||||
| <?rfc comments="yes"?> | ||||
| <?rfc inline="yes"?> | ||||
| <?rfc rfcedstyle="yes"?> | ||||
| <?github-issue-label cache?> | ||||
| <rfc version="3" | <rfc version="3" | |||
| tocInclude="true" | ||||
| tocDepth="4" | tocDepth="4" | |||
| sortRefs="true" | sortRefs="true" | |||
| symRefs="true" | ||||
| submissionType="IETF" | ||||
| category="std" | category="std" | |||
| consensus="true" | ||||
| ipr="pre5378Trust200902" | ipr="pre5378Trust200902" | |||
| docName="draft-ietf-httpbis-cache-19" | docName="draft-ietf-httpbis-cache-19" | |||
| obsoletes="7234"> | number="9111" | |||
| <!--see https://trac.tools.ietf.org/tools/xml2rfc/trac/ticket/420--> | obsoletes="7234" | |||
| <?v3xml2rfc silence="Warning: Setting consensus="true" for IETF STD document"?> | updates="" | |||
| <?v3xml2rfc silence="Warning: Expected a valid submissionType (stream) setting"? | xmlns:xi="http://www.w3.org/2001/XInclude" | |||
| > | xml:lang="en"> | |||
| <front> | <front> | |||
| <title>HTTP Caching</title> | <title>HTTP Caching</title> | |||
| <seriesInfo name="RFC" value="9111"/> | ||||
| <seriesInfo name="STD" value="98"/> | ||||
| <author fullname="Roy T. Fielding" | <author fullname="Roy T. Fielding" | |||
| initials="R." | initials="R." | |||
| surname="Fielding" | surname="Fielding" | |||
| role="editor"> | role="editor"> | |||
| <organization>Adobe</organization> | <organization>Adobe</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <postalLine>345 Park Ave</postalLine> | <postalLine>345 Park Ave</postalLine> | |||
| <postalLine>San Jose, CA 95110</postalLine> | <postalLine>San Jose, CA 95110</postalLine> | |||
| <postalLine>United States of America</postalLine> | <postalLine>United States of America</postalLine> | |||
| skipping to change at line 55 ¶ | skipping to change at line 54 ¶ | |||
| <uri>https://roy.gbiv.com/</uri> | <uri>https://roy.gbiv.com/</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Mark Nottingham" | <author fullname="Mark Nottingham" | |||
| initials="M." | initials="M." | |||
| surname="Nottingham" | surname="Nottingham" | |||
| role="editor"> | role="editor"> | |||
| <organization>Fastly</organization> | <organization>Fastly</organization> | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <postalLine>Prahran VIC</postalLine> | <postalLine>Prahran</postalLine> | |||
| <postalLine>Australia</postalLine> | <postalLine>Australia</postalLine> | |||
| </postal> | </postal> | |||
| <email>mnot@mnot.net</email> | <email>mnot@mnot.net</email> | |||
| <uri>https://www.mnot.net/</uri> | <uri>https://www.mnot.net/</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <author fullname="Julian Reschke" | <author fullname="Julian Reschke" | |||
| initials="J." | initials="J." | |||
| surname="Reschke" | surname="Reschke" | |||
| role="editor"> | role="editor"> | |||
| skipping to change at line 77 ¶ | skipping to change at line 76 ¶ | |||
| <address> | <address> | |||
| <postal> | <postal> | |||
| <postalLine>Hafenweg 16</postalLine> | <postalLine>Hafenweg 16</postalLine> | |||
| <postalLine>48155 Münster</postalLine> | <postalLine>48155 Münster</postalLine> | |||
| <postalLine>Germany</postalLine> | <postalLine>Germany</postalLine> | |||
| </postal> | </postal> | |||
| <email>julian.reschke@greenbytes.de</email> | <email>julian.reschke@greenbytes.de</email> | |||
| <uri>https://greenbytes.de/tech/webdav/</uri> | <uri>https://greenbytes.de/tech/webdav/</uri> | |||
| </address> | </address> | |||
| </author> | </author> | |||
| <date year="2021" month="September" day="10"/> | <date year="2022" month="June"/> | |||
| <area>Applications and Real-Time</area> | <area>Applications and Real-Time</area> | |||
| <workgroup>HTTP Working Group</workgroup> | <workgroup>HTTP Working Group</workgroup> | |||
| <keyword>Hypertext Transfer Protocol</keyword> | <keyword>Hypertext Transfer Protocol</keyword> | |||
| <keyword>HTTP</keyword> | <keyword>HTTP</keyword> | |||
| <keyword>HTTP Caching</keyword> | <keyword>HTTP Caching</keyword> | |||
| <abstract> | <abstract> | |||
| <t> | <t> | |||
| The Hypertext Transfer Protocol (HTTP) is a stateless application-level | The Hypertext Transfer Protocol (HTTP) is a stateless application-level | |||
| protocol for distributed, collaborative, hypertext information systems. | protocol for distributed, collaborative, hypertext information systems. | |||
| This document defines HTTP caches and the associated header fields that | This document defines HTTP caches and the associated header fields that | |||
| control cache behavior or indicate cacheable response messages. | control cache behavior or indicate cacheable response messages. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This document obsoletes RFC 7234. | This document obsoletes RFC 7234. | |||
| </t> | </t> | |||
| </abstract> | </abstract> | |||
| <note title="Editorial Note"> | ||||
| <t>This note is to be removed before publishing as an RFC.</t> | ||||
| <t> | ||||
| Discussion of this draft takes place on the HTTP working group | ||||
| mailing list (ietf-http-wg@w3.org), which is archived at | ||||
| <eref target="https://lists.w3.org/Archives/Public/ietf-http-wg/" | ||||
| brackets="angle"/>. | ||||
| </t> | ||||
| <t> | ||||
| Working Group information can be found at <eref target="https://httpwg.org/" | ||||
| brackets="angle"/>; | ||||
| source code and issues list for this draft can be found at | ||||
| <eref target="https://github.com/httpwg/http-core" brackets="angle"/>. | ||||
| </t> | ||||
| <t> | ||||
| The changes in this draft are summarized in <xref target="changes.since.18"/ | ||||
| >. | ||||
| </t> | ||||
| </note> | ||||
| </front> | </front> | |||
| <middle> | <middle> | |||
| <section anchor="caching" title="Introduction"> | <section anchor="caching" title="Introduction"> | |||
| <t> | <t> | |||
| The Hypertext Transfer Protocol (HTTP) is a stateless application-level | The Hypertext Transfer Protocol (HTTP) is a stateless application-level | |||
| request/response protocol that uses extensible semantics and | request/response protocol that uses extensible semantics and | |||
| self-descriptive messages for flexible interaction with network-based | self-descriptive messages for flexible interaction with network-based | |||
| hypertext information systems. It is typically used for distributed informati on systems, where | hypertext information systems. It is typically used for distributed informati on systems, where | |||
| the use of response caches can improve performance. This document | the use of response caches can improve performance. This document | |||
| defines aspects of HTTP related to caching and reusing response | defines aspects of HTTP related to caching and reusing response | |||
| messages. | messages. | |||
| </t> | </t> | |||
| <iref item="cache"/> | <iref item="cache"/> | |||
| <t> | <t> | |||
| An HTTP <em>cache</em> is a local store of response messages and the | An HTTP "cache" is a local store of response messages and the | |||
| subsystem that controls storage, retrieval, and deletion of messages in it. | subsystem that controls storage, retrieval, and deletion of messages in it. | |||
| A cache stores cacheable responses to reduce the response time and | A cache stores cacheable responses to reduce the response time and | |||
| network bandwidth consumption on future equivalent requests. Any client or | network bandwidth consumption on future equivalent requests. Any client or | |||
| server <bcp14>MAY</bcp14> use a cache, though not when acting as a tunnel (<x ref target="HTTP" section="3.7"/>). | server <bcp14>MAY</bcp14> use a cache, though not when acting as a tunnel (<x ref target="HTTP" section="3.7"/>). | |||
| </t> | </t> | |||
| <iref item="shared cache"/> | <iref item="shared cache"/> | |||
| <iref item="private cache"/> | <iref item="private cache"/> | |||
| <t anchor="shared.and.private.caches"> | <t anchor="shared.and.private.caches"> | |||
| A <em>shared cache</em> is a cache that stores responses for reuse | A "shared cache" is a cache that stores responses for reuse | |||
| by more than one user; shared caches are usually (but not always) deployed | by more than one user; shared caches are usually (but not always) deployed | |||
| as a part of an intermediary. A <em>private cache</em>, in contrast, | as a part of an intermediary. A "private cache", in contrast, | |||
| is dedicated to a single user; often, they are deployed as a component of | is dedicated to a single user; often, they are deployed as a component of | |||
| a user agent. | a user agent. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The goal of HTTP caching is significantly improving performance | The goal of HTTP caching is significantly improving performance | |||
| by reusing a prior response message to satisfy a current request. | by reusing a prior response message to satisfy a current request. | |||
| A cache considers a stored response "fresh", as defined in | A cache considers a stored response "fresh", as defined in | |||
| <xref target="expiration.model"/>, if it can be reused without | <xref target="expiration.model"/>, if it can be reused without | |||
| "validation" (checking with the origin server to see if the cached response | "validation" (checking with the origin server to see if the cached response | |||
| remains valid for this request). A fresh response can therefore | remains valid for this request). A fresh response can therefore | |||
| skipping to change at line 155 ¶ | skipping to change at line 138 ¶ | |||
| "validation" (checking with the origin server to see if the cached response | "validation" (checking with the origin server to see if the cached response | |||
| remains valid for this request). A fresh response can therefore | remains valid for this request). A fresh response can therefore | |||
| reduce both latency and network overhead each time the cache reuses it. | reduce both latency and network overhead each time the cache reuses it. | |||
| When a cached response is not fresh, it might still be reusable if validation | When a cached response is not fresh, it might still be reusable if validation | |||
| can freshen it (<xref target="validation.model"/>) or if the | can freshen it (<xref target="validation.model"/>) or if the | |||
| origin is unavailable (<xref target="serving.stale.responses"/>). | origin is unavailable (<xref target="serving.stale.responses"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This document obsoletes <xref target="RFC7234" format="none">RFC 7234</xref>, | This document obsoletes <xref target="RFC7234" format="none">RFC 7234</xref>, | |||
| with the changes being summarized in <xref target="changes.from.rfc.7234"/>. | with the changes being summarized in <xref target="changes.from.rfc.7234"/>. | |||
| </t> | </t> | |||
| <section anchor="requirements.notation" title="Requirements Notation"> | <section anchor="requirements.notation" title="Requirements Notation"> | |||
| <t> | ||||
| The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL | <t> | |||
| NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", | The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", | |||
| "MAY", and "OPTIONAL" in this document are to be interpreted as | "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL | |||
| described in BCP 14 <xref target="RFC2119"/> | NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", | |||
| <xref target="RFC8174"/> when, and only when, they | "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>", | |||
| appear in all capitals, as shown here. | "<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are | |||
| to be interpreted as described in BCP 14 <xref target="RFC2119"/> | ||||
| <xref target="RFC8174"/> when, and only when, they appear in all capitals, | ||||
| as shown here. | ||||
| </t> | </t> | |||
| <t> | <t> | |||
| <xref target="HTTP" section="2"/> defines conformance criteria an d contains considerations regarding error handling. | <xref target="HTTP" section="2"/> defines conformance criteria an d contains considerations regarding error handling. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="notation" title="Syntax Notation"> | <section anchor="notation" title="Syntax Notation"> | |||
| <iref primary="true" item="Grammar" subitem="DIGIT"/> | <iref primary="true" item="Grammar" subitem="DIGIT"/> | |||
| <t> | <t> | |||
| This specification uses the Augmented Backus-Naur Form (ABNF) notation of | This specification uses the Augmented Backus-Naur Form (ABNF) notation of | |||
| <xref target="RFC5234"/>, extended with the notation for case-sensitivity | <xref target="RFC5234"/>, extended with the notation for case-sensitivity | |||
| in strings defined in <xref target="RFC7405"/>. | in strings defined in <xref target="RFC7405"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| It also uses a list extension, defined in <xref target="HTTP" section="5.6.1" />, | It also uses a list extension, defined in <xref target="HTTP" section="5.6.1" />, | |||
| that allows for compact definition of comma-separated lists using a '#' | that allows for compact definition of comma-separated lists using a "#" | |||
| operator (similar to how the '*' operator indicates repetition). <xref target | operator (similar to how the "*" operator indicates repetition). <xref target | |||
| ="collected.abnf"/> shows the collected grammar with all list | ="collected.abnf"/> shows the collected grammar with all list | |||
| operators expanded to standard ABNF notation. | operators expanded to standard ABNF notation. | |||
| </t> | </t> | |||
| <section anchor="abnf.imported" title="Imported Rules"> | <section anchor="abnf.imported" title="Imported Rules"> | |||
| <t anchor="core.rules"> | <t anchor="core.rules"> | |||
| The following core rule is included by | The following core rule is included by | |||
| reference, as defined in <xref target="RFC5234" sectionFormat="comma" section ="B.1"/>: | reference, as defined in <xref target="RFC5234" sectionFormat="comma" section ="B.1"/>: | |||
| DIGIT (decimal 0-9). | DIGIT (decimal 0-9). | |||
| </t> | </t> | |||
| <t anchor="imported.rules"> | <t anchor="imported.rules"> | |||
| <xref target="HTTP"/> defines the following rules: | <xref target="HTTP"/> defines the following rules: | |||
| </t> | </t> | |||
| <sourcecode type="abnf7230"><![CDATA[ HTTP-date = <HTTP-date | <sourcecode type="abnf9110"><![CDATA[ HTTP-date = <HTTP-date | |||
| , see [HTTP], Section 5.6.7> | , see [HTTP], Section 5.6.7> | |||
| OWS = <OWS, see [HTTP], Section 5.6.3> | OWS = <OWS, see [HTTP], Section 5.6.3> | |||
| field-name = <field-name, see [HTTP], Section 5.1> | field-name = <field-name, see [HTTP], Section 5.1> | |||
| quoted-string = <quoted-string, see [HTTP], Section 5.6.4> | quoted-string = <quoted-string, see [HTTP], Section 5.6.4> | |||
| token = <token, see [HTTP], Section 5.6.2> | token = <token, see [HTTP], Section 5.6.2> | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| </section> | </section> | |||
| <section anchor="delta-seconds" title="Delta Seconds"> | <section anchor="delta-seconds" title="Delta Seconds"> | |||
| <t> | <t> | |||
| The delta-seconds rule specifies a non-negative integer, representing time | The delta-seconds rule specifies a non-negative integer, representing time | |||
| in seconds. | in seconds. | |||
| </t> | </t> | |||
| <iref item="Grammar" primary="true" subitem="delta-seconds"/> | <iref item="Grammar" primary="true" subitem="delta-seconds"/> | |||
| <sourcecode type="abnf7230"><![CDATA[ delta-seconds = 1*DIGIT | <sourcecode type="abnf9110"><![CDATA[ delta-seconds = 1*DIGIT | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| A recipient parsing a delta-seconds value and converting it to binary form | A recipient parsing a delta-seconds value and converting it to binary form | |||
| ought to use an arithmetic type of at least 31 bits of non-negative integer | ought to use an arithmetic type of at least 31 bits of non-negative integer | |||
| range. | range. | |||
| If a cache receives a delta-seconds value greater than the greatest integer | If a cache receives a delta-seconds value greater than the greatest integer | |||
| it can represent, or if any of its subsequent calculations overflows, | it can represent, or if any of its subsequent calculations overflows, | |||
| the cache <bcp14>MUST</bcp14> consider the value to be 2147483648 | the cache <bcp14>MUST</bcp14> consider the value to be 2147483648 | |||
| (2<sup>31</sup>) or the greatest positive integer it can conveniently | (2<sup>31</sup>) or the greatest positive integer it can conveniently | |||
| represent. | represent. | |||
| skipping to change at line 250 ¶ | skipping to change at line 237 ¶ | |||
| Although caching is an entirely <bcp14>OPTIONAL</bcp14> feature of HTTP, it c an be | Although caching is an entirely <bcp14>OPTIONAL</bcp14> feature of HTTP, it c an be | |||
| assumed that reusing a cached response is desirable and that such reuse | assumed that reusing a cached response is desirable and that such reuse | |||
| is the default behavior when no requirement or local configuration | is the default behavior when no requirement or local configuration | |||
| prevents it. Therefore, HTTP cache requirements are focused | prevents it. Therefore, HTTP cache requirements are focused | |||
| on preventing a cache from either storing a non-reusable response or | on preventing a cache from either storing a non-reusable response or | |||
| reusing a stored response inappropriately, rather than mandating that | reusing a stored response inappropriately, rather than mandating that | |||
| caches always store and reuse particular responses. | caches always store and reuse particular responses. | |||
| </t> | </t> | |||
| <iref item="cache key"/> | <iref item="cache key"/> | |||
| <t> | <t> | |||
| The <em>cache key</em> is the information a cache uses to choose a response a nd | The "cache key" is the information a cache uses to choose a response and | |||
| is composed from, at a minimum, the request method and target | is composed from, at a minimum, the request method and target | |||
| URI used to retrieve the stored response; the method determines under which | URI used to retrieve the stored response; the method determines under which | |||
| circumstances that response can be used to satisfy a subsequent request. Howe ver, many | circumstances that response can be used to satisfy a subsequent request. Howe ver, many | |||
| HTTP caches in common use today only cache GET responses, and therefore only | HTTP caches in common use today only cache GET responses and therefore only | |||
| use the URI as the cache key, forwarding other methods. | use the URI as the cache key. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache might store multiple responses for a request target that is | A cache might store multiple responses for a request target that is | |||
| subject to content negotiation. Caches differentiate these responses | subject to content negotiation. Caches differentiate these responses | |||
| by incorporating some of the original request's header fields | by incorporating some of the original request's header fields | |||
| into the cache key as well, using information in the Vary | into the cache key as well, using information in the Vary | |||
| response header field, as per <xref target="caching.negotiated.responses"/>. | response header field, as per <xref target="caching.negotiated.responses"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Caches might incorporate additional material into the cache key. | Caches might incorporate additional material into the cache key. | |||
| skipping to change at line 280 ¶ | skipping to change at line 267 ¶ | |||
| Most commonly, caches store the successful result of a retrieval | Most commonly, caches store the successful result of a retrieval | |||
| request: i.e., a 200 (OK) response to a GET request, which | request: i.e., a 200 (OK) response to a GET request, which | |||
| contains a representation of the target resource | contains a representation of the target resource | |||
| (<xref target="HTTP" section="9.3.1"/>). However, it is also possible to stor e | (<xref target="HTTP" section="9.3.1"/>). However, it is also possible to stor e | |||
| redirects, negative results (e.g., 404 (Not Found)), | redirects, negative results (e.g., 404 (Not Found)), | |||
| incomplete results (e.g., 206 (Partial Content)), and | incomplete results (e.g., 206 (Partial Content)), and | |||
| responses to methods other than GET if the method's definition allows such | responses to methods other than GET if the method's definition allows such | |||
| caching and defines something suitable for use as a cache key. | caching and defines something suitable for use as a cache key. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache is <em>disconnected</em> when it cannot contact the origin | A cache is "disconnected" when it cannot contact the origin | |||
| server or otherwise find a forward path for a request. A | server or otherwise find a forward path for a request. A | |||
| disconnected cache can serve stale responses in some circumstances (<xref tar get="serving.stale.responses"/>). | disconnected cache can serve stale responses in some circumstances (<xref tar get="serving.stale.responses"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="response.cacheability" title="Storing Responses in Caches "> | <section anchor="response.cacheability" title="Storing Responses in Caches "> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST NOT</bcp14> store a response to a request unless: | A cache <bcp14>MUST NOT</bcp14> store a response to a request unless: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| <t>the request method is understood by the cache;</t> | <t>the request method is understood by the cache;</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the response status code is final (see | <t>the response status code is final (see | |||
| <xref target="HTTP" section="15"/>);</t> | <xref target="HTTP" section="15"/>);</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>if the response status code is 206 or 304, or the "must-unders tand" cache directive (see <xref target="cache-response-directive.must-understan d"/>) is present: the cache understands the response status code;</t> | <t>if the response status code is 206 or 304, or the must-underst and cache directive (see <xref target="cache-response-directive.must-understand" />) is present: the cache understands the response status code;</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the "no-store" cache directive is not present in the response | <t>the no-store cache directive is not present in the response | |||
| (see <xref target="cache-response-directive.no-store"/>);</t> | (see <xref target="cache-response-directive.no-store"/>);</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>if the cache is shared: the "private" response directive is ei ther not | <t>if the cache is shared: the private response directive is eith er not | |||
| present or allows a shared cache to store a modified response; | present or allows a shared cache to store a modified response; | |||
| see <xref target="cache-response-directive.private"/>);</t> | see <xref target="cache-response-directive.private"/>);</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>if the cache is shared: the Authorization header field | <t>if the cache is shared: the Authorization header field | |||
| is not present in the request | is not present in the request | |||
| (see <xref target="HTTP" section="11.6.2"/>) or a | (see <xref target="HTTP" section="11.6.2"/>) or a | |||
| response directive is present that explicitly allows shared caching | response directive is present that explicitly allows shared caching | |||
| (see <xref target="caching.authenticated.responses"/>); | (see <xref target="caching.authenticated.responses"/>); | |||
| and,</t> | and</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the response contains at least one of:</t> | <t>the response contains at least one of the following:</t> | |||
| <ul> | <ul> | |||
| <li>a public response directive | <li>a public response directive | |||
| (see <xref target="cache-response-directive.public"/>);</li> | (see <xref target="cache-response-directive.public"/>);</li> | |||
| <li>a private response directive, if the cache is not shared | <li>a private response directive, if the cache is not shared | |||
| (see <xref target="cache-response-directive.private"/>);</li> | (see <xref target="cache-response-directive.private"/>);</li> | |||
| <li>an <xref target="field.expires" format="none">Expires</xre f> header field | <li>an <xref target="field.expires" format="none">Expires</xre f> header field | |||
| (see <xref target="field.expires"/>);</li> | (see <xref target="field.expires"/>);</li> | |||
| <li>a max-age response directive | <li>a max-age response directive | |||
| (see <xref target="cache-response-directive.max-age"/>);</li> | (see <xref target="cache-response-directive.max-age"/>);</li> | |||
| <li>if the cache is shared: an s-maxage response directive | <li>if the cache is shared: an s-maxage response directive | |||
| (see <xref target="cache-response-directive.s-maxage"/>);</li> | (see <xref target="cache-response-directive.s-maxage"/>);</li> | |||
| <li>a Cache Control Extension that allows it to be cached | <li>a cache extension that allows it to be cached | |||
| (see <xref target="cache.control.extensions"/>); or,</li> | (see <xref target="cache.control.extensions"/>); or</li> | |||
| <li>a status code that is defined as heuristically cacheable | <li>a status code that is defined as heuristically cacheable | |||
| (see <xref target="heuristic.freshness"/>).</li> | (see <xref target="heuristic.freshness"/>).</li> | |||
| </ul> | </ul> | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| Note that a cache-control extension can override any of the requirements | Note that a cache extension can override any of the requirements | |||
| listed; see <xref target="cache.control.extensions"/>. | listed; see <xref target="cache.control.extensions"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| In this context, a cache has "understood" a request method or a response | In this context, a cache has "understood" a request method or a response | |||
| status code if it recognizes it and implements all specified | status code if it recognizes it and implements all specified | |||
| caching-related behavior. | caching-related behavior. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that, in normal operation, some caches will not store a response that | Note that, in normal operation, some caches will not store a response that | |||
| has neither a cache validator nor an explicit expiration time, as such | has neither a cache validator nor an explicit expiration time, as such | |||
| responses are not usually useful to store. However, caches are not | responses are not usually useful to store. However, caches are not | |||
| prohibited from storing such responses. | prohibited from storing such responses. | |||
| </t> | </t> | |||
| <section anchor="storing.fields" title="Storing Header and Trailer Fiel ds"> | <section anchor="storing.fields" title="Storing Header and Trailer Fiel ds"> | |||
| <t> | <t> | |||
| Caches <bcp14>MUST</bcp14> include all received response header fields — incl | Caches <bcp14>MUST</bcp14> include all received response header fields -- inc | |||
| uding | luding | |||
| unrecognised ones — when storing a response; this assures that new HTTP | unrecognized ones -- when storing a response; this assures that new HTTP | |||
| header fields can be successfully deployed. However, the following exceptions | header fields can be successfully deployed. However, the following exceptions | |||
| are made: | are made: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li>The Connection header field and fields whose names are listed in it are | <li>The Connection header field and fields whose names are listed in it are | |||
| required by <xref target="HTTP" section="7.6.1"/> to be removed before | required by <xref target="HTTP" section="7.6.1"/> to be removed before | |||
| forwarding the message. This <bcp14>MAY</bcp14> be implemented by doing so | forwarding the message. This <bcp14>MAY</bcp14> be implemented by doing so | |||
| before storage.</li> | before storage.</li> | |||
| <li>Likewise, some fields' semantics require them to be removed | <li>Likewise, some fields' semantics require them to be removed | |||
| before forwarding the message, and this <bcp14>MAY</bcp14> be implemented by doing so | before forwarding the message, and this <bcp14>MAY</bcp14> be implemented by doing so | |||
| skipping to change at line 380 ¶ | skipping to change at line 367 ¶ | |||
| directives can have arguments that prevent storage of header fields by all | directives can have arguments that prevent storage of header fields by all | |||
| caches and shared caches, respectively.</li> | caches and shared caches, respectively.</li> | |||
| <li>Header fields that are specific to the proxy that a cache use s when forwarding a request | <li>Header fields that are specific to the proxy that a cache use s when forwarding a request | |||
| <bcp14>MUST NOT</bcp14> be stored, unless the cache incorporates the identity of the | <bcp14>MUST NOT</bcp14> be stored, unless the cache incorporates the identity of the | |||
| proxy into the cache key. Effectively, this is limited to Proxy-Authenticate | proxy into the cache key. Effectively, this is limited to Proxy-Authenticate | |||
| (<xref target="HTTP" section="11.7.1"/>), Proxy-Authentication-Info | (<xref target="HTTP" section="11.7.1"/>), Proxy-Authentication-Info | |||
| (<xref target="HTTP" section="11.7.3"/>), and Proxy-Authorization | (<xref target="HTTP" section="11.7.3"/>), and Proxy-Authorization | |||
| (<xref target="HTTP" section="11.7.2"/>).</li> | (<xref target="HTTP" section="11.7.2"/>).</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| Caches <bcp14>MAY</bcp14> either store trailer fields separate from header fi elds, or | Caches <bcp14>MAY</bcp14> either store trailer fields separate from header fi elds or | |||
| discard them. Caches <bcp14>MUST NOT</bcp14> combine trailer fields with head er fields. | discard them. Caches <bcp14>MUST NOT</bcp14> combine trailer fields with head er fields. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="update" title="Updating Stored Header Fields"> | <section anchor="update" title="Updating Stored Header Fields"> | |||
| <t> | <t> | |||
| Caches are required to update a stored response's header fields from another | Caches are required to update a stored response's header fields from another | |||
| (typically newer) response in several situations; for example, see <xref targ | (typically newer) response in several situations; for example, see Sections < | |||
| et="combining.responses"/>, <xref target="freshening.responses"/> and | xref target="combining.responses" format="counter"/>, <xref target="freshening.r | |||
| <xref target="head.effects"/>. | esponses" format="counter"/>, and | |||
| <xref target="head.effects" format="counter"/>. | ||||
| </t> | </t> | |||
| <t> | <t> | |||
| When doing so, the cache <bcp14>MUST</bcp14> add each header field in the pro vided response | When doing so, the cache <bcp14>MUST</bcp14> add each header field in the pro vided response | |||
| to the stored response, replacing field values that are already present, | to the stored response, replacing field values that are already present, | |||
| with the following exceptions: | with the following exceptions: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li>Header fields excepted from storage in <xref target="storing. fields"/>,</li> | <li>Header fields excepted from storage in <xref target="storing. fields"/>,</li> | |||
| <li>Header fields that the cache's stored response depends upon, as described below,</li> | <li>Header fields that the cache's stored response depends upon, as described below,</li> | |||
| <li>Header fields that are automatically processed and removed by the recipient, as described below, and</li> | <li>Header fields that are automatically processed and removed by the recipient, as described below, and</li> | |||
| <li>The Content-Length header field.</li> | <li>The Content-Length header field.</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| In some cases, caches (especially in user agents) store the results of | In some cases, caches (especially in user agents) store the results of | |||
| processing the received response, rather than the response itself, | processing the received response, rather than the response itself, | |||
| and updating header fields that affect that processing can result in | and updating header fields that affect that processing can result in | |||
| inconsistent behavior and security issues. Caches in this situation <bcp14>MA Y</bcp14> | inconsistent behavior and security issues. Caches in this situation <bcp14>MA Y</bcp14> | |||
| omit these header fields from updating stored responses on an | omit these header fields from updating stored responses on an | |||
| exceptional basis, but <bcp14>SHOULD</bcp14> limit such omission to those fie lds | exceptional basis but <bcp14>SHOULD</bcp14> limit such omission to those fiel ds | |||
| necessary to assure integrity of the stored response. | necessary to assure integrity of the stored response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| For example, a browser might decode the content coding of a response | For example, a browser might decode the content coding of a response | |||
| while it is being received, creating a disconnect between the data it has | while it is being received, creating a disconnect between the data it has | |||
| stored and the response's original metadata. | stored and the response's original metadata. | |||
| Updating that stored metadata with a different Content-Encoding | Updating that stored metadata with a different Content-Encoding | |||
| header field would be problematic. Likewise, a browser might store a | header field would be problematic. Likewise, a browser might store a | |||
| post-parse HTML tree, rather than the content received in | post-parse HTML tree rather than the content received in | |||
| the response; updating the Content-Type header field would not be workable | the response; updating the Content-Type header field would not be workable | |||
| in this case, because any assumptions about the format made in parsing would | in this case because any assumptions about the format made in parsing would | |||
| now be invalid. | now be invalid. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Furthermore, some fields are automatically processed and removed by the | Furthermore, some fields are automatically processed and removed by the | |||
| HTTP implementation; for example, the Content-Range header field. | HTTP implementation, such as the Content-Range header field. | |||
| Implementations <bcp14>MAY</bcp14> automatically omit such header fields from updates, | Implementations <bcp14>MAY</bcp14> automatically omit such header fields from updates, | |||
| even when the processing does not actually occur. | even when the processing does not actually occur. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that the Content-* prefix is not a signal that a header field is omitted | Note that the Content-* prefix is not a signal that a header field is omitted | |||
| from update; it is a convention for MIME header fields, not HTTP. | from update; it is a convention for MIME header fields, not HTTP. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="incomplete.responses" title="Storing Incomplete Respon ses"> | <section anchor="incomplete.responses" title="Storing Incomplete Respon ses"> | |||
| <t> | <t> | |||
| If the request method is GET, the response status code is 200 | If the request method is GET, the response status code is 200 | |||
| (OK), and the entire response header section has been received, a | (OK), and the entire response header section has been received, a | |||
| cache <bcp14>MAY</bcp14> store a response body that is not complete (<xref ta rget="HTTP" section="3.4"/>) if the stored response | cache <bcp14>MAY</bcp14> store a response that is not complete (<xref target= "HTTP" section="6.1"/>) provided that the stored response | |||
| is recorded as being incomplete. Likewise, a 206 (Partial | is recorded as being incomplete. Likewise, a 206 (Partial | |||
| Content) response <bcp14>MAY</bcp14> be stored as if it were an incomplete | Content) response <bcp14>MAY</bcp14> be stored as if it were an incomplete | |||
| 200 (OK) response. However, a cache <bcp14>MUST NOT</bcp14> store | 200 (OK) response. However, a cache <bcp14>MUST NOT</bcp14> store | |||
| incomplete or partial-content responses if it does not support the | incomplete or partial-content responses if it does not support the | |||
| Range and Content-Range header fields or if | Range and Content-Range header fields or if | |||
| it does not understand the range units used in those fields. | it does not understand the range units used in those fields. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MAY</bcp14> complete a stored incomplete response by making a subsequent | A cache <bcp14>MAY</bcp14> complete a stored incomplete response by making a subsequent | |||
| range request (<xref target="HTTP" section="14.2"/>) and combining the succes sful response with the | range request (<xref target="HTTP" section="14.2"/>) and combining the succes sful response with the | |||
| skipping to change at line 479 ¶ | skipping to change at line 466 ¶ | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="caching.authenticated.responses" | <section anchor="caching.authenticated.responses" | |||
| title="Storing Responses to Authenticated Requests"> | title="Storing Responses to Authenticated Requests"> | |||
| <t> | <t> | |||
| A shared cache <bcp14>MUST NOT</bcp14> use a cached response to a request wit h an | A shared cache <bcp14>MUST NOT</bcp14> use a cached response to a request wit h an | |||
| Authorization header field (<xref target="HTTP" section="11.6.2"/>) to | Authorization header field (<xref target="HTTP" section="11.6.2"/>) to | |||
| satisfy any subsequent request unless the response contains a | satisfy any subsequent request unless the response contains a | |||
| <xref target="field.cache-control" format="none">Cache-Control</xref> field w ith a response directive | <xref target="field.cache-control" format="none">Cache-Control</xref> field w ith a response directive | |||
| (<xref target="cache-response-directive"/>) that allows it to be stored by | (<xref target="cache-response-directive"/>) that allows it to be stored by | |||
| a shared cache and the cache conforms to the requirements of that | a shared cache, and the cache conforms to the requirements of that | |||
| directive for that response. | directive for that response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| In this specification, the following response directives have such an effect: | In this specification, the following response directives have such an effect: | |||
| must-revalidate (<xref target="cache-response-directive.must-revalidate"/>), | must-revalidate (<xref target="cache-response-directive.must-revalidate"/>), | |||
| public (<xref target="cache-response-directive.public"/>), and | public (<xref target="cache-response-directive.public"/>), and | |||
| s-maxage (<xref target="cache-response-directive.s-maxage"/>). | s-maxage (<xref target="cache-response-directive.s-maxage"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="constructing.responses.from.caches" | <section anchor="constructing.responses.from.caches" | |||
| title="Constructing Responses from Caches"> | title="Constructing Responses from Caches"> | |||
| <t> | <t> | |||
| When presented with a request, a cache <bcp14>MUST NOT</bcp14> reuse a stored response | When presented with a request, a cache <bcp14>MUST NOT</bcp14> reuse a stored response | |||
| unless: | unless: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| <t>The presented target URI (<xref target="HTTP" section="7.1"/>) and | <t>the presented target URI (<xref target="HTTP" section="7.1"/>) and | |||
| that of the stored response match, and</t> | that of the stored response match, and</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the request method associated with the stored response allows it to | <t>the request method associated with the stored response allows it to | |||
| be used for the presented request, and</t> | be used for the presented request, and</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>request header fields nominated by the stored response (if any ) | <t>request header fields nominated by the stored response (if any ) | |||
| match those presented (see <xref target="caching.negotiated.responses"/>), an d</t> | match those presented (see <xref target="caching.negotiated.responses"/>), an d</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the stored response does not contain the no-cache cache direct ive | <t>the stored response does not contain the no-cache directive | |||
| (<xref target="cache-response-directive.no-cache"/>), unless it is | (<xref target="cache-response-directive.no-cache"/>), unless it is | |||
| successfully validated (<xref target="validation.model"/>), and</t> | successfully validated (<xref target="validation.model"/>), and</t> | |||
| </li> | </li> | |||
| <li> | <li> | |||
| <t>the stored response is either:</t> | <t>the stored response is one of the following:</t> | |||
| <ul> | <ul> | |||
| <li>fresh (see <xref target="expiration.model"/>), or</li> | <li>fresh (see <xref target="expiration.model"/>), or</li> | |||
| <li>allowed to be served stale (see <xref target="serving.stal e.responses"/>), or</li> | <li>allowed to be served stale (see <xref target="serving.stal e.responses"/>), or</li> | |||
| <li>successfully validated (see <xref target="validation.model "/>).</li> | <li>successfully validated (see <xref target="validation.model "/>).</li> | |||
| </ul> | </ul> | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| Note that a cache-control extension can override any of the requirements | Note that a cache extension can override any of the requirements | |||
| listed; see <xref target="cache.control.extensions"/>. | listed; see <xref target="cache.control.extensions"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| When a stored response is used to satisfy a request without validation, a | When a stored response is used to satisfy a request without validation, a | |||
| cache <bcp14>MUST</bcp14> generate an <xref target="field.age" format="none"> Age</xref> header field (<xref target="field.age"/>), replacing any present in t he response with a value | cache <bcp14>MUST</bcp14> generate an <xref target="field.age" format="none"> Age</xref> header field (<xref target="field.age"/>), replacing any present in t he response with a value | |||
| equal to the stored response's current_age; see <xref target="age.calculation s"/>. | equal to the stored response's current_age; see <xref target="age.calculation s"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST</bcp14> write through requests with methods that are unsa fe | A cache <bcp14>MUST</bcp14> write through requests with methods that are unsa fe | |||
| (<xref target="HTTP" section="9.2.1"/>) to the origin server; i.e., a cache i s not allowed to | (<xref target="HTTP" section="9.2.1"/>) to the origin server; i.e., a cache i s not allowed to | |||
| generate a reply to such a request before having forwarded the request and | generate a reply to such a request before having forwarded the request and | |||
| having received a corresponding response. | having received a corresponding response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Also, note that unsafe requests might invalidate already-stored responses; | Also, note that unsafe requests might invalidate already-stored responses; | |||
| see <xref target="invalidation"/>. | see <xref target="invalidation"/>. | |||
| </t> | </t> | |||
| <iref item="collapsed requests"/> | <iref item="collapsed requests"/> | |||
| <t> | <t> | |||
| A response that is stored or storable can be used to satisfy multiple | A cache can use a response that is stored or storable to satisfy | |||
| requests, provided that it is allowed to reuse that response for the requests | multiple requests, provided that it is allowed to reuse that response | |||
| in question. This enables caches to <em>collapse requests</em> — or combine m | for the requests in question. This enables a cache to "collapse | |||
| ultiple incoming requests into a single forward | requests" -- or combine multiple incoming requests into a single forward | |||
| request upon a cache miss — thereby reducing load on the origin server and ne | request upon a cache miss -- thereby reducing load on the origin server | |||
| twork. | and network. Note, however, that if the cache cannot use the returned | |||
| However, note that if the response returned is not able to be used for some o | response for some or all of the collapsed requests, it will need to | |||
| r all | forward the requests in order to satisfy them, potentially introducing | |||
| of the collapsed requests, additional latency might be introduced, because th | additional latency. | |||
| ey will | ||||
| need to be forwarded to be satisfied. | ||||
| </t> | </t> | |||
| <t> | <t> | |||
| When more than one suitable response is stored, a cache <bcp14>MUST</bcp14> u se the | When more than one suitable response is stored, a cache <bcp14>MUST</bcp14> u se the | |||
| most recent one (as determined by the Date header | most recent one (as determined by the Date header | |||
| field). It can also forward the request with "Cache-Control: max-age=0" or | field). It can also forward the request with "Cache-Control: max-age=0" or | |||
| "Cache-Control: no-cache" to disambiguate which response to use. | "Cache-Control: no-cache" to disambiguate which response to use. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache without a clock (<xref target="HTTP" section="5.6.7"/>) <bcp14>MUST</ bcp14> revalidate | A cache without a clock (<xref target="HTTP" section="5.6.7"/>) <bcp14>MUST</ bcp14> revalidate | |||
| stored responses upon every use. | stored responses upon every use. | |||
| skipping to change at line 576 ¶ | skipping to change at line 565 ¶ | |||
| and that stored response contains a Vary header field | and that stored response contains a Vary header field | |||
| (<xref target="HTTP" section="12.5.5"/>), | (<xref target="HTTP" section="12.5.5"/>), | |||
| the cache <bcp14>MUST NOT</bcp14> use that stored response without revalidati on unless | the cache <bcp14>MUST NOT</bcp14> use that stored response without revalidati on unless | |||
| all the presented request header fields nominated by that Vary field value | all the presented request header fields nominated by that Vary field value | |||
| match those fields in the original request (i.e., the | match those fields in the original request (i.e., the | |||
| request that caused the cached response to be stored). | request that caused the cached response to be stored). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The header fields from two requests are defined to match if | The header fields from two requests are defined to match if | |||
| and only if those in the first request can be transformed to those in the | and only if those in the first request can be transformed to those in the | |||
| second request by applying any of: | second request by applying any of the following: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| adding or removing whitespace, where allowed in the header field's | adding or removing whitespace, where allowed in the header field's | |||
| syntax | syntax | |||
| </li> | </li> | |||
| <li> | <li> | |||
| combining multiple header field lines with the same field name | combining multiple header field lines with the same field name | |||
| (see <xref target="HTTP" section="5.2"/>) | (see <xref target="HTTP" section="5.2"/>) | |||
| </li> | </li> | |||
| skipping to change at line 636 ¶ | skipping to change at line 625 ¶ | |||
| If no stored response matches, the cache cannot satisfy the presented | If no stored response matches, the cache cannot satisfy the presented | |||
| request. Typically, the request is forwarded to the origin server, | request. Typically, the request is forwarded to the origin server, | |||
| potentially with preconditions added to describe what responses the cache | potentially with preconditions added to describe what responses the cache | |||
| has already stored (<xref target="validation.model"/>). | has already stored (<xref target="validation.model"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="expiration.model" title="Freshness"> | <section anchor="expiration.model" title="Freshness"> | |||
| <iref item="fresh"/> | <iref item="fresh"/> | |||
| <iref item="stale"/> | <iref item="stale"/> | |||
| <t> | <t> | |||
| A <em>fresh</em> response is one whose age has not yet exceeded its | A "fresh" response is one whose age has not yet exceeded its | |||
| freshness lifetime. Conversely, a <em>stale</em> | freshness lifetime. Conversely, a "stale" response is one where it has. | |||
| response is one where it has. | ||||
| </t> | </t> | |||
| <iref item="freshness lifetime"/> | <iref item="freshness lifetime"/> | |||
| <iref item="explicit expiration time"/> | <iref item="explicit expiration time"/> | |||
| <iref item="heuristic expiration time"/> | <iref item="heuristic expiration time"/> | |||
| <t> | <t> | |||
| A response's <em>freshness lifetime</em> is the length of time | A response's "freshness lifetime" is the length of time | |||
| between its generation by the origin server and its expiration time. An | between its generation by the origin server and its expiration time. An | |||
| <em>explicit expiration time</em> is the time at which the origin | "explicit expiration time" is the time at which the origin | |||
| server intends that a stored response can no longer be used by a cache | server intends that a stored response can no longer be used by a cache | |||
| without further validation, whereas a <em>heuristic expiration | without further validation, whereas a "heuristic expiration | |||
| time</em> is assigned by a cache when no explicit expiration time is | time" is assigned by a cache when no explicit expiration time is | |||
| available. | available. | |||
| </t> | </t> | |||
| <iref item="age"/> | <iref item="age"/> | |||
| <t> | <t> | |||
| A response's <em>age</em> is the time that has passed since it was | A response's "age" is the time that has passed since it was | |||
| generated by, or successfully validated with, the origin server. | generated by, or successfully validated with, the origin server. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| When a response is fresh, it can be used to satisfy | When a response is fresh, it can be used to satisfy | |||
| subsequent requests without contacting the origin server, thereby improving | subsequent requests without contacting the origin server, thereby improving | |||
| efficiency. | efficiency. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The primary mechanism for determining freshness is for an origin server to | The primary mechanism for determining freshness is for an origin server to | |||
| provide an explicit expiration time in the future, using either the | provide an explicit expiration time in the future, using either the | |||
| skipping to change at line 685 ¶ | skipping to change at line 673 ¶ | |||
| cached response before reusing it for subsequent requests (see <xref target=" serving.stale.responses"/>). | cached response before reusing it for subsequent requests (see <xref target=" serving.stale.responses"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Since origin servers do not always provide explicit expiration times, | Since origin servers do not always provide explicit expiration times, | |||
| caches are also allowed to use a heuristic to determine an expiration time | caches are also allowed to use a heuristic to determine an expiration time | |||
| under certain circumstances (see <xref target="heuristic.freshness"/>). | under certain circumstances (see <xref target="heuristic.freshness"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The calculation to determine if a response is fresh is: | The calculation to determine if a response is fresh is: | |||
| </t> | </t> | |||
| <artwork type="code"><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
| response_is_fresh = (freshness_lifetime > current_age) | response_is_fresh = (freshness_lifetime > current_age) | |||
| ]]></artwork> | ]]></sourcecode> | |||
| <t> | <t> | |||
| freshness_lifetime is defined in <xref target="calculating.freshness.lifetime "/>; current_age is defined in | freshness_lifetime is defined in <xref target="calculating.freshness.lifetime "/>; current_age is defined in | |||
| <xref target="age.calculations"/>. | <xref target="age.calculations"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Clients can send the max-age or min-fresh request directives (<xref target="c ache-request-directive"/>) to suggest limits on the freshness | Clients can send the max-age or min-fresh request directives (<xref target="c ache-request-directive"/>) to suggest limits on the freshness | |||
| calculations for the corresponding response. However, caches are not | calculations for the corresponding response. However, caches are not | |||
| required to honor them. | required to honor them. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| skipping to change at line 722 ¶ | skipping to change at line 710 ¶ | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| Note that freshness applies only to cache operation; it cannot be used to | Note that freshness applies only to cache operation; it cannot be used to | |||
| force a user agent to refresh its display or reload a resource. See <xref tar get="history.lists"/> for an explanation of the difference between | force a user agent to refresh its display or reload a resource. See <xref tar get="history.lists"/> for an explanation of the difference between | |||
| caches and history mechanisms. | caches and history mechanisms. | |||
| </t> | </t> | |||
| <section anchor="calculating.freshness.lifetime" | <section anchor="calculating.freshness.lifetime" | |||
| title="Calculating Freshness Lifetime"> | title="Calculating Freshness Lifetime"> | |||
| <t> | <t> | |||
| A cache can calculate the freshness lifetime (denoted as | A cache can calculate the freshness lifetime (denoted as | |||
| freshness_lifetime) of a response by using the first match of: | freshness_lifetime) of a response by evaluating the following rules and using the first match: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li>If the cache is shared and the s-maxage response directive | <li>If the cache is shared and the s-maxage response directive | |||
| (<xref target="cache-response-directive.s-maxage"/>) is present, use its valu e, | (<xref target="cache-response-directive.s-maxage"/>) is present, use its valu e, | |||
| or</li> | or</li> | |||
| <li>If the max-age response directive (<xref target="cache-res ponse-directive.max-age"/>) is present, use its value, or</li> | <li>If the max-age response directive (<xref target="cache-res ponse-directive.max-age"/>) is present, use its value, or</li> | |||
| <li>If the <xref target="field.expires" format="none">Expires< /xref> response header field | <li>If the <xref target="field.expires" format="none">Expires< /xref> response header field | |||
| (<xref target="field.expires"/>) is present, use its value minus the | (<xref target="field.expires"/>) is present, use its value minus the | |||
| value of the Date response header field | value of the Date response header field | |||
| (using the time the message was received if it is not present, as per <xref target="HTTP" section="6.6.1"/>), or</li> | (using the time the message was received if it is not present, as per <xref target="HTTP" section="6.6.1"/>), or</li> | |||
| <li>Otherwise, no explicit expiration time is present in the r esponse. A | <li>Otherwise, no explicit expiration time is present in the r esponse. A | |||
| heuristic freshness lifetime might be applicable; see <xref target="heuristic .freshness"/>.</li> | heuristic freshness lifetime might be applicable; see <xref target="heuristic .freshness"/>.</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| Note that this calculation is intended to reduce clock skew by using the | Note that this calculation is intended to reduce clock skew by using the | |||
| clock information provided by the origin server whenever possible. | clock information provided by the origin server whenever possible. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| When there is more than one value present for a given directive (e.g., two | When there is more than one value present for a given directive (e.g., two | |||
| <xref target="field.expires" format="none">Expires</xref> header field lines or multiple Cache-Control: max-age | <xref target="field.expires" format="none">Expires</xref> header field lines or multiple Cache-Control: max-age | |||
| directives), either the first occurrence should be used, or the response shou ld | directives), either the first occurrence should be used or the response shoul d | |||
| be considered stale. If directives conflict (e.g., | be considered stale. If directives conflict (e.g., | |||
| both max-age and no-cache are present), the most restrictive directive should | both max-age and no-cache are present), the most restrictive directive should | |||
| be honored. Caches are encouraged to consider responses that have | be honored. Caches are encouraged to consider responses that have | |||
| invalid freshness information (e.g., a max-age directive with non-integer con tent) to | invalid freshness information (e.g., a max-age directive with non-integer con tent) to | |||
| be stale. | be stale. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="heuristic.freshness" title="Calculating Heuristic F reshness"> | <section anchor="heuristic.freshness" title="Calculating Heuristic F reshness"> | |||
| <iref item="heuristically cacheable"/> | <iref item="heuristically cacheable"/> | |||
| <t> | <t> | |||
| Since origin servers do not always provide explicit expiration times, a | Since origin servers do not always provide explicit expiration times, a | |||
| cache <bcp14>MAY</bcp14> assign a heuristic expiration time when an explicit time is not | cache <bcp14>MAY</bcp14> assign a heuristic expiration time when an explicit time is not | |||
| specified, employing algorithms that use other field values (such as | specified, employing algorithms that use other field values (such as | |||
| the Last-Modified time) to estimate a plausible expiration | the Last-Modified time) to estimate a plausible expiration | |||
| time. This specification does not provide specific algorithms, but does | time. This specification does not provide specific algorithms, but it does | |||
| impose worst-case constraints on their results. | impose worst-case constraints on their results. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST NOT</bcp14> use heuristics to determine freshness when an explicit | A cache <bcp14>MUST NOT</bcp14> use heuristics to determine freshness when an explicit | |||
| expiration time is present in the stored response. Because of the | expiration time is present in the stored response. Because of the | |||
| requirements in <xref target="response.cacheability"/>, this means that | requirements in <xref target="response.cacheability"/>, | |||
| heuristics can only be used on responses without explicit | heuristics can only be used on responses without explicit | |||
| freshness whose status codes are defined as <em>heuristically cacheable</em> | freshness whose status codes are defined as "heuristically cacheable" (e.g., | |||
| (e.g., see | see | |||
| <xref target="HTTP" section="15.1"/>), and those responses without | <xref target="HTTP" section="15.1"/>) and on responses without | |||
| explicit freshness that have been marked as explicitly cacheable (e.g., | explicit freshness that have been marked as explicitly cacheable (e.g., | |||
| with a "public" response directive). | with a public response directive). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that in previous specifications heuristically cacheable response status | Note that in previous specifications, heuristically cacheable response status | |||
| codes were called "cacheable by default." | codes were called "cacheable by default". | |||
| </t> | </t> | |||
| <t> | <t> | |||
| If the response has a Last-Modified header field | If the response has a Last-Modified header field | |||
| (<xref target="HTTP" section="8.8.2"/>), caches are encouraged to use a heuri stic | (<xref target="HTTP" section="8.8.2"/>), caches are encouraged to use a heuri stic | |||
| expiration value that is no more than some fraction of the interval since | expiration value that is no more than some fraction of the interval since | |||
| that time. A typical setting of this fraction might be 10%. | that time. A typical setting of this fraction might be 10%. | |||
| </t> | </t> | |||
| <aside> | <aside> | |||
| <t> | <t> | |||
| <strong>Note:</strong> | <strong>Note:</strong> | |||
| <xref target="RFC2616" section="13.9"/> prohibited caches | A previous version of the HTTP specification | |||
| (<xref target="RFC2616" section="13.9"/>) prohibited caches | ||||
| from calculating heuristic freshness for URIs with query components | from calculating heuristic freshness for URIs with query components | |||
| (i.e., those containing '?'). In practice, this has not been widely | (i.e., those containing "?"). In practice, this has not been widely | |||
| implemented. Therefore, origin servers are encouraged to send explicit | implemented. Therefore, origin servers are encouraged to send explicit | |||
| directives (e.g., Cache-Control: no-cache) if they wish to prevent | directives (e.g., Cache-Control: no-cache) if they wish to prevent | |||
| caching. | caching. | |||
| </t> | </t> | |||
| </aside> | </aside> | |||
| </section> | </section> | |||
| <section anchor="age.calculations" title="Calculating Age"> | <section anchor="age.calculations" title="Calculating Age"> | |||
| <t> | <t> | |||
| The <xref target="field.age" format="none">Age</xref> header field is used to convey an estimated | The <xref target="field.age" format="none">Age</xref> header field is used to convey an estimated | |||
| age of the response message when obtained from a cache. The Age field value | age of the response message when obtained from a cache. The Age field value | |||
| is the cache's estimate of the number of seconds since the origin server gene rated | is the cache's estimate of the number of seconds since the origin server gene rated | |||
| or validated the response. The Age value is therefore | or validated the response. The Age value is therefore | |||
| the sum of the time that the response has been resident in each of the | the sum of the time that the response has been resident in each of the | |||
| caches along the path from the origin server, plus the time it | caches along the path from the origin server, plus the time it | |||
| has been in transit along network paths. | has been in transit along network paths. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Age calculation uses the following data: | Age calculation uses the following data: | |||
| </t> | </t> | |||
| <dl newline="false"> | <dl newline="true"> | |||
| <dt> | <dt> | |||
| <em>age_value</em> | "age_value" | |||
| </dt> | </dt> | |||
| <dd> | <dd> | |||
| The term "age_value" denotes the value of the <xref target="field.age" form at="none">Age</xref> | The term "age_value" denotes the value of the <xref target="field.age" form at="none">Age</xref> | |||
| header field (<xref target="field.age"/>), in a form appropriate for | header field (<xref target="field.age"/>), in a form appropriate for | |||
| arithmetic operation; or 0, if not available. | arithmetic operation; or 0, if not available. | |||
| </dd> | </dd> | |||
| <dt> | <dt> | |||
| <em>date_value</em> | "date_value" | |||
| </dt> | </dt> | |||
| <dd> | <dd> | |||
| The term "date_value" denotes the value of | The term "date_value" denotes the value of | |||
| the Date header field, in a form appropriate for arithmetic | the Date header field, in a form appropriate for arithmetic | |||
| operations. See <xref target="HTTP" section="6.6.1"/> for the definition of the Date header | operations. See <xref target="HTTP" section="6.6.1"/> for the definition of the Date header | |||
| field, and for requirements regarding responses without it. | field and for requirements regarding responses without it. | |||
| </dd> | </dd> | |||
| <dt> | <dt> | |||
| <em>now</em> | "now" | |||
| </dt> | </dt> | |||
| <dd> | <dd> | |||
| The term "now" means the current value of this implementation's clock | The term "now" means the current value of this implementation's clock | |||
| (<xref target="HTTP" section="5.6.7"/>). | (<xref target="HTTP" section="5.6.7"/>). | |||
| </dd> | </dd> | |||
| <dt> | <dt> | |||
| <em>request_time</em> | "request_time" | |||
| </dt> | </dt> | |||
| <dd> | <dd> | |||
| The value of the clock at the time of the request that | The value of the clock at the time of the request that | |||
| resulted in the stored response. | resulted in the stored response. | |||
| </dd> | </dd> | |||
| <dt> | <dt> | |||
| <em>response_time</em> | "response_time" | |||
| </dt> | </dt> | |||
| <dd> | <dd> | |||
| The value of the clock at the time the response | The value of the clock at the time the response | |||
| was received. | was received. | |||
| </dd> | </dd> | |||
| </dl> | </dl> | |||
| <t> | <t> | |||
| A response's age can be calculated in two entirely independent ways: | A response's age can be calculated in two entirely independent ways: | |||
| </t> | </t> | |||
| <ol> | <ol> | |||
| <li>the "apparent_age": response_time minus date_value, if the | <li>the "apparent_age": response_time minus date_value, if the | |||
| implementation's | implementation's | |||
| clock is reasonably well synchronized to the origin server's clock. If | clock is reasonably well synchronized to the origin server's clock. If | |||
| the result is negative, the result is replaced by zero.</li> | the result is negative, the result is replaced by zero.</li> | |||
| <li>the "corrected_age_value", if all of the caches along the response | <li>the "corrected_age_value", if all of the caches along the response | |||
| path implement HTTP/1.1 or greater. A cache <bcp14>MUST</bcp14> interpret thi s value | path implement HTTP/1.1 or greater. A cache <bcp14>MUST</bcp14> interpret thi s value | |||
| relative to the time the request was initiated, not the time that the | relative to the time the request was initiated, not the time that the | |||
| response was received.</li> | response was received.</li> | |||
| </ol> | </ol> | |||
| <artwork type="code"><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
| apparent_age = max(0, response_time - date_value); | apparent_age = max(0, response_time - date_value); | |||
| response_delay = response_time - request_time; | response_delay = response_time - request_time; | |||
| corrected_age_value = age_value + response_delay; | corrected_age_value = age_value + response_delay; | |||
| ]]></artwork> | ]]></sourcecode> | |||
| <t> | <t> | |||
| The corrected_age_value <bcp14>MAY</bcp14> be used as the corrected_initial_a ge. In | The corrected_age_value <bcp14>MAY</bcp14> be used as the corrected_initial_a ge. In | |||
| circumstances where very old cache implementations that might not correctly | circumstances where very old cache implementations that might not correctly | |||
| insert <xref target="field.age" format="none">Age</xref> are present, correct ed_initial_age can be calculated | insert <xref target="field.age" format="none">Age</xref> are present, correct ed_initial_age can be calculated | |||
| more conservatively as | more conservatively as | |||
| </t> | </t> | |||
| <artwork type="code"><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
| corrected_initial_age = max(apparent_age, corrected_age_value); | corrected_initial_age = max(apparent_age, corrected_age_value); | |||
| ]]></artwork> | ]]></sourcecode> | |||
| <t> | <t> | |||
| The current_age of a stored response can then be calculated by adding the | The current_age of a stored response can then be calculated by adding the | |||
| time (in seconds) since the stored response was last validated by | time (in seconds) since the stored response was last validated by | |||
| the origin server to the corrected_initial_age. | the origin server to the corrected_initial_age. | |||
| </t> | </t> | |||
| <artwork type="code"><![CDATA[ | <sourcecode type="pseudocode"><![CDATA[ | |||
| resident_time = now - response_time; | resident_time = now - response_time; | |||
| current_age = corrected_initial_age + resident_time; | current_age = corrected_initial_age + resident_time; | |||
| ]]></artwork> | ]]></sourcecode> | |||
| </section> | </section> | |||
| <section anchor="serving.stale.responses" title="Serving Stale Respo nses"> | <section anchor="serving.stale.responses" title="Serving Stale Respo nses"> | |||
| <t> | <t> | |||
| A "stale" response is one that either has explicit expiry information or is | A "stale" response is one that either has explicit expiry information or is | |||
| allowed to have heuristic expiry calculated, but is not fresh according to | allowed to have heuristic expiry calculated, but is not fresh according to | |||
| the calculations in <xref target="expiration.model"/>. | the calculations in <xref target="expiration.model"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST NOT</bcp14> generate a stale response if it is prohibited by an | A cache <bcp14>MUST NOT</bcp14> generate a stale response if it is prohibited by an | |||
| explicit in-protocol directive (e.g., by a "no-cache" cache | explicit in-protocol directive (e.g., by a no-cache response | |||
| directive, a "must-revalidate" cache-response-directive, or an applicable | directive, a must-revalidate response directive, or an applicable | |||
| "s-maxage" or "proxy-revalidate" cache-response-directive; see <xref target=" | s-maxage or proxy-revalidate response directive; see <xref target="cache-resp | |||
| cache-response-directive"/>). | onse-directive"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST NOT</bcp14> generate a stale response unless it is discon nected | A cache <bcp14>MUST NOT</bcp14> generate a stale response unless it is discon nected | |||
| or doing so is explicitly permitted by the client or origin server | or doing so is explicitly permitted by the client or origin server | |||
| (e.g., by the max-stale request directive in <xref target="cache-request-dire | (e.g., by the max-stale request directive in <xref target="cache-request-dire | |||
| ctive"/>, by extension directives such as those | ctive"/>, extension directives such as those | |||
| defined in <xref target="RFC5861"/>, or by configuration in accordance | defined in <xref target="RFC5861"/>, or configuration in accordance | |||
| with an out-of-band contract). | with an out-of-band contract). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="validation.model" title="Validation"> | <section anchor="validation.model" title="Validation"> | |||
| <t> | <t> | |||
| When a cache has one or more stored responses for a requested URI, but | When a cache has one or more stored responses for a requested URI, but | |||
| cannot serve any of them (e.g., because they are not fresh, or one cannot | cannot serve any of them (e.g., because they are not fresh, or one cannot | |||
| be chosen; see <xref target="caching.negotiated.responses"/>), it can use | be chosen; see <xref target="caching.negotiated.responses"/>), it can use | |||
| the conditional request mechanism (<xref target="HTTP" section="13.1"/>) in t he forwarded request to | the conditional request mechanism (<xref target="HTTP" section="13"/>) in the forwarded request to | |||
| give the next inbound server an opportunity to choose a valid stored | give the next inbound server an opportunity to choose a valid stored | |||
| response to use, updating the stored metadata in the process, or to replace | response to use, updating the stored metadata in the process, or to replace | |||
| the stored response(s) with a new response. This process is known as | the stored response(s) with a new response. This process is known as | |||
| <em>validating</em> or <em>revalidating</em> the stored | "validating" or "revalidating" the stored | |||
| response. | response. | |||
| </t> | </t> | |||
| <section anchor="validation.sent" title="Sending a Validation Reques t"> | <section anchor="validation.sent" title="Sending a Validation Reques t"> | |||
| <iref item="validator"/> | <iref item="validator"/> | |||
| <t> | <t> | |||
| When generating a conditional request for validation, a cache starts with | When generating a conditional request for validation, a cache either starts w | |||
| either a request it is attempting to satisfy, or — if it is initiating | ith | |||
| the request independently — it synthesises a request using a stored | a request it is attempting to satisfy or -- if it is initiating | |||
| the request independently -- synthesizes a request using a stored | ||||
| response by copying the method, target URI, and request header fields | response by copying the method, target URI, and request header fields | |||
| identified by the Vary header field (<xref target="caching.negotiated.respons es"/>). | identified by the Vary header field (<xref target="caching.negotiated.respons es"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| It then updates that request with one or more precondition header fields. | It then updates that request with one or more precondition header fields. | |||
| These contain validator metadata sourced from stored response(s) that have | These contain validator metadata sourced from a stored response(s) that has | |||
| the same URI. Typically, this will include only those stored responses(s) tha | the same URI. Typically, this will include only the stored response(s) that | |||
| t | has the same cache key, although a cache is allowed to validate | |||
| have the same cache key, although a cache is allowed to validate | ||||
| a response that it cannot choose with the request header fields it is sending | a response that it cannot choose with the request header fields it is sending | |||
| (see <xref target="caching.negotiated.responses"/>). | (see <xref target="caching.negotiated.responses"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The precondition header fields are then compared by recipients to | The precondition header fields are then compared by recipients to | |||
| determine whether any stored response is equivalent to a current | determine whether any stored response is equivalent to a current | |||
| representation of the resource. | representation of the resource. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| One such validator is the timestamp given in a Last-Modified | One such validator is the timestamp given in a Last-Modified | |||
| header field (<xref target="HTTP" section="8.8.2"/>), which can be used in an | header field (<xref target="HTTP" section="8.8.2"/>), which can be used in an | |||
| If-Modified-Since header field for response validation, or | If-Modified-Since header field for response validation, or | |||
| in an If-Unmodified-Since or If-Range header | in an If-Unmodified-Since or If-Range header | |||
| field for representation selection (i.e., the client is referring | field for representation selection (i.e., the client is referring | |||
| specifically to a previously obtained representation with that timestamp). | specifically to a previously obtained representation with that timestamp). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Another validator is the entity-tag given in an ETag | Another validator is the entity tag given in an ETag | |||
| field (<xref target="HTTP" section="8.8.3"/>). One or more entity-tags, indic | field (<xref target="HTTP" section="8.8.3"/>). One or more entity tags, indic | |||
| ating one or more | ating one or more | |||
| stored responses, can be used in an If-None-Match header | stored responses, can be used in an If-None-Match header | |||
| field for response validation, or in an If-Match or | field for response validation, or in an If-Match or | |||
| If-Range header field for representation selection (i.e., | If-Range header field for representation selection (i.e., | |||
| the client is referring specifically to one or more previously obtained | the client is referring specifically to one or more previously obtained | |||
| representations with the listed entity-tags). | representations with the listed entity tags). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| When generating a conditional request for validation, a cache: | When generating a conditional request for validation, a cache: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| <bcp14>MUST</bcp14> send the relevant entity-tags | <bcp14>MUST</bcp14> send the relevant entity tags | |||
| (using If-Match, If-None-Match, or | (using If-Match, If-None-Match, or | |||
| If-Range) if the entity-tags were provided in the | If-Range) if the entity tags were provided in the | |||
| stored response(s) being validated.</li> | stored response(s) being validated.</li> | |||
| <li> | <li> | |||
| <bcp14>SHOULD</bcp14> send the Last-Modified value (using | <bcp14>SHOULD</bcp14> send the Last-Modified value (using | |||
| If-Modified-Since) if the request is not for a subrange, | If-Modified-Since) if the request is not for a subrange, | |||
| a single stored response is being validated, and that response | a single stored response is being validated, and that response | |||
| contains a Last-Modified value.</li> | contains a Last-Modified value.</li> | |||
| <li> | <li> | |||
| <bcp14>MAY</bcp14> send the Last-Modified value (using | <bcp14>MAY</bcp14> send the Last-Modified value (using | |||
| If-Unmodified-Since or If-Range) if | If-Unmodified-Since or If-Range) if | |||
| the request is for a subrange, a single stored response is being | the request is for a subrange, a single stored response is being | |||
| validated, and that response contains only a Last-Modified value | validated, and that response contains only a Last-Modified value | |||
| (not an entity-tag).</li> | (not an entity tag).</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| In most cases, both validators are generated in cache validation requests, | In most cases, both validators are generated in cache validation requests, | |||
| even when entity-tags are clearly superior, to allow old intermediaries | even when entity tags are clearly superior, to allow old intermediaries | |||
| that do not understand entity-tag preconditions to respond appropriately. | that do not understand entity tag preconditions to respond appropriately. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="validation.received" | <section anchor="validation.received" | |||
| title="Handling a Received Validation Request"> | title="Handling a Received Validation Request"> | |||
| <t> | <t> | |||
| Each client in the request chain may have its own cache, so it is common | Each client in the request chain may have its own cache, so it is common | |||
| for a cache at an intermediary to receive conditional requests from other | for a cache at an intermediary to receive conditional requests from other | |||
| (outbound) caches. Likewise, some user agents make use of conditional | (outbound) caches. Likewise, some user agents make use of conditional | |||
| requests to limit data transfers to recently modified representations or to | requests to limit data transfers to recently modified representations or to | |||
| complete the transfer of a partially retrieved representation. | complete the transfer of a partially retrieved representation. | |||
| skipping to change at line 1042 ¶ | skipping to change at line 1031 ¶ | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache that implements partial responses to range requests, as defined in | A cache that implements partial responses to range requests, as defined in | |||
| <xref target="HTTP" section="14.2"/>, also needs to evaluate a received | <xref target="HTTP" section="14.2"/>, also needs to evaluate a received | |||
| If-Range header field (<xref target="HTTP" section="13.1.5"/>) | If-Range header field (<xref target="HTTP" section="13.1.5"/>) | |||
| with respect to the cache's chosen response. | with respect to the cache's chosen response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| When a cache decides to forward a request to revalidate its own stored | When a cache decides to forward a request to revalidate its own stored | |||
| responses for a | responses for a | |||
| request that contains an If-None-Match list of entity-tags, | request that contains an If-None-Match list of entity tags, | |||
| the cache <bcp14>MAY</bcp14> combine the received list with a list of entity- | the cache <bcp14>MAY</bcp14> combine the received list with a list of entity | |||
| tags | tags | |||
| from its own stored set of responses (fresh or stale) and send the union of | from its own stored set of responses (fresh or stale) and send the union of | |||
| the two lists as a replacement If-None-Match header | the two lists as a replacement If-None-Match header | |||
| field value in the forwarded request. | field value in the forwarded request. | |||
| If a stored response contains only partial content, the | If a stored response contains only partial content, the | |||
| cache <bcp14>MUST NOT</bcp14> include its entity-tag in the union unless the request is | cache <bcp14>MUST NOT</bcp14> include its entity tag in the union unless the request is | |||
| for a range that would be fully satisfied by that partial stored response. | for a range that would be fully satisfied by that partial stored response. | |||
| If the response to the forwarded request is | If the response to the forwarded request is | |||
| 304 (Not Modified) and has an ETag field value with | 304 (Not Modified) and has an ETag field value with | |||
| an entity-tag that is not in the client's list, the cache <bcp14>MUST</bcp14> | an entity tag that is not in the client's list, the cache <bcp14>MUST</bcp14> | |||
| generate a 200 (OK) response for the client by reusing its | generate a 200 (OK) response for the client by reusing its | |||
| corresponding stored response, as updated by the 304 response metadata | corresponding stored response, as updated by the 304 response metadata | |||
| (<xref target="freshening.responses"/>). | (<xref target="freshening.responses"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="validation.response" title="Handling a Validation R esponse"> | <section anchor="validation.response" title="Handling a Validation R esponse"> | |||
| <t> | <t> | |||
| Cache handling of a response to a conditional request depends upon its | Cache handling of a response to a conditional request depends upon its | |||
| status code: | status code: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| A 304 (Not Modified) response status code indicates | A 304 (Not Modified) response status code indicates | |||
| that the stored response can be updated and reused; see <xref target="fresh ening.responses"/>. | that the stored response can be updated and reused; see <xref target="fresh ening.responses"/>. | |||
| </li> | </li> | |||
| <li> | <li> | |||
| A full response (i.e., one containing content) indicates that none | A full response (i.e., one containing content) indicates that none | |||
| of the stored responses nominated in the conditional request is | of the stored responses nominated in the conditional request are | |||
| suitable. Instead, the cache <bcp14>MUST</bcp14> use the full response to | suitable. Instead, the cache <bcp14>MUST</bcp14> use the full response to | |||
| satisfy the request. The cache <bcp14>MAY</bcp14> store such a full respons e, | satisfy the request. The cache <bcp14>MAY</bcp14> store such a full respons e, | |||
| subject to its constraints (see <xref target="response.cacheability"/>). | subject to its constraints (see <xref target="response.cacheability"/>). | |||
| </li> | </li> | |||
| <li> | <li> | |||
| However, if a cache receives a 5xx (Server Error) | However, if a cache receives a 5xx (Server Error) | |||
| response while attempting to validate a response, it can either | response while attempting to validate a response, it can either | |||
| forward this response to the requesting client, or act as if the | forward this response to the requesting client or act as if the | |||
| server failed to respond. In the latter case, the cache can send a | server failed to respond. In the latter case, the cache can send a | |||
| previously stored response, subject to its constraints on doing so (see <xr ef target="serving.stale.responses"/>), or retry the validation request. | previously stored response, subject to its constraints on doing so (see <xr ef target="serving.stale.responses"/>), or retry the validation request. | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| </section> | </section> | |||
| <section anchor="freshening.responses" | <section anchor="freshening.responses" | |||
| title="Freshening Stored Responses upon Validation"> | title="Freshening Stored Responses upon Validation"> | |||
| <t> | <t> | |||
| When a cache receives a 304 (Not Modified) response, it needs | When a cache receives a 304 (Not Modified) response, it needs | |||
| to identify stored responses that are suitable for updating with the new info rmation | to identify stored responses that are suitable for updating with the new info rmation | |||
| provided, and then do so. | provided, and then do so. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The initial set of stored responses to update are those that could have been chosen for | The initial set of stored responses to update are those that could have been chosen for | |||
| that request — i.e., those that meet the requirements in <xref target="constr | that request -- i.e., those that meet the requirements in <xref target="const | |||
| ucting.responses.from.caches"/>, except the last requirement | ructing.responses.from.caches"/>, except the last requirement | |||
| to be fresh, able to be served stale or just validated. | to be fresh, able to be served stale, or just validated. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Then, that initial set of stored response(s) is further filtered by the first match of: | Then, that initial set of stored responses is further filtered by the first m atch of: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li> | <li> | |||
| If the new response contains one or more <em>strong validators</em> (see | If the new response contains one or more "strong validators" (see | |||
| <xref target="HTTP" section="8.8.1"/>), then each of those strong validator s | <xref target="HTTP" section="8.8.1"/>), then each of those strong validator s | |||
| identify a selected representation for update. All the stored | identifies a selected representation for update. All the stored | |||
| responses in the initial set with one of those same strong validators are i dentified for update. If | responses in the initial set with one of those same strong validators are i dentified for update. If | |||
| none of the initial set contain at least one of the same strong validators, then the | none of the initial set contains at least one of the same strong validators , then the | |||
| cache <bcp14>MUST NOT</bcp14> use the new response to update any stored res ponses. | cache <bcp14>MUST NOT</bcp14> use the new response to update any stored res ponses. | |||
| </li> | </li> | |||
| <li> | <li> | |||
| If the new response contains no strong validators but does contain | If the new response contains no strong validators but does contain | |||
| one or more <em>weak validators</em>, and those | one or more "weak validators", and those | |||
| validators correspond to one of the initial set's stored responses, then th e most | validators correspond to one of the initial set's stored responses, then th e most | |||
| recent of those matching stored responses is identified for update. | recent of those matching stored responses is identified for update. | |||
| </li> | </li> | |||
| <li> | <li> | |||
| If the new response does not include any form of validator (such as | If the new response does not include any form of validator (such as | |||
| where a client generates an If-Modified-Since request from | where a client generates an If-Modified-Since request from | |||
| a source other than the Last-Modified response header | a source other than the Last-Modified response header | |||
| field), and there is only one stored response in the initial set, and that stored response | field), and there is only one stored response in the initial set, and that stored response | |||
| also lacks a validator, then that stored response is identified for update. | also lacks a validator, then that stored response is identified for update. | |||
| </li> | </li> | |||
| skipping to change at line 1162 ¶ | skipping to change at line 1151 ¶ | |||
| </t> | </t> | |||
| <t> | <t> | |||
| If a cache updates a stored response with the metadata provided in a HEAD | If a cache updates a stored response with the metadata provided in a HEAD | |||
| response, the cache <bcp14>MUST</bcp14> use the header fields provided in the HEAD | response, the cache <bcp14>MUST</bcp14> use the header fields provided in the HEAD | |||
| response to update the stored response (see <xref target="update"/>). | response to update the stored response (see <xref target="update"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="invalidation" title="Invalidating Stored Responses"> | <section anchor="invalidation" title="Invalidating Stored Responses"> | |||
| <t> | <t> | |||
| Because unsafe request methods (<xref target="HTTP" section="9.2.1"/>) such a s PUT, POST or DELETE | Because unsafe request methods (<xref target="HTTP" section="9.2.1"/>) such a s PUT, POST, or DELETE | |||
| have the potential for changing state on the origin server, intervening | have the potential for changing state on the origin server, intervening | |||
| caches are required to invalidate stored responses to keep their contents up to date. | caches are required to invalidate stored responses to keep their contents up to date. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A cache <bcp14>MUST</bcp14> invalidate the target URI | A cache <bcp14>MUST</bcp14> invalidate the target URI | |||
| (<xref target="HTTP" section="7.1"/>) when it receives a non-error status | (<xref target="HTTP" section="7.1"/>) when it receives a non-error status | |||
| code in response to | code in response to | |||
| an unsafe request method (including methods whose safety is unknown). | an unsafe request method (including methods whose safety is unknown). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| skipping to change at line 1185 ¶ | skipping to change at line 1174 ¶ | |||
| safety is unknown). | safety is unknown). | |||
| In particular, the URI(s) in the | In particular, the URI(s) in the | |||
| Location and Content-Location response header | Location and Content-Location response header | |||
| fields (if present) are candidates for invalidation; other URIs might be | fields (if present) are candidates for invalidation; other URIs might be | |||
| discovered through mechanisms not specified in this document. | discovered through mechanisms not specified in this document. | |||
| However, a cache <bcp14>MUST NOT</bcp14> trigger an invalidation under these conditions | However, a cache <bcp14>MUST NOT</bcp14> trigger an invalidation under these conditions | |||
| if the origin (<xref target="HTTP" section="4.3.1"/>) of the URI to be invali dated differs from that of the target URI | if the origin (<xref target="HTTP" section="4.3.1"/>) of the URI to be invali dated differs from that of the target URI | |||
| (<xref target="HTTP" section="7.1"/>). This helps prevent denial-of-service a ttacks. | (<xref target="HTTP" section="7.1"/>). This helps prevent denial-of-service a ttacks. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| <em>Invalidate</em> means that the cache will either remove all | "Invalidate" means that the cache will either remove all | |||
| stored responses whose target URI matches the given URI, or will mark them | stored responses whose target URI matches the given URI or mark them | |||
| as "invalid" and in need of a mandatory validation before they can be sent | as "invalid" and in need of a mandatory validation before they can be sent | |||
| in response to a subsequent request. | in response to a subsequent request. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A "non-error response" is one with a 2xx (Successful) | A "non-error response" is one with a 2xx (Successful) | |||
| or 3xx (Redirection) status code. | or 3xx (Redirection) status code. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that this does not guarantee that all appropriate responses are | Note that this does not guarantee that all appropriate responses are | |||
| invalidated globally; a state-changing request would only invalidate | invalidated globally; a state-changing request would only invalidate | |||
| skipping to change at line 1218 ¶ | skipping to change at line 1207 ¶ | |||
| <iref primary="true" item="Header Fields" subitem="Age"/> | <iref primary="true" item="Header Fields" subitem="Age"/> | |||
| <iref primary="true" item="Fields" subitem="Age"/> | <iref primary="true" item="Fields" subitem="Age"/> | |||
| <iref primary="true" item="Header Fields" subitem="Age"/> | <iref primary="true" item="Header Fields" subitem="Age"/> | |||
| <iref item="Age header field" primary="true"/> | <iref item="Age header field" primary="true"/> | |||
| <t> | <t> | |||
| The "Age" response header field conveys the sender's estimate of the | The "Age" response header field conveys the sender's estimate of the | |||
| time since the response was generated or successfully validated at the | time since the response was generated or successfully validated at the | |||
| origin server. Age values are calculated as specified in <xref target="age.ca lculations"/>. | origin server. Age values are calculated as specified in <xref target="age.ca lculations"/>. | |||
| </t> | </t> | |||
| <iref primary="true" item="Grammar" subitem="Age"/> | <iref primary="true" item="Grammar" subitem="Age"/> | |||
| <sourcecode type="abnf7230"><![CDATA[ Age = delta-seconds | <sourcecode type="abnf9110"><![CDATA[ Age = delta-seconds | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| The Age field value is a non-negative integer, representing time in seconds | The Age field value is a non-negative integer, representing time in seconds | |||
| (see <xref target="delta-seconds"/>). | (see <xref target="delta-seconds"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Although it is defined as a singleton header field, a cache encountering a | Although it is defined as a singleton header field, a cache encountering a | |||
| message with a list-based Age field value <bcp14>SHOULD</bcp14> use the | message with a list-based Age field value <bcp14>SHOULD</bcp14> use the | |||
| first member of the field value, discarding subsequent ones. | first member of the field value, discarding subsequent ones. | |||
| </t> | </t> | |||
| skipping to change at line 1246 ¶ | skipping to change at line 1235 ¶ | |||
| generated or validated by the origin server for this request. However, | generated or validated by the origin server for this request. However, | |||
| lack of an Age header field does not imply the origin was contacted. | lack of an Age header field does not imply the origin was contacted. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="field.cache-control" title="Cache-Control"> | <section anchor="field.cache-control" title="Cache-Control"> | |||
| <iref primary="true" item="Fields" subitem="Cache-Control"/> | <iref primary="true" item="Fields" subitem="Cache-Control"/> | |||
| <iref primary="true" item="Header Fields" subitem="Cache-Control"/> | <iref primary="true" item="Header Fields" subitem="Cache-Control"/> | |||
| <iref item="Cache-Control header field" primary="true"/> | <iref item="Cache-Control header field" primary="true"/> | |||
| <t> | <t> | |||
| The "Cache-Control" header field is used to list directives for caches | The "Cache-Control" header field is used to list directives for caches | |||
| along the request/response chain. Such cache directives are unidirectional | along the request/response chain. Cache directives are unidirectional, | |||
| in that the presence of a directive in a request does not imply that the | in that the presence of a directive in a request does not imply that the | |||
| same directive is present in the response, or to be repeated in it. | same directive is present or copied in the response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| See <xref target="cache.control.extensions"/> for information about how | See <xref target="cache.control.extensions"/> for information about how | |||
| Cache-Control directives defined elsewhere are handled. | Cache-Control directives defined elsewhere are handled. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| A proxy, whether or not it implements a cache, <bcp14>MUST</bcp14> pass cache directives | A proxy, whether or not it implements a cache, <bcp14>MUST</bcp14> pass cache directives | |||
| through in forwarded messages, regardless of their | through in forwarded messages, regardless of their | |||
| significance to that application, since the directives might apply | significance to that application, since the directives might apply | |||
| to all recipients along the request/response chain. It is not possible to | to all recipients along the request/response chain. It is not possible to | |||
| target a directive to a specific cache. | target a directive to a specific cache. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Cache directives are identified by a token, to be compared case-insensitively , | Cache directives are identified by a token, to be compared case-insensitively , | |||
| and have an optional argument that can use both token and quoted-string | and have an optional argument that can use both token and quoted-string | |||
| syntax. For the directives defined below that define arguments, recipients | syntax. For the directives defined below that define arguments, recipients | |||
| ought to accept both forms, even if a specific form is required for generatio n. | ought to accept both forms, even if a specific form is required for generatio n. | |||
| </t> | </t> | |||
| <iref primary="true" item="Grammar" subitem="Cache-Control"/> | <iref primary="true" item="Grammar" subitem="Cache-Control"/> | |||
| <iref primary="true" item="Grammar" subitem="cache-directive"/> | <iref primary="true" item="Grammar" subitem="cache-directive"/> | |||
| <sourcecode type="abnf7230"><![CDATA[ Cache-Control = #cache-dire ctive | <sourcecode type="abnf9110"><![CDATA[ Cache-Control = #cache-dire ctive | |||
| cache-directive = token [ "=" ( token / quoted-string ) ] | cache-directive = token [ "=" ( token / quoted-string ) ] | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| For the cache directives defined below, no argument is defined (nor allowed) | For the cache directives defined below, no argument is defined (nor allowed) | |||
| unless stated otherwise. | unless stated otherwise. | |||
| </t> | </t> | |||
| <section anchor="cache-request-directive" | <section anchor="cache-request-directive" | |||
| title="Request Cache-Control Directives"> | title="Request Directives"> | |||
| <t> | <t> | |||
| This section defines cache request directives. They are advisory; caches | This section defines cache request directives. They are advisory; caches | |||
| <bcp14>MAY</bcp14> implement them, but are not required to. | <bcp14>MAY</bcp14> implement them, but are not required to. | |||
| </t> | </t> | |||
| <section anchor="cache-request-directive.max-age" title="max-age" > | <section anchor="cache-request-directive.max-age" title="max-age" > | |||
| <iref item="max-age (cache directive)" primary="true"/> | <iref item="max-age (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li> | <li> | |||
| <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "max-age" request directive indicates that the client prefers a | The max-age request directive indicates that the client prefers a | |||
| response whose age is less than or equal to the specified number of | response whose age is less than or equal to the specified number of | |||
| seconds. Unless the max-stale request directive is also present, the | seconds. Unless the max-stale request directive is also present, the | |||
| client does not wish to receive a stale response. | client does not wish to receive a stale response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the token form of the argument syntax: | This directive uses the token form of the argument syntax: | |||
| e.g., 'max-age=5' not 'max-age="5"'. A sender <bcp14>MUST NOT</bcp14> generat e the | e.g., 'max-age=5' not 'max-age="5"'. A sender <bcp14>MUST NOT</bcp14> generat e the | |||
| quoted-string form. | quoted-string form. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-request-directive.max-stale" title="max-st ale"> | <section anchor="cache-request-directive.max-stale" title="max-st ale"> | |||
| <iref item="max-stale (cache directive)" primary="true"/> | <iref item="max-stale (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li> | <li> | |||
| <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "max-stale" request directive indicates that the client will | The max-stale request directive indicates that the client will | |||
| accept a response that has exceeded its freshness lifetime. If a value is | accept a response that has exceeded its freshness lifetime. If a value is | |||
| present, then the client is willing to accept a response that has exceeded | present, then the client is willing to accept a response that has exceeded | |||
| its freshness lifetime by no more than the specified number of seconds. If | its freshness lifetime by no more than the specified number of seconds. If | |||
| no value is assigned to max-stale, then the client will accept a | no value is assigned to max-stale, then the client will accept a | |||
| stale response of any age. | stale response of any age. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the token form of the argument syntax: | This directive uses the token form of the argument syntax: | |||
| e.g., 'max-stale=10' not 'max-stale="10"'. A sender <bcp14>MUST NOT</bcp14> g enerate | e.g., 'max-stale=10' not 'max-stale="10"'. A sender <bcp14>MUST NOT</bcp14> g enerate | |||
| the quoted-string form. | the quoted-string form. | |||
| skipping to change at line 1337 ¶ | skipping to change at line 1326 ¶ | |||
| <section anchor="cache-request-directive.min-fresh" title="min-fr esh"> | <section anchor="cache-request-directive.min-fresh" title="min-fr esh"> | |||
| <iref item="min-fresh (cache directive)" primary="true"/> | <iref item="min-fresh (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li> | <li> | |||
| <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "min-fresh" request directive indicates that the client prefers a | The min-fresh request directive indicates that the client prefers a | |||
| response whose freshness lifetime is no less than its current age plus the | response whose freshness lifetime is no less than its current age plus the | |||
| specified time in seconds. That is, the client wants a response that will | specified time in seconds. That is, the client wants a response that will | |||
| still be fresh for at least the specified number of seconds. | still be fresh for at least the specified number of seconds. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the token form of the argument syntax: | This directive uses the token form of the argument syntax: | |||
| e.g., 'min-fresh=20' not 'min-fresh="20"'. A sender <bcp14>MUST NOT</bcp14> g enerate | e.g., 'min-fresh=20' not 'min-fresh="20"'. A sender <bcp14>MUST NOT</bcp14> g enerate | |||
| the quoted-string form. | the quoted-string form. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-request-directive.no-cache" title="no-cach e"> | <section anchor="cache-request-directive.no-cache" title="no-cach e"> | |||
| <iref item="no-cache (cache directive)" primary="true"/> | <iref item="no-cache (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "no-cache" request directive indicates that the client prefers | The no-cache request directive indicates that the client prefers | |||
| stored response not be used to satisfy the request without successful | a stored response not be used to satisfy the request without successful | |||
| validation on the origin server. | validation on the origin server. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-request-directive.no-store" title="no-stor e"> | <section anchor="cache-request-directive.no-store" title="no-stor e"> | |||
| <iref item="no-store (cache directive)" primary="true"/> | <iref item="no-store (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "no-store" request directive indicates that a cache <bcp14>MUST NOT</bcp1 4> | The no-store request directive indicates that a cache <bcp14>MUST NOT</bcp14> | |||
| store any part of either this request or any response to it. This | store any part of either this request or any response to it. This | |||
| directive applies to both private and shared caches. "MUST NOT | directive applies to both private and shared caches. "MUST NOT | |||
| store" in this context means that the cache <bcp14>MUST NOT</bcp14> intention ally | store" in this context means that the cache <bcp14>MUST NOT</bcp14> intention ally | |||
| store the information in non-volatile storage, and <bcp14>MUST</bcp14> make a | store the information in non-volatile storage and <bcp14>MUST</bcp14> make a | |||
| best-effort attempt to remove the information from volatile storage as | best-effort attempt to remove the information from volatile storage as | |||
| promptly as possible after forwarding it. | promptly as possible after forwarding it. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive is <em>not</em> a reliable or sufficient mechanism for ensurin g | This directive is not a reliable or sufficient mechanism for ensuring | |||
| privacy. In particular, malicious or compromised caches might not | privacy. In particular, malicious or compromised caches might not | |||
| recognize or obey this directive, and communications networks might be | recognize or obey this directive, and communications networks might be | |||
| vulnerable to eavesdropping. | vulnerable to eavesdropping. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that if a request containing this directive is satisfied from a | Note that if a request containing this directive is satisfied from a | |||
| cache, the no-store request directive does not apply to the already | cache, the no-store request directive does not apply to the already | |||
| stored response. | stored response. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-request-directive.no-transform" title="no- transform"> | <section anchor="cache-request-directive.no-transform" title="no- transform"> | |||
| <iref item="no-transform (cache directive)" primary="true"/> | <iref item="no-transform (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "no-transform" request directive indicates that the client is asking | The no-transform request directive indicates that the client is asking | |||
| for intermediaries to avoid | for intermediaries to avoid | |||
| transforming the content, as defined in <xref target="HTTP" section="7.7"/>. | transforming the content, as defined in <xref target="HTTP" section="7.7"/>. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-request-directive.only-if-cached" title="o nly-if-cached"> | <section anchor="cache-request-directive.only-if-cached" title="o nly-if-cached"> | |||
| <iref item="only-if-cached (cache directive)" primary="true"/> | <iref item="only-if-cached (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "only-if-cached" request directive indicates that the client only | The only-if-cached request directive indicates that the client only | |||
| wishes to obtain a stored response. Caches that honor this request | wishes to obtain a stored response. Caches that honor this request | |||
| directive <bcp14>SHOULD</bcp14>, upon receiving it, either respond using a st | directive <bcp14>SHOULD</bcp14>, upon receiving it, respond with either a sto | |||
| ored | red | |||
| response consistent with the other constraints of the request, or | response consistent with the other constraints of the request or | |||
| respond with a 504 (Gateway Timeout) status code. | a 504 (Gateway Timeout) status code. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive" | <section anchor="cache-response-directive" | |||
| title="Response Cache-Control Directives"> | title="Response Directives"> | |||
| <t> | <t> | |||
| This section defines cache response directives. A cache <bcp14>MUST</bcp14> o bey the | This section defines cache response directives. A cache <bcp14>MUST</bcp14> o bey the | |||
| Cache-Control directives defined in this section. | Cache-Control directives defined in this section. | |||
| </t> | </t> | |||
| <section anchor="cache-response-directive.max-age" title="max-age "> | <section anchor="cache-response-directive.max-age" title="max-age "> | |||
| <iref item="max-age (cache directive)" primary="true"/> | <iref item="max-age (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li> | <li> | |||
| <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "max-age" response directive indicates that the response is to be | The max-age response directive indicates that the response is to be | |||
| considered stale after its age is greater than the specified number of | considered stale after its age is greater than the specified number of | |||
| seconds. | seconds. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the token form of the argument syntax: | This directive uses the token form of the argument syntax: | |||
| e.g., 'max-age=5' not 'max-age="5"'. A sender <bcp14>MUST NOT</bcp14> generat e the | e.g., 'max-age=5' not 'max-age="5"'. A sender <bcp14>MUST NOT</bcp14> generat e the | |||
| quoted-string form. | quoted-string form. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.must-revalidate" | <section anchor="cache-response-directive.must-revalidate" | |||
| title="must-revalidate"> | title="must-revalidate"> | |||
| <iref item="must-revalidate (cache directive)" primary="true"/ > | <iref item="must-revalidate (cache directive)" primary="true"/ > | |||
| <t> | <t> | |||
| The "must-revalidate" response directive indicates that once the response | The must-revalidate response directive indicates that once the response | |||
| has become stale, a cache <bcp14>MUST NOT</bcp14> reuse that response to sati sfy | has become stale, a cache <bcp14>MUST NOT</bcp14> reuse that response to sati sfy | |||
| another request until it has been successfully validated by the origin, as | another request until it has been successfully validated by the origin, as | |||
| defined by <xref target="validation.model"/>. | defined by <xref target="validation.model"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The must-revalidate directive is necessary to support reliable operation | The must-revalidate directive is necessary to support reliable operation | |||
| for certain protocol features. In all circumstances a cache <bcp14>MUST NOT</ bcp14> ignore | for certain protocol features. In all circumstances, a cache <bcp14>MUST NOT< /bcp14> ignore | |||
| the must-revalidate directive; in particular, if a cache is disconnected, | the must-revalidate directive; in particular, if a cache is disconnected, | |||
| the cache <bcp14>MUST</bcp14> generate an error response rather than reuse th e stale response. | the cache <bcp14>MUST</bcp14> generate an error response rather than reuse th e stale response. | |||
| The generated status code <bcp14>SHOULD</bcp14> be 504 (Gateway Timeout) | The generated status code <bcp14>SHOULD</bcp14> be 504 (Gateway Timeout) | |||
| unless another error status code is more applicable. | unless another error status code is more applicable. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The must-revalidate directive ought to be used by servers if and only | The must-revalidate directive ought to be used by servers if and only | |||
| if failure to validate a request could cause | if failure to validate a request could cause | |||
| incorrect operation, such as a silently unexecuted financial | incorrect operation, such as a silently unexecuted financial | |||
| transaction. | transaction. | |||
| skipping to change at line 1459 ¶ | skipping to change at line 1448 ¶ | |||
| reuse a response to a request containing an Authorization | reuse a response to a request containing an Authorization | |||
| header field (<xref target="HTTP" section="11.6.2"/>), | header field (<xref target="HTTP" section="11.6.2"/>), | |||
| subject to the above requirement on revalidation | subject to the above requirement on revalidation | |||
| (<xref target="caching.authenticated.responses"/>). | (<xref target="caching.authenticated.responses"/>). | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.must-understand" | <section anchor="cache-response-directive.must-understand" | |||
| title="must-understand"> | title="must-understand"> | |||
| <iref item="must-understand (cache directive)" primary="true"/ > | <iref item="must-understand (cache directive)" primary="true"/ > | |||
| <t> | <t> | |||
| The "must-understand" response directive limits caching of the response to | The must-understand response directive limits caching of the response to | |||
| a cache that understands and conforms to the requirements for that | a cache that understands and conforms to the requirements for that | |||
| response's status code. | response's status code. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Responses containing "must-understand" <bcp14>SHOULD</bcp14> also contain the | A response that contains the must-understand directive <bcp14>SHOULD</bcp14> | |||
| "no-store" directive; | also contain the no-store directive. When a cache that implements the | |||
| caches that implement "must-understand" <bcp14>SHOULD</bcp14> ignore the "no- | must-understand directive receives a response that includes it, | |||
| store" directive | the cache <bcp14>SHOULD</bcp14> ignore the no-store directive if it | |||
| in responses that contain both directives and a status code that the cache | understands and implements the status code's caching requirements. | |||
| understands and conforms to any related caching requirements. | ||||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.no-cache" title="no-cac he"> | <section anchor="cache-response-directive.no-cache" title="no-cac he"> | |||
| <iref item="no-cache (cache directive)" primary="true"/> | <iref item="no-cache (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li>#<xref target="imported.rules" format="none">field-name </xref> | <li>#<xref target="imported.rules" format="none">field-name </xref> | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "no-cache" response directive, in its unqualified form (without an | The no-cache response directive, in its unqualified form (without an | |||
| argument), indicates that the response <bcp14>MUST NOT</bcp14> be used to sat isfy any | argument), indicates that the response <bcp14>MUST NOT</bcp14> be used to sat isfy any | |||
| other request without forwarding it for validation and receiving a | other request without forwarding it for validation and receiving a | |||
| successful response; see <xref target="validation.model"/>. | successful response; see <xref target="validation.model"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This allows an origin server to prevent a cache from using | This allows an origin server to prevent a cache from using | |||
| the response to satisfy a request without contacting it, even by caches that have | the response to satisfy a request without contacting it, even by caches that have | |||
| been configured to send stale responses. | been configured to send stale responses. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The qualified form of no-cache response directive, with an argument that | The qualified form of the no-cache response directive, with an argument that | |||
| lists one or more field names, indicates that a cache <bcp14>MAY</bcp14> use the | lists one or more field names, indicates that a cache <bcp14>MAY</bcp14> use the | |||
| response to satisfy a subsequent request, subject to any other restrictions | response to satisfy a subsequent request, subject to any other restrictions | |||
| on caching, if the listed header fields are excluded from the subsequent | on caching, if the listed header fields are excluded from the subsequent | |||
| response or the subsequent response has been successfully revalidated with | response or the subsequent response has been successfully revalidated with | |||
| the origin server (updating or removing those fields). | the origin server (updating or removing those fields). | |||
| This allows an origin server to prevent the re-use of certain header | This allows an origin server to prevent the reuse of certain header | |||
| fields in a response, while still allowing caching of the rest of the | fields in a response, while still allowing caching of the rest of the | |||
| response. | response. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The field names given are not limited to the set of header | The field names given are not limited to the set of header | |||
| fields defined by this specification. Field names are case-insensitive. | fields defined by this specification. Field names are case-insensitive. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the quoted-string form of the argument syntax. | This directive uses the quoted-string form of the argument syntax. | |||
| A sender <bcp14>SHOULD NOT</bcp14> generate the token form (even if quoting a ppears not | A sender <bcp14>SHOULD NOT</bcp14> generate the token form (even if quoting a ppears not | |||
| to be needed for single-entry lists). | to be needed for single-entry lists). | |||
| </t> | </t> | |||
| <aside> | <aside> | |||
| <t> | <t> | |||
| <strong>Note:</strong> The | <strong>Note:</strong> The | |||
| qualified form of the directive is often handled by caches as if an | qualified form of the directive is often handled by caches as if an | |||
| unqualified no-cache directive was received; i.e., the special handling | unqualified no-cache directive was received; that is, the special handling | |||
| for the qualified form is not widely implemented. | for the qualified form is not widely implemented. | |||
| </t> | </t> | |||
| </aside> | </aside> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.no-store" title="no-sto re"> | <section anchor="cache-response-directive.no-store" title="no-sto re"> | |||
| <iref item="no-store (cache directive)" primary="true"/> | <iref item="no-store (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "no-store" response directive indicates that a cache <bcp14>MUST NOT</bcp | The no-store response directive indicates that a cache <bcp14>MUST NOT</bcp14 | |||
| 14> store | > store | |||
| any part of either the immediate request or response, and <bcp14>MUST NOT</bc | any part of either the immediate request or the response and <bcp14>MUST NOT< | |||
| p14> use | /bcp14> use | |||
| the response to satisfy any other request. | the response to satisfy any other request. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive applies to both private and shared caches. "MUST NOT | This directive applies to both private and shared caches. "MUST NOT | |||
| store" in this context means that the cache <bcp14>MUST NOT</bcp14> intention ally store | store" in this context means that the cache <bcp14>MUST NOT</bcp14> intention ally store | |||
| the information in non-volatile storage, and <bcp14>MUST</bcp14> make a best- effort | the information in non-volatile storage and <bcp14>MUST</bcp14> make a best-e ffort | |||
| attempt to remove the information from volatile storage as promptly as | attempt to remove the information from volatile storage as promptly as | |||
| possible after forwarding it. | possible after forwarding it. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive is <em>not</em> a reliable or sufficient mechanism for ensurin g | This directive is not a reliable or sufficient mechanism for ensuring | |||
| privacy. In particular, malicious or compromised caches might not | privacy. In particular, malicious or compromised caches might not | |||
| recognize or obey this directive, and communications networks might be | recognize or obey this directive, and communications networks might be | |||
| vulnerable to eavesdropping. | vulnerable to eavesdropping. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that the "must-understand" cache directive overrides "no-store" in certa in | Note that the must-understand cache directive overrides no-store in certain | |||
| circumstances; see <xref target="cache-response-directive.must-understand"/>. | circumstances; see <xref target="cache-response-directive.must-understand"/>. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.no-transform" title="no -transform"> | <section anchor="cache-response-directive.no-transform" title="no -transform"> | |||
| <iref item="no-transform (cache directive)" primary="true"/> | <iref item="no-transform (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "no-transform" response directive indicates that an intermediary | The no-transform response directive indicates that an intermediary | |||
| (regardless of whether it implements a cache) <bcp14>MUST NOT</bcp14> transfo rm the | (regardless of whether it implements a cache) <bcp14>MUST NOT</bcp14> transfo rm the | |||
| content, as defined in <xref target="HTTP" section="7.7"/>. | content, as defined in <xref target="HTTP" section="7.7"/>. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.private" title="private "> | <section anchor="cache-response-directive.private" title="private "> | |||
| <iref item="private (cache directive)" primary="true"/> | <iref item="private (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li>#<xref target="imported.rules" format="none">field-name </xref> | <li>#<xref target="imported.rules" format="none">field-name </xref> | |||
| </li> | </li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The unqualified "private" response directive indicates that | The unqualified private response directive indicates that | |||
| a shared cache <bcp14>MUST NOT</bcp14> store the response (i.e., the response is | a shared cache <bcp14>MUST NOT</bcp14> store the response (i.e., the response is | |||
| intended for a single user). | intended for a single user). | |||
| It also indicates that a private cache <bcp14>MAY</bcp14> store the response, subject | It also indicates that a private cache <bcp14>MAY</bcp14> store the response, subject | |||
| the constraints defined in <xref target="response.cacheability"/>, even if | to the constraints defined in <xref target="response.cacheability"/>, even if | |||
| the response would not otherwise be heuristically cacheable by a private | the response would not otherwise be heuristically cacheable by a private | |||
| cache. | cache. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| If a qualified private response directive is present, with an argument that | If a qualified private response directive is present, with an argument that | |||
| lists one or more field names, then only the listed header fields are limited to a | lists one or more field names, then only the listed header fields are limited to a | |||
| single user: a shared cache <bcp14>MUST NOT</bcp14> store the listed header f ields if they | single user: a shared cache <bcp14>MUST NOT</bcp14> store the listed header f ields if they | |||
| are present in the original response, but <bcp14>MAY</bcp14> store the remain der of the | are present in the original response but <bcp14>MAY</bcp14> store the remaind er of the | |||
| response message without those header fields, subject | response message without those header fields, subject | |||
| the constraints defined in <xref target="response.cacheability"/>. | the constraints defined in <xref target="response.cacheability"/>. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The field names given are not limited to the set of header | The field names given are not limited to the set of header | |||
| fields defined by this specification. Field names are case-insensitive. | fields defined by this specification. Field names are case-insensitive. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the quoted-string form of the argument syntax. | This directive uses the quoted-string form of the argument syntax. | |||
| A sender <bcp14>SHOULD NOT</bcp14> generate the token form (even if quoting a ppears not | A sender <bcp14>SHOULD NOT</bcp14> generate the token form (even if quoting a ppears not | |||
| to be needed for single-entry lists). | to be needed for single-entry lists). | |||
| </t> | </t> | |||
| <aside> | <aside> | |||
| <t> | <t> | |||
| <strong>Note:</strong> This usage of the word "private" only controls | <strong>Note:</strong> This usage of the word "private" only controls | |||
| where the response can be stored; it cannot ensure the privacy of the | where the response can be stored; it cannot ensure the privacy of the | |||
| message content. Also, the qualified form of the directive is | message content. Also, the qualified form of the directive is | |||
| often handled by caches as if an unqualified private directive | often handled by caches as if an unqualified private directive | |||
| was received; i.e., the special handling for the qualified form is not | was received; that is, the special handling for the qualified form is not | |||
| widely implemented. | widely implemented. | |||
| </t> | </t> | |||
| </aside> | </aside> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.proxy-revalidate" | <section anchor="cache-response-directive.proxy-revalidate" | |||
| title="proxy-revalidate"> | title="proxy-revalidate"> | |||
| <iref item="proxy-revalidate (cache directive)" primary="true" /> | <iref item="proxy-revalidate (cache directive)" primary="true" /> | |||
| <t> | <t> | |||
| The "proxy-revalidate" response directive indicates that once the response | The proxy-revalidate response directive indicates that once the response | |||
| has become stale, a shared cache <bcp14>MUST NOT</bcp14> reuse that response to satisfy | has become stale, a shared cache <bcp14>MUST NOT</bcp14> reuse that response to satisfy | |||
| another request until it has been successfully validated by the origin, | another request until it has been successfully validated by the origin, | |||
| as defined by <xref target="validation.model"/>. This is analogous to | as defined by <xref target="validation.model"/>. This is analogous to | |||
| must-revalidate (<xref target="cache-response-directive.must-revalidate"/>), | must-revalidate (<xref target="cache-response-directive.must-revalidate"/>), | |||
| except that proxy-revalidate does not apply to private caches. | except that proxy-revalidate does not apply to private caches. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that "proxy-revalidate" on its own does not imply that a response is | Note that proxy-revalidate on its own does not imply that a response is | |||
| cacheable. For example, it might be combined with the public directive | cacheable. For example, it might be combined with the public directive | |||
| (<xref target="cache-response-directive.public"/>), allowing the response | (<xref target="cache-response-directive.public"/>), allowing the response | |||
| to be cached while requiring only a shared cache to revalidate when stale. | to be cached while requiring only a shared cache to revalidate when stale. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="cache-response-directive.public" title="public"> | <section anchor="cache-response-directive.public" title="public"> | |||
| <iref item="public (cache directive)" primary="true"/> | <iref item="public (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| The "public" response directive indicates that a cache <bcp14>MAY</bcp14> sto re the | The public response directive indicates that a cache <bcp14>MAY</bcp14> store the | |||
| response even if it would otherwise be prohibited, subject to the | response even if it would otherwise be prohibited, subject to the | |||
| constraints defined in <xref target="response.cacheability"/>. In other words , | constraints defined in <xref target="response.cacheability"/>. In other words , | |||
| public explicitly marks the response as cacheable. For example, | public explicitly marks the response as cacheable. For example, | |||
| public permits a shared cache to reuse a response to a request containing | public permits a shared cache to reuse a response to a request containing | |||
| an Authorization header field (<xref target="caching.authenticated.responses" />). | an Authorization header field (<xref target="caching.authenticated.responses" />). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that it is unnecessary to add the public directive to a response that | Note that it is unnecessary to add the public directive to a response that | |||
| is already cacheable according to <xref target="response.cacheability"/>. | is already cacheable according to <xref target="response.cacheability"/>. | |||
| </t> | </t> | |||
| skipping to change at line 1645 ¶ | skipping to change at line 1635 ¶ | |||
| <section anchor="cache-response-directive.s-maxage" title="s-maxa ge"> | <section anchor="cache-response-directive.s-maxage" title="s-maxa ge"> | |||
| <iref item="s-maxage (cache directive)" primary="true"/> | <iref item="s-maxage (cache directive)" primary="true"/> | |||
| <t> | <t> | |||
| Argument syntax: | Argument syntax: | |||
| </t> | </t> | |||
| <ul empty="true"> | <ul empty="true"> | |||
| <li> | <li> | |||
| <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | <xref target="delta-seconds" format="none">delta-seconds </xref> (see <xref target="delta-seconds"/>)</li> | |||
| </ul> | </ul> | |||
| <t> | <t> | |||
| The "s-maxage" response directive indicates that, for a shared cache, the | The s-maxage response directive indicates that, for a shared cache, the | |||
| maximum age specified by this directive overrides the maximum age | maximum age specified by this directive overrides the maximum age | |||
| specified by either the max-age directive or the <xref target="field.expires" format="none">Expires</xref> | specified by either the max-age directive or the <xref target="field.expires" format="none">Expires</xref> | |||
| header field. | header field. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The s-maxage directive incorporates the | The s-maxage directive incorporates the | |||
| proxy-revalidate (<xref target="cache-response-directive.proxy-revalidate"/>) | semantics of the proxy&nbhy;revalidate response directive (<xref target="cach | |||
| response directive's semantics for a shared cache. | e-response-directive.proxy-revalidate"/>) | |||
| for a shared cache. | ||||
| A shared cache <bcp14>MUST NOT</bcp14> reuse a stale response with s-maxage t o satisfy | A shared cache <bcp14>MUST NOT</bcp14> reuse a stale response with s-maxage t o satisfy | |||
| another request until it has been successfully validated by the origin, as | another request until it has been successfully validated by the origin, as | |||
| defined by <xref target="validation.model"/>. | defined by <xref target="validation.model"/>. | |||
| This directive also permits a shared cache to reuse a response to a | This directive also permits a shared cache to reuse a response to a | |||
| request containing an Authorization header field, subject to the above | request containing an Authorization header field, subject to the above | |||
| requirements on maximum age and revalidation | requirements on maximum age and revalidation | |||
| (<xref target="caching.authenticated.responses"/>). | (<xref target="caching.authenticated.responses"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This directive uses the token form of the argument syntax: | This directive uses the token form of the argument syntax: | |||
| e.g., 's-maxage=10' not 's-maxage="10"'. A sender <bcp14>MUST NOT</bcp14> gen erate | e.g., 's-maxage=10' not 's-maxage="10"'. A sender <bcp14>MUST NOT</bcp14> gen erate | |||
| the quoted-string form. | the quoted-string form. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="cache.control.extensions" title="Cache Control Exte nsions"> | <section anchor="cache.control.extensions" title="Extension Directiv es"> | |||
| <t> | <t> | |||
| The Cache-Control header field can be extended through the use of one or | The Cache-Control header field can be extended through the use of one or | |||
| more extension cache directives. | more extension cache directives. | |||
| A cache <bcp14>MUST</bcp14> ignore unrecognized cache directives. | A cache <bcp14>MUST</bcp14> ignore unrecognized cache directives. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Informational extensions (those that do not require a change in cache | Informational extensions (those that do not require a change in cache | |||
| behavior) can be added without changing the semantics of other directives. | behavior) can be added without changing the semantics of other directives. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Behavioral extensions are designed to work by acting as modifiers to the | Behavioral extensions are designed to work by acting as modifiers to the | |||
| existing base of cache directives. | existing base of cache directives. | |||
| Both the new directive and the old directive are supplied, such that | Both the new directive and the old directive are supplied, such that | |||
| applications that do not understand the new directive will default to the | applications that do not understand the new directive will default to the | |||
| behavior specified by the old directive, and those that understand the | behavior specified by the old directive, and those that understand the | |||
| new directive will recognize it as modifying the requirements associated | new directive will recognize it as modifying the requirements associated | |||
| with the old directive. In this way, extensions to the existing | with the old directive. In this way, extensions to the existing | |||
| cache-control directives can be made without breaking deployed caches. | cache directives can be made without breaking deployed caches. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| For example, consider a hypothetical new response directive called | For example, consider a hypothetical new response directive called | |||
| "community" that acts as a modifier to the private directive: in addition | "community" that acts as a modifier to the private directive: in addition | |||
| to private caches, any cache that is shared only by members of the named | to private caches, only a cache that is shared by members of the named | |||
| community is allowed to cache the response. An origin server wishing to | community is allowed to cache the response. An origin server wishing to | |||
| allow the UCI community to use an otherwise private response in their | allow the UCI community to use an otherwise private response in their | |||
| shared cache(s) could do so by including | shared cache(s) could do so by including | |||
| </t> | </t> | |||
| <sourcecode type="http-message"><![CDATA[Cache-Control: private, community="UCI" | <sourcecode type="http-message"><![CDATA[Cache-Control: private, community="UCI" | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| A cache that recognizes such a community cache directive could broaden its | A cache that recognizes such a community cache directive could broaden its | |||
| behavior in accordance with that extension. A cache that does not | behavior in accordance with that extension. A cache that does not | |||
| recognize the community cache directive would ignore it and adhere to the | recognize the community cache directive would ignore it and adhere to the | |||
| private directive. | private directive. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| New extension directives ought to consider defining: | New extension directives ought to consider defining: | |||
| </t> | </t> | |||
| <ul> | <ul> | |||
| <li>What it means for a directive to be specified multiple tim es,</li> | <li>What it means for a directive to be specified multiple tim es,</li> | |||
| <li>When the directive does not take an argument, what it mean s when an | <li>When the directive does not take an argument, what it mean s when an | |||
| argument is present,</li> | argument is present,</li> | |||
| <li>When the directive requires an argument, what it means whe n it is | <li>When the directive requires an argument, what it means whe n it is | |||
| missing,</li> | missing, and</li> | |||
| <li>Whether the directive is specific to requests, responses, | <li>Whether the directive is specific to requests, specific to | |||
| or able | responses, or able | |||
| to be used in either.</li> | to be used in either.</li> | |||
| </ul> | </ul> | |||
| </section> | </section> | |||
| <section anchor="cache.directive.registry" title="Cache Directive Re gistry"> | <section anchor="cache.directive.registry" title="Cache Directive Re gistry"> | |||
| <t> | <t> | |||
| The "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" defines the namespace for the | The "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" defines the namespace for the | |||
| cache directives. It has been created and is now maintained at | cache directives. It has been created and is now maintained at | |||
| <eref target="https://www.iana.org/assignments/http-cache-directives" | <eref target="https://www.iana.org/assignments/http-cache-directives" | |||
| brackets="angle"/>. | brackets="angle"/>. | |||
| </t> | </t> | |||
| skipping to change at line 1757 ¶ | skipping to change at line 1747 ¶ | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The presence of an Expires header field does not imply that the original reso urce | The presence of an Expires header field does not imply that the original reso urce | |||
| will change or cease to exist at, before, or after that time. | will change or cease to exist at, before, or after that time. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The Expires field value is an HTTP-date timestamp, as defined in <xref target ="HTTP" section="5.6.7"/>. | The Expires field value is an HTTP-date timestamp, as defined in <xref target ="HTTP" section="5.6.7"/>. | |||
| See also <xref target="expiration.model"/> for parsing requirements specific to caches. | See also <xref target="expiration.model"/> for parsing requirements specific to caches. | |||
| </t> | </t> | |||
| <iref primary="true" item="Grammar" subitem="Expires"/> | <iref primary="true" item="Grammar" subitem="Expires"/> | |||
| <sourcecode type="abnf7230"><![CDATA[ Expires = HTTP-date | <sourcecode type="abnf9110"><![CDATA[ Expires = HTTP-date | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| For example | For example | |||
| </t> | </t> | |||
| <sourcecode type="http-message"><![CDATA[Expires: Thu, 01 Dec 1994 1 6:00:00 GMT | <sourcecode type="http-message"><![CDATA[Expires: Thu, 01 Dec 1994 1 6:00:00 GMT | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| <t> | <t> | |||
| A cache recipient <bcp14>MUST</bcp14> interpret invalid date formats, especia lly the | A cache recipient <bcp14>MUST</bcp14> interpret invalid date formats, especia lly the | |||
| value "0", as representing a time in the past (i.e., "already expired"). | value "0", as representing a time in the past (i.e., "already expired"). | |||
| </t> | </t> | |||
| skipping to change at line 1858 ¶ | skipping to change at line 1848 ¶ | |||
| </t> | </t> | |||
| <t> | <t> | |||
| This specification does not prohibit the application from taking HTTP caching into | This specification does not prohibit the application from taking HTTP caching into | |||
| account; for example, a history mechanism might tell the user that a view | account; for example, a history mechanism might tell the user that a view | |||
| is stale, or it might honor cache directives (e.g., Cache-Control: | is stale, or it might honor cache directives (e.g., Cache-Control: | |||
| no-store). | no-store). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| However, when an application caches data and does not make this | However, when an application caches data and does not make this | |||
| apparent to or easily controllable by the user, it is strongly encouraged to | apparent to or easily controllable by the user, it is strongly encouraged to | |||
| define its operation with respect to HTTP cache directives, so as | define its operation with respect to HTTP cache directives so as | |||
| not to surprise authors who expect caching semantics | not to surprise authors who expect caching semantics | |||
| to be honoured. For example, while it might be reasonable to define an | to be honored. For example, while it might be reasonable to define an | |||
| application cache "above" HTTP that allows a response containing | application cache "above" HTTP that allows a response containing | |||
| Cache-Control: no-store to be reused for requests that are directly related | Cache-Control: no-store to be reused for requests that are directly related | |||
| to the request that fetched it (such as those created during the same page | to the request that fetched it (such as those created during the same page | |||
| load), it would likely be surprising and confusing to users and authors if it | load), it would likely be surprising and confusing to users and authors if it | |||
| were allowed to be reused for requests unrelated in any way to the one from | were allowed to be reused for requests unrelated in any way to the one from | |||
| which it was obtained. | which it was obtained. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="security.considerations" title="Security Considerations"> | <section anchor="security.considerations" title="Security Considerations"> | |||
| <t> | <t> | |||
| This section is meant to inform developers, information providers, and | This section is meant to inform developers, information providers, and | |||
| users of known security concerns specific to HTTP caching. | users of known security concerns specific to HTTP caching. | |||
| More general security considerations are addressed in "HTTP/1.1" | More general security considerations are addressed in "HTTP/1.1" | |||
| (<xref target="HTTP11" section="11"/>) | (<xref target="HTTP11" section="11"/>) | |||
| and "HTTP Semantics" | and "HTTP Semantics" | |||
| (<xref target="HTTP" section="17"/>). | (<xref target="HTTP" section="17"/>). | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Caches expose an additional attack surface, since the contents of | Caches expose an additional attack surface because the contents of | |||
| the cache represent an attractive target for malicious exploitation. | the cache represent an attractive target for malicious exploitation. | |||
| Because cache contents persist after an HTTP request is complete, an attack | Since cache contents persist after an HTTP request is complete, an attack | |||
| on the cache can reveal information long after a user believes that the | on the cache can reveal information long after a user believes that the | |||
| information has been removed from the network. Therefore, cache contents | information has been removed from the network. Therefore, cache contents | |||
| need to be protected as sensitive information. | need to be protected as sensitive information. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| In particular, because private caches are restricted to a single user, | In particular, because private caches are restricted to a single user, | |||
| they can be used to reconstruct a user's activity. As a result, it is | they can be used to reconstruct a user's activity. As a result, it is | |||
| important for user agents to allow end users to control them; for example, | important for user agents to allow end users to control them, for example, | |||
| allowing stored responses to be removed for some or all origin servers. | by allowing stored responses to be removed for some or all origin servers. | |||
| </t> | </t> | |||
| <section anchor="cache.poisoning" title="Cache Poisoning"> | <section anchor="cache.poisoning" title="Cache Poisoning"> | |||
| <t> | <t> | |||
| Storing a malicious payload in a cache can extend the reach of an attacker | Storing malicious content in a cache can extend the reach of an attacker | |||
| to affect multiple users. Such | to affect multiple users. Such | |||
| "cache poisoning" attacks happen when an attacker uses | "cache poisoning" attacks happen when an attacker uses | |||
| implementation flaws, elevated privileges, or other techniques to insert | implementation flaws, elevated privileges, or other techniques to insert | |||
| a response into a cache. This is especially effective when shared caches | a response into a cache. This is especially effective when shared caches | |||
| are used to distribute malicious content to many clients. | are used to distribute malicious content to many clients. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| One common attack vector for cache poisoning is to exploit differences in | One common attack vector for cache poisoning is to exploit differences in | |||
| message parsing on proxies and in user agents; see <xref target="HTTP11" sect ion="6.3"/> for the relevant requirements regarding | message parsing on proxies and in user agents; see <xref target="HTTP11" sect ion="6.3"/> for the relevant requirements regarding | |||
| HTTP/1.1. | HTTP/1.1. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="security.timing" title="Timing Attacks"> | <section anchor="security.timing" title="Timing Attacks"> | |||
| <t> | <t> | |||
| Because one of the primary uses of a cache is to optimise performance, | Because one of the primary uses of a cache is to optimize performance, | |||
| its use can "leak" information about what resources have been previously | its use can "leak" information about which resources have been previously | |||
| requested. | requested. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| For example, if a user visits a site and their browser caches some of its | For example, if a user visits a site and their browser caches some of its | |||
| responses, and then navigates to a second site, that site can attempt to | responses and then navigates to a second site, that site can attempt to | |||
| load responses it knows exists on the first site. If they load | load responses it knows exist on the first site. If they load | |||
| quickly, it can be assumed that the user has visited that site, or even | quickly, it can be assumed that the user has visited that site, or even | |||
| a specific page on it. | a specific page on it. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Such "timing attacks" can be mitigated by adding more information to the | Such "timing attacks" can be mitigated by adding more information to the | |||
| cache key, such as the identity of the referring site (to prevent the | cache key, such as the identity of the referring site (to prevent the | |||
| attack described above). This is sometimes called "double keying." | attack described above). This is sometimes called "double keying". | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="caching.of.sensitive.information" | <section anchor="caching.of.sensitive.information" | |||
| title="Caching of Sensitive Information"> | title="Caching of Sensitive Information"> | |||
| <t> | <t> | |||
| Implementation and deployment flaws (as well as misunderstanding of cache | Implementation and deployment flaws (often led to by the misunderstanding of | |||
| operation) might lead to caching of sensitive information (e.g., | cache | |||
| operation) might lead to the caching of sensitive information (e.g., | ||||
| authentication credentials) that is thought to be private, exposing it to | authentication credentials) that is thought to be private, exposing it to | |||
| unauthorized parties. | unauthorized parties. | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Note that the Set-Cookie response header field <xref target="COOKIE"/> | Note that the Set-Cookie response header field <xref target="COOKIE"/> | |||
| does not inhibit caching; a cacheable response with a Set-Cookie header | does not inhibit caching; a cacheable response with a Set-Cookie header | |||
| field can be (and often is) used to satisfy subsequent requests to caches. | field can be (and often is) used to satisfy subsequent requests to caches. | |||
| Servers who wish to control caching of these responses are encouraged to | Servers that wish to control caching of these responses are encouraged to | |||
| emit appropriate Cache-Control response header fields. | emit appropriate Cache-Control response header fields. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </section> | </section> | |||
| <section anchor="iana.considerations" title="IANA Considerations"> | <section anchor="iana.considerations" title="IANA Considerations"> | |||
| <t> | <t> | |||
| The change controller for the following registrations is: | The change controller for the following registrations is: | |||
| "IETF (iesg@ietf.org) - Internet Engineering Task Force". | "IETF (iesg@ietf.org) - Internet Engineering Task Force". | |||
| </t> | </t> | |||
| <section anchor="field.name.registration" title="Field Name Registratio n"> | <section anchor="field.name.registration" title="Field Name Registratio n"> | |||
| <t> | <t> | |||
| First, introduce the new "Hypertext Transfer Protocol (HTTP) Field | IANA has updated the "Hypertext Transfer Protocol (HTTP) Field | |||
| Name Registry" at <eref target="https://www.iana.org/assignments/http-fields" | Name Registry" at <eref target="https://www.iana.org/assignments/http-fields" | |||
| brackets="angle"/> | brackets="angle"/>, | |||
| as described in | as described in <xref target="HTTP" section="18.4"/>, | |||
| <xref target="HTTP" section="18.4"/>. | with the field names listed in the table below: | |||
| </t> | </t> | |||
| <t> | ||||
| Then, please update the registry with the field names listed in the table | ||||
| below: | ||||
| </t> | ||||
| <!--AUTOGENERATED FROM extract-header-defs.xslt, do not edit manuall | ||||
| y--> | ||||
| <table align="left" anchor="iana.header.registration.table"> | <table align="left" anchor="iana.header.registration.table"> | |||
| <thead> | <thead> | |||
| <tr> | <tr> | |||
| <th>Field Name</th> | <th>Field Name</th> | |||
| <th>Status</th> | <th>Status</th> | |||
| <th>Ref.</th> | <th>Section</th> | |||
| <th>Comments</th> | <th>Comments</th> | |||
| </tr> | </tr> | |||
| </thead> | </thead> | |||
| <tbody> | <tbody> | |||
| <tr> | <tr> | |||
| <td>Age</td> | <td>Age</td> | |||
| <td>standard</td> | <td>permanent</td> | |||
| <td> | <td> | |||
| <xref target="field.age" format="counter"/> | <xref target="field.age" format="counter"/> | |||
| </td> | </td> | |||
| <td/> | <td/> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>Cache-Control</td> | <td>Cache-Control</td> | |||
| <td>standard</td> | <td>permanent</td> | |||
| <td> | <td> | |||
| <xref target="field.cache-control" format="counter"/> | <xref target="field.cache-control" format="counter"/> | |||
| </td> | </td> | |||
| <td/> | <td/> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>Expires</td> | <td>Expires</td> | |||
| <td>standard</td> | <td>permanent</td> | |||
| <td> | <td> | |||
| <xref target="field.expires" format="counter"/> | <xref target="field.expires" format="counter"/> | |||
| </td> | </td> | |||
| <td/> | <td/> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>Pragma</td> | <td>Pragma</td> | |||
| <td>standard</td> | <td>deprecated</td> | |||
| <td> | <td> | |||
| <xref target="field.pragma" format="counter"/> | <xref target="field.pragma" format="counter"/> | |||
| </td> | </td> | |||
| <td/> | <td/> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>Warning</td> | <td>Warning</td> | |||
| <td>obsoleted</td> | <td>obsoleted</td> | |||
| <td> | <td> | |||
| <xref target="field.warning" format="counter"/> | <xref target="field.warning" format="counter"/> | |||
| </td> | </td> | |||
| <td/> | <td/> | |||
| </tr> | </tr> | |||
| </tbody> | </tbody> | |||
| </table> | </table> | |||
| <!--(END)--> | ||||
| </section> | </section> | |||
| <section anchor="cache.directive.registration" | <section anchor="cache.directive.registration" | |||
| title="Cache Directive Registration"> | title="Cache Directive Registration"> | |||
| <t> | <t> | |||
| Please update the | IANA has updated the | |||
| "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" | "Hypertext Transfer Protocol (HTTP) Cache Directive Registry" | |||
| at <eref target="https://www.iana.org/assignments/http-cache-directives" | at <eref target="https://www.iana.org/assignments/http-cache-directives" | |||
| brackets="angle"/> | brackets="angle"/> | |||
| with the registration procedure of <xref target="cache.directive.registry"/> | with the registration procedure per <xref target="cache.directive.registry"/> | |||
| and the cache directive names summarized in the table below. | and the cache directive names summarized in the table below. | |||
| </t> | </t> | |||
| <!--AUTOGENERATED FROM extract-cache-directives-defs.xslt, do not ed it manually--> | ||||
| <table align="left" anchor="iana.cache.directive.registration.table" > | <table align="left" anchor="iana.cache.directive.registration.table" > | |||
| <thead> | <thead> | |||
| <tr> | <tr> | |||
| <th>Cache Directive</th> | <th>Cache Directive</th> | |||
| <th>Reference</th> | <th>Section</th> | |||
| </tr> | </tr> | |||
| </thead> | </thead> | |||
| <tbody> | <tbody> | |||
| <tr> | <tr> | |||
| <td>max-age</td> | <td>max-age</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.max-age"/>, <xref target="cache-response-directive.max-age"/> | <xref target="cache-request-directive.max-age" format="c ounter"/>, <xref target="cache-response-directive.max-age" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>max-stale</td> | <td>max-stale</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.max-stale"/> | <xref target="cache-request-directive.max-stale" format= "counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>min-fresh</td> | <td>min-fresh</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.min-fresh"/> | <xref target="cache-request-directive.min-fresh" format= "counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>must-revalidate</td> | <td>must-revalidate</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.must-revalidate"/ > | <xref target="cache-response-directive.must-revalidate" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>must-understand</td> | <td>must-understand</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.must-understand"/ > | <xref target="cache-response-directive.must-understand" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>no-cache</td> | <td>no-cache</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.no-cache"/>, <xref target="cache-response-directive.no-cache"/> | <xref target="cache-request-directive.no-cache" format=" counter"/>, <xref target="cache-response-directive.no-cache" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>no-store</td> | <td>no-store</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.no-store"/>, <xref target="cache-response-directive.no-store"/> | <xref target="cache-request-directive.no-store" format=" counter"/>, <xref target="cache-response-directive.no-store" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>no-transform</td> | <td>no-transform</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.no-transform"/>, < xref target="cache-response-directive.no-transform"/> | <xref target="cache-request-directive.no-transform" form at="counter"/>, <xref target="cache-response-directive.no-transform" format="cou nter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>only-if-cached</td> | <td>only-if-cached</td> | |||
| <td> | <td> | |||
| <xref target="cache-request-directive.only-if-cached"/> | <xref target="cache-request-directive.only-if-cached" fo rmat="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>private</td> | <td>private</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.private"/> | <xref target="cache-response-directive.private" format=" counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>proxy-revalidate</td> | <td>proxy-revalidate</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.proxy-revalidate" /> | <xref target="cache-response-directive.proxy-revalidate" format="counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>public</td> | <td>public</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.public"/> | <xref target="cache-response-directive.public" format="c ounter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| <tr> | <tr> | |||
| <td>s-maxage</td> | <td>s-maxage</td> | |||
| <td> | <td> | |||
| <xref target="cache-response-directive.s-maxage"/> | <xref target="cache-response-directive.s-maxage" format= "counter"/> | |||
| </td> | </td> | |||
| </tr> | </tr> | |||
| </tbody> | </tbody> | |||
| </table> | </table> | |||
| <!--(END)--> | ||||
| </section> | </section> | |||
| <section anchor="warn.code.registration" title="Warn Code Registry"> | <section anchor="warn.code.registration" title="Warn Code Registry"> | |||
| <t> | <t> | |||
| Please add a note to the "Hypertext Transfer Protocol (HTTP) Warn Codes" | IANA has added the following note to the "Hypertext Transfer Protocol (HTTP) Warn Codes" | |||
| registry at <eref target="https://www.iana.org/assignments/http-warn-codes" | registry at <eref target="https://www.iana.org/assignments/http-warn-codes" | |||
| brackets="angle"/> to the effect | brackets="angle"/> | |||
| that Warning is obsoleted. | stating that "Warning" has been obsoleted: | |||
| </t> | </t> | |||
| <blockquote> | ||||
| <t> | ||||
| The Warning header field (and the warn codes that it uses) has been obsoleted | ||||
| for HTTP per [RFC9111]. | ||||
| </t> | ||||
| </blockquote> | ||||
| </section> | </section> | |||
| </section> | </section> | |||
| </middle> | </middle> | |||
| <back> | <back> | |||
| <displayreference xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" | ||||
| xmlns:x="http://purl.org/net/xml2rfc/ext" | <displayreference target="HTTP11" to="HTTP/1.1"/> | |||
| target="HTTP11" | ||||
| to="HTTP/1.1"/> | ||||
| <references> | <references> | |||
| <name>References</name> | <name>References</name> | |||
| <references> | <references> | |||
| <name>Normative References</name> | <name>Normative References</name> | |||
| <reference anchor="HTTP"><!--included from draft-ietf-httpbis-semant | ||||
| ics-latest.xml--> | <!-- [HTTP][I-D.ietf-httpbis-semantics-19]; companion document RFC 9110 --> | |||
| <front> | <reference anchor='HTTP' target='https://www.rfc-editor.org/info/rfc9110'> | |||
| <title>HTTP Semantics</title> | <front> | |||
| <author fullname="Roy T. Fielding" | <title>HTTP Semantics</title> | |||
| initials="R." | <author initials='R' surname='Fielding' fullname='Roy T. Fielding' role="editor" | |||
| surname="Fielding" | > | |||
| role="editor"> | <organization /> | |||
| <organization>Adobe</organization> | </author> | |||
| <address> | <author initials='M' surname='Nottingham' fullname='Mark Nottingham' role="edito | |||
| <postal> | r"> | |||
| <postalLine>345 Park Ave</postalLine> | <organization /> | |||
| <postalLine>San Jose, CA 95110</postalLine> | </author> | |||
| <postalLine>United States of America</postalLine> | <author initials='J' surname='Reschke' fullname='Julian Reschke' role="editor"> | |||
| </postal> | <organization /> | |||
| <email>fielding@gbiv.com</email> | </author> | |||
| <uri>https://roy.gbiv.com/</uri> | <date year='2022' month='June'/> | |||
| </address> | </front> | |||
| </author> | <seriesInfo name="STD" value="97"/> | |||
| <author fullname="Mark Nottingham" | <seriesInfo name="RFC" value="9110"/> | |||
| initials="M." | <seriesInfo name="DOI" value="10.17487/RFC9110"/> | |||
| surname="Nottingham" | </reference> | |||
| role="editor"> | ||||
| <organization>Fastly</organization> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2119. | |||
| <address> | xml"/> | |||
| <postal> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7405. | |||
| <postalLine>Prahran VIC</postalLine> | xml"/> | |||
| <postalLine>Australia</postalLine> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8174. | |||
| </postal> | xml"/> | |||
| <email>mnot@mnot.net</email> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5234. | |||
| <uri>https://www.mnot.net/</uri> | xml"/> | |||
| </address> | ||||
| </author> | ||||
| <author fullname="Julian Reschke" | ||||
| initials="J." | ||||
| surname="Reschke" | ||||
| role="editor"> | ||||
| <organization abbrev="greenbytes">greenbytes GmbH</organiza | ||||
| tion> | ||||
| <address> | ||||
| <postal> | ||||
| <postalLine>Hafenweg 16</postalLine> | ||||
| <postalLine>48155 Münster</postalLine> | ||||
| <postalLine>Germany</postalLine> | ||||
| </postal> | ||||
| <email>julian.reschke@greenbytes.de</email> | ||||
| <uri>https://greenbytes.de/tech/webdav/</uri> | ||||
| </address> | ||||
| </author> | ||||
| <date year="2021" month="September" day="10"/> | ||||
| </front> | ||||
| <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-seman | ||||
| tics-19"/> | ||||
| </reference> | ||||
| <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/ | ||||
| rfc2119"> | ||||
| <front> | ||||
| <title>Key words for use in RFCs to Indicate Requirement Level | ||||
| s</title> | ||||
| <author initials="S." surname="Bradner" fullname="Scott Bradne | ||||
| r"/> | ||||
| <date month="March" year="1997"/> | ||||
| </front> | ||||
| <seriesInfo name="BCP" value="14"/> | ||||
| <seriesInfo name="RFC" value="2119"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC2119"/> | ||||
| </reference> | ||||
| <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/ | ||||
| rfc8174"> | ||||
| <front> | ||||
| <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Wor | ||||
| ds</title> | ||||
| <author initials="B." surname="Leiba" fullname="Barry Leiba"/> | ||||
| <date year="2017" month="May"/> | ||||
| </front> | ||||
| <seriesInfo name="BCP" value="14"/> | ||||
| <seriesInfo name="RFC" value="8174"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC8174"/> | ||||
| </reference> | ||||
| <reference anchor="RFC5234" target="https://www.rfc-editor.org/info/ | ||||
| rfc5234"> | ||||
| <front> | ||||
| <title abbrev="ABNF for Syntax Specifications">Augmented BNF f | ||||
| or Syntax Specifications: ABNF</title> | ||||
| <author initials="D." | ||||
| surname="Crocker" | ||||
| fullname="Dave Crocker" | ||||
| role="editor"/> | ||||
| <author initials="P." surname="Overell" fullname="Paul Overell | ||||
| "/> | ||||
| <date month="January" year="2008"/> | ||||
| </front> | ||||
| <seriesInfo name="STD" value="68"/> | ||||
| <seriesInfo name="RFC" value="5234"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC5234"/> | ||||
| </reference> | ||||
| <reference anchor="RFC7405" target="https://www.rfc-editor.org/info/ | ||||
| rfc7405"> | ||||
| <front> | ||||
| <title>Case-Sensitive String Support in ABNF</title> | ||||
| <author initials="P." surname="Kyzivat" fullname="Dave Kyzivat | ||||
| "/> | ||||
| <date month="December" year="2014"/> | ||||
| </front> | ||||
| <seriesInfo name="RFC" value="7405"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC7405"/> | ||||
| </reference> | ||||
| </references> | </references> | |||
| <references> | <references> | |||
| <name>Informative References</name> | <name>Informative References</name> | |||
| <reference anchor="HTTP11"><!--included from draft-ietf-httpbis-mess | ||||
| aging-latest.xml--> | <!-- [HTTP/1.1] [draft-ietf-httpbis-messaging]; companion document RFC 9112 --> | |||
| <front> | <reference anchor="HTTP11" target='https://www.rfc-editor.org/info/rfc9112'> | |||
| <title>HTTP/1.1</title> | <front> | |||
| <author fullname="Roy T. Fielding" | <title>HTTP/1.1</title> | |||
| initials="R." | <author fullname="Roy Fielding" role="editor"> | |||
| surname="Fielding" | <organization>Adobe</organization> | |||
| role="editor"> | </author> | |||
| <organization>Adobe</organization> | <author fullname="Mark Nottingham" role="editor"> | |||
| <address> | <organization>Fastly</organization> | |||
| <postal> | </author> | |||
| <postalLine>345 Park Ave</postalLine> | <author fullname="Julian Reschke" role="editor"> | |||
| <postalLine>San Jose, CA 95110</postalLine> | <organization>greenbytes GmbH</organization> | |||
| <postalLine>United States of America</postalLine> | </author> | |||
| </postal> | <date month="June" year="2022"/> | |||
| <email>fielding@gbiv.com</email> | </front> | |||
| <uri>https://roy.gbiv.com/</uri> | <seriesInfo name="STD" value="99"/> | |||
| </address> | <seriesInfo name="RFC" value="9112"/> | |||
| </author> | <seriesInfo name="DOI" value="10.17487/RFC9112"/> | |||
| <author fullname="Mark Nottingham" | </reference> | |||
| initials="M." | ||||
| surname="Nottingham" | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.2616. | |||
| role="editor"> | xml"/> | |||
| <organization>Fastly</organization> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.7234. | |||
| <address> | xml"/> | |||
| <postal> | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.5861. | |||
| <postalLine>Prahran VIC</postalLine> | xml"/> | |||
| <postalLine>Australia</postalLine> | ||||
| </postal> | ||||
| <email>mnot@mnot.net</email> | ||||
| <uri>https://www.mnot.net/</uri> | ||||
| </address> | ||||
| </author> | ||||
| <author fullname="Julian Reschke" | ||||
| initials="J." | ||||
| surname="Reschke" | ||||
| role="editor"> | ||||
| <organization abbrev="greenbytes">greenbytes GmbH</organiza | ||||
| tion> | ||||
| <address> | ||||
| <postal> | ||||
| <postalLine>Hafenweg 16</postalLine> | ||||
| <postalLine>48155 Münster</postalLine> | ||||
| <postalLine>Germany</postalLine> | ||||
| </postal> | ||||
| <email>julian.reschke@greenbytes.de</email> | ||||
| <uri>https://greenbytes.de/tech/webdav/</uri> | ||||
| </address> | ||||
| </author> | ||||
| <date year="2021" month="September" day="10"/> | ||||
| </front> | ||||
| <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-messa | ||||
| ging-19"/> | ||||
| </reference> | ||||
| <reference anchor="RFC2616" target="https://www.rfc-editor.org/info/ | ||||
| rfc2616"> | ||||
| <front> | ||||
| <title>Hypertext Transfer Protocol -- HTTP/1.1</title> | ||||
| <author fullname="R. Fielding" initials="R." surname="Fielding | ||||
| "/> | ||||
| <author fullname="J. Gettys" initials="J." surname="Gettys"/> | ||||
| <author fullname="J. Mogul" initials="J." surname="Mogul"/> | ||||
| <author fullname="H. Frystyk" initials="H." surname="Frystyk"/ | ||||
| > | ||||
| <author fullname="L. Masinter" initials="L." surname="Masinter | ||||
| "/> | ||||
| <author fullname="P. Leach" initials="P." surname="Leach"/> | ||||
| <author fullname="T. Berners-Lee" initials="T." surname="Berne | ||||
| rs-Lee"/> | ||||
| <date month="June" year="1999"/> | ||||
| </front> | ||||
| <seriesInfo name="RFC" value="2616"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC2616"/> | ||||
| </reference> | ||||
| <reference anchor="RFC7234" target="https://www.rfc-editor.org/info/ | ||||
| rfc7234"> | ||||
| <front> | ||||
| <title>Hypertext Transfer Protocol (HTTP): Caching</title> | ||||
| <author initials="R." | ||||
| surname="Fielding" | ||||
| fullname="Roy T. Fielding" | ||||
| role="editor"/> | ||||
| <author initials="M." | ||||
| surname="Nottingham" | ||||
| fullname="Mark Nottingham" | ||||
| role="editor"/> | ||||
| <author initials="J. F." | ||||
| surname="Reschke" | ||||
| fullname="Julian F. Reschke" | ||||
| role="editor"/> | ||||
| <date month="June" year="2014"/> | ||||
| </front> | ||||
| <seriesInfo name="RFC" value="7234"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC7234"/> | ||||
| </reference> | ||||
| <reference anchor="RFC5861" target="https://www.rfc-editor.org/info/ | ||||
| rfc5861"> | ||||
| <front> | ||||
| <title abbrev="HTTP stale controls">HTTP Cache-Control Extensi | ||||
| ons for Stale Content</title> | ||||
| <author initials="M." surname="Nottingham" fullname="Mark Nott | ||||
| ingham"/> | ||||
| <date month="April" year="2010"/> | ||||
| </front> | ||||
| <seriesInfo name="RFC" value="5861"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC5861"/> | ||||
| </reference> | ||||
| <reference anchor="COOKIE" target="https://www.rfc-editor.org/info/r fc6265"> | <reference anchor="COOKIE" target="https://www.rfc-editor.org/info/r fc6265"> | |||
| <front> | <front> | |||
| <title>HTTP State Management Mechanism</title> | <title>HTTP State Management Mechanism</title> | |||
| <author initials="A." surname="Barth" fullname="Adam Barth"/> | <author initials="A." surname="Barth" fullname="Adam Barth"/> | |||
| <date year="2011" month="April"/> | <date year="2011" month="April"/> | |||
| </front> | </front> | |||
| <seriesInfo name="RFC" value="6265"/> | <seriesInfo name="RFC" value="6265"/> | |||
| <seriesInfo name="DOI" value="10.17487/RFC6265"/> | <seriesInfo name="DOI" value="10.17487/RFC6265"/> | |||
| </reference> | </reference> | |||
| <reference anchor="RFC8126" target="https://www.rfc-editor.org/info/ | <xi:include href="https://xml2rfc.ietf.org/public/rfc/bibxml/reference.RFC.8126. | |||
| rfc8126"> | xml"/> | |||
| <front> | ||||
| <title>Guidelines for Writing an IANA Considerations Section i | ||||
| n RFCs</title> | ||||
| <author initials="M." surname="Cotton" fullname="M. Cotton"/> | ||||
| <author initials="B." surname="Leiba" fullname="B. Leiba"/> | ||||
| <author initials="T." surname="Narten" fullname="T. Narten"/> | ||||
| <date year="2017" month="June"/> | ||||
| </front> | ||||
| <seriesInfo name="BCP" value="26"/> | ||||
| <seriesInfo name="RFC" value="8126"/> | ||||
| <seriesInfo name="DOI" value="10.17487/RFC8126"/> | ||||
| </reference> | ||||
| </references> | </references> | |||
| </references> | </references> | |||
| <section anchor="collected.abnf" title="Collected ABNF"> | <section anchor="collected.abnf" title="Collected ABNF"> | |||
| <t>In the collected ABNF below, list rules are expanded as per <xref ta | <t>In the collected ABNF below, list rules are expanded per <xref targe | |||
| rget="HTTP" section="5.6.1"/>.</t> | t="HTTP" section="5.6.1"/>.</t> | |||
| <sourcecode type="abnf" name="draft-ietf-httpbis-cache-latest.parsed-ab | <sourcecode type="abnf" name="rfc9111.parsed-abnf"><![CDATA[Age = delta | |||
| nf"><![CDATA[Age = delta-seconds | -seconds | |||
| Cache-Control = [ cache-directive *( OWS "," OWS cache-directive ) ] | Cache-Control = [ cache-directive *( OWS "," OWS cache-directive ) ] | |||
| Expires = HTTP-date | Expires = HTTP-date | |||
| HTTP-date = <HTTP-date, see [HTTP], Section 5.6.7> | HTTP-date = <HTTP-date, see [HTTP], Section 5.6.7> | |||
| OWS = <OWS, see [HTTP], Section 5.6.3> | OWS = <OWS, see [HTTP], Section 5.6.3> | |||
| cache-directive = token [ "=" ( token / quoted-string ) ] | cache-directive = token [ "=" ( token / quoted-string ) ] | |||
| skipping to change at line 2379 ¶ | skipping to change at line 2219 ¶ | |||
| token = <token, see [HTTP], Section 5.6.2> | token = <token, see [HTTP], Section 5.6.2> | |||
| ]]></sourcecode> | ]]></sourcecode> | |||
| </section> | </section> | |||
| <section anchor="changes.from.rfc.7234" title="Changes from RFC 7234"> | <section anchor="changes.from.rfc.7234" title="Changes from RFC 7234"> | |||
| <t> | <t> | |||
| Handling of duplicate and conflicting cache directives has been clarified. | Handling of duplicate and conflicting cache directives has been clarified. | |||
| (<xref target="calculating.freshness.lifetime"/>) | (<xref target="calculating.freshness.lifetime"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Cache invalidation of the URIs in the Location and Content-Location | Cache invalidation of the URIs in the Location and Content-Location | |||
| header fields is no longer required, but still allowed. | header fields is no longer required but is still allowed. | |||
| (<xref target="invalidation"/>) | (<xref target="invalidation"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Cache invalidation of the URIs in the Location and Content-Location header fi elds is disallowed | Cache invalidation of the URIs in the Location and Content-Location header fi elds is disallowed | |||
| when the origin is different; previously, it was the host. | when the origin is different; previously, it was the host. | |||
| (<xref target="invalidation"/>) | (<xref target="invalidation"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| Handling invalid and multiple Age header field values has been clarified. | Handling invalid and multiple Age header field values has been clarified. | |||
| (<xref target="field.age"/>) | (<xref target="field.age"/>) | |||
| skipping to change at line 2401 ¶ | skipping to change at line 2241 ¶ | |||
| <t> | <t> | |||
| Some cache directives defined by this specification now have stronger | Some cache directives defined by this specification now have stronger | |||
| prohibitions against generating the quoted form of their values, since | prohibitions against generating the quoted form of their values, since | |||
| this has been found to create interoperability problems. Consumers of | this has been found to create interoperability problems. Consumers of | |||
| extension cache directives are no longer required to accept both token and | extension cache directives are no longer required to accept both token and | |||
| quoted-string forms, but they still need to parse them properly for | quoted-string forms, but they still need to parse them properly for | |||
| unknown extensions. | unknown extensions. | |||
| (<xref target="field.cache-control"/>) | (<xref target="field.cache-control"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The "public" and "private" cache directives were clarified, so that they | The public and private cache directives were clarified, so that they | |||
| do not make responses reusable under any condition. | do not make responses reusable under any condition. | |||
| (<xref target="cache-response-directive"/>) | (<xref target="cache-response-directive"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The "must-understand" cache directive was introduced; caches are no | The must-understand cache directive was introduced; caches are no | |||
| longer required to understand the semantics of new response status codes | longer required to understand the semantics of new response status codes | |||
| unless it is present. | unless it is present. | |||
| (<xref target="cache-response-directive.must-understand"/>) | (<xref target="cache-response-directive.must-understand"/>) | |||
| </t> | </t> | |||
| <t> | <t> | |||
| The Warning response header was obsoleted. Much of the information | The Warning response header was obsoleted. Much of the information | |||
| supported by Warning could be gleaned by examining the response, and the | supported by Warning could be gleaned by examining the response, and the | |||
| remaining warn-codes — although potentially useful — were entirely | remaining information -- although potentially useful -- was entirely | |||
| advisory. In practice, Warning was not added by caches or intermediaries. | advisory. In practice, Warning was not added by caches or intermediaries. | |||
| (<xref target="field.warning"/>) | (<xref target="field.warning"/>) | |||
| </t> | </t> | |||
| </section> | </section> | |||
| <section anchor="change.log" title="Change Log"> | ||||
| <t>This section is to be removed before publishing as an RFC.</t> | ||||
| <section anchor="changes.since.publication.as.rfc" | ||||
| title="Between RFC7234 and draft 00"> | ||||
| <t> | ||||
| The changes were purely editorial: | ||||
| </t> | ||||
| <ul> | ||||
| <li>Change boilerplate and abstract to indicate the "draft" statu | ||||
| s, and update references to ancestor specifications.</li> | ||||
| <li>Remove version "1.1" from document title, indicating that thi | ||||
| s specification applies to all HTTP versions.</li> | ||||
| <li>Adjust historical notes.</li> | ||||
| <li>Update links to sibling specifications.</li> | ||||
| <li>Replace sections listing changes from RFC 2616 by new empty s | ||||
| ections referring to RFC 723x.</li> | ||||
| <li>Remove acknowledgements specific to RFC 723x.</li> | ||||
| <li>Move "Acknowledgements" to the very end and make them unnumbe | ||||
| red.</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.00" title="Since draft-ietf-httpbis-cach | ||||
| e-00"> | ||||
| <t> | ||||
| The changes are purely editorial: | ||||
| </t> | ||||
| <ul> | ||||
| <li>Moved all extensibility tips, registration procedures, and re | ||||
| gistry | ||||
| tables from the IANA considerations to normative sections, reducing the | ||||
| IANA considerations to just instructions that will be removed prior to | ||||
| publication as an RFC.</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.01" title="Since draft-ietf-httpbis-cach | ||||
| e-01"> | ||||
| <ul> | ||||
| <li>Cite RFC 8126 instead of RFC 5226 (<eref target="https://gith | ||||
| ub.com/httpwg/http-core/issues/75" brackets="angle"/>)</li> | ||||
| <li>In <xref target="field.pragma"/>, misleading statement about | ||||
| the relation between Pragma and Cache-Control (<eref target="https://github.com/ | ||||
| httpwg/http-core/issues/92" brackets="angle"/>, <eref target="https://www.rfc-ed | ||||
| itor.org/errata/eid4674" brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.02" title="Since draft-ietf-httpbis-cach | ||||
| e-02"> | ||||
| <ul> | ||||
| <li>In <xref target="response.cacheability"/>, explain that only | ||||
| final responses are cacheable (<eref target="https://github.com/httpwg/http-core | ||||
| /issues/29" brackets="angle"/>)</li> | ||||
| <li>In <xref target="cache-response-directive"/>, clarify what re | ||||
| sponses various directives apply to (<eref target="https://github.com/httpwg/htt | ||||
| p-core/issues/52" brackets="angle"/>)</li> | ||||
| <li>In <xref target="validation.sent"/>, clarify the source of va | ||||
| lidators in conditional requests (<eref target="https://github.com/httpwg/http-c | ||||
| ore/issues/110" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Revise <xref target="history.lists"/> to apply to more than j | ||||
| ust History Lists (<eref target="https://github.com/httpwg/http-core/issues/126" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="field.warning"/>, deprecated "Warning" heade | ||||
| r field (<eref target="https://github.com/httpwg/http-core/issues/139" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="caching.authenticated.responses"/>, remove a | ||||
| spurious note (<eref target="https://github.com/httpwg/http-core/issues/141" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.03" title="Since draft-ietf-httpbis-cach | ||||
| e-03"> | ||||
| <ul> | ||||
| <li>In <xref target="caching.overview"/>, define what a disconnec | ||||
| ted cache is (<eref target="https://github.com/httpwg/http-core/issues/5" bracke | ||||
| ts="angle"/>)</li> | ||||
| <li>In <xref target="constructing.responses.from.caches"/>, clari | ||||
| fy language around how to select a response when more than one matches (<eref ta | ||||
| rget="https://github.com/httpwg/http-core/issues/23" brackets="angle"/>)</li> | ||||
| <li>in <xref target="serving.stale.responses"/>, mention stale-wh | ||||
| ile-revalidate and stale-if-error (<eref target="https://github.com/httpwg/http- | ||||
| core/issues/122" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Remove requirements around cache request directives (<eref ta | ||||
| rget="https://github.com/httpwg/http-core/issues/129" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Deprecate Pragma (<eref target="https://github.com/httpwg/htt | ||||
| p-core/issues/140" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="caching.authenticated.responses"/> and <xref | ||||
| target="cache-response-directive"/>, note effect of some directives on authenti | ||||
| cated requests (<eref target="https://github.com/httpwg/http-core/issues/161" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.04" title="Since draft-ietf-httpbis-cach | ||||
| e-04"> | ||||
| <ul> | ||||
| <li>In <xref target="field.cache-control"/>, remove the registrat | ||||
| ions for stale-if-error and stale-while-revalidate which happened in RFC 7234 (< | ||||
| eref target="https://github.com/httpwg/http-core/issues/207" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.05" title="Since draft-ietf-httpbis-cach | ||||
| e-05"> | ||||
| <ul> | ||||
| <li>In <xref target="incomplete.responses"/>, clarify how weakly | ||||
| framed content is considered for purposes of completeness (<eref target="https:/ | ||||
| /github.com/httpwg/http-core/issues/25" brackets="angle"/>)</li> | ||||
| <li>Throughout, describe Vary and cache key operations more clear | ||||
| ly (<eref target="https://github.com/httpwg/http-core/issues/28" brackets="angle | ||||
| "/>)</li> | ||||
| <li>In <xref target="response.cacheability"/>, remove concept of | ||||
| "cacheable methods" in favor of prose (<eref target="https://github.com/httpwg/h | ||||
| ttp-core/issues/54" brackets="angle"/>, <eref target="https://www.rfc-editor.org | ||||
| /errata/eid5300" brackets="angle"/>)</li> | ||||
| <li>Refactored <xref target="security.considerations"/>, and adde | ||||
| d a section on timing attacks (<eref target="https://github.com/httpwg/http-core | ||||
| /issues/233" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Changed "cacheable by default" to "heuristically cacheable" t | ||||
| hroughout (<eref target="https://github.com/httpwg/http-core/issues/242" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.06" title="Since draft-ietf-httpbis-cach | ||||
| e-06"> | ||||
| <ul> | ||||
| <li>In <xref target="response.cacheability"/> and <xref target="c | ||||
| ache-response-directive.must-understand"/>, change response cacheability to only | ||||
| require understanding the response status code if the must-understand cache dir | ||||
| ective is present (<eref target="https://github.com/httpwg/http-core/issues/120" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Change requirements for handling different forms of cache dir | ||||
| ectives in <xref target="field.cache-control"/> (<eref target="https://github.co | ||||
| m/httpwg/http-core/issues/128" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Fix typo in <xref target="cache-response-directive.s-maxage"/ | ||||
| > (<eref target="https://github.com/httpwg/http-core/issues/264" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="cache-response-directive.public"/> and <xref | ||||
| target="cache-response-directive.private"/>, clarify "private" and "public" so | ||||
| that they do not override all other cache directives (<eref target="https://gith | ||||
| ub.com/httpwg/http-core/issues/268" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="response.cacheability"/>, distinguish betwee | ||||
| n private with and without qualifying headers (<eref target="https://github.com/ | ||||
| httpwg/http-core/issues/270" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="caching.negotiated.responses"/>, clarify tha | ||||
| t any "*" as a member of Vary will disable caching (<eref target="https://github | ||||
| .com/httpwg/http-core/issues/286" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="requirements.notation"/>, reference RFC 8174 | ||||
| as well (<eref target="https://github.com/httpwg/http-core/issues/303" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.07" title="Since draft-ietf-httpbis-cach | ||||
| e-07"> | ||||
| <ul> | ||||
| <li>Throughout, replace "effective request URI", "request-target" | ||||
| and similar with "target URI" (<eref target="https://github.com/httpwg/http-cor | ||||
| e/issues/259" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="cache-response-directive.public"/> and <xref | ||||
| target="cache-response-directive.private"/>, make it clear that these directive | ||||
| s do not ignore other requirements for caching (<eref target="https://github.com | ||||
| /httpwg/http-core/issues/320" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="incomplete.responses"/>, move definition of | ||||
| "complete" into semantics (<eref target="https://github.com/httpwg/http-core/iss | ||||
| ues/334" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.08" title="Since draft-ietf-httpbis-cach | ||||
| e-08"> | ||||
| <ul> | ||||
| <li> | ||||
| <xref target="collected.abnf"/> now uses the sender variant of | ||||
| the "#" list expansion (<eref target="https://github.com/httpwg/http-core/issue | ||||
| s/192" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.09" title="Since draft-ietf-httpbis-cach | ||||
| e-09"> | ||||
| <ul> | ||||
| <li>In <xref target="field.age"/>, discuss handling of invalid an | ||||
| d multiple Age header field values (<eref target="https://github.com/httpwg/http | ||||
| -core/issues/193" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Switch to xml2rfc v3 mode for draft generation (<eref target= | ||||
| "https://github.com/httpwg/http-core/issues/394" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.10" title="Since draft-ietf-httpbis-cach | ||||
| e-10"> | ||||
| <ul> | ||||
| <li>In <xref target="field.cache-control"/> (<xref target="field. | ||||
| cache-control" format="none">Cache-Control</xref>), adjust ABNF to allow empty l | ||||
| ists (<eref target="https://github.com/httpwg/http-core/issues/210" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.11" title="Since draft-ietf-httpbis-cach | ||||
| e-11"> | ||||
| <ul> | ||||
| <li>None.</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.12" title="Since draft-ietf-httpbis-cach | ||||
| e-12"> | ||||
| <ul> | ||||
| <li>In <xref target="serving.stale.responses"/>, remove 'no-store | ||||
| ', as it won't be in cache in the first place (<eref target="https://github.com/ | ||||
| httpwg/http-core/issues/447" | ||||
| brackets="angle"/>, <eref target="https://www.rfc-editor | ||||
| .org/errata/eid6279" brackets="angle"/>)</li> | ||||
| <li>In <xref target="storing.fields"/>, make it clear that only r | ||||
| esponse headers need be stored (<eref target="https://github.com/httpwg/http-cor | ||||
| e/issues/457" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Rewrote "Updating Stored Header Fields" <xref target="update" | ||||
| /> (<eref target="https://github.com/httpwg/http-core/issues/458" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="calculating.freshness.lifetime"/> clarify ho | ||||
| w to handle invalid and conflicting directives (<eref target="https://github.com | ||||
| /httpwg/http-core/issues/460" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="validation.response"/>, mention retry of fai | ||||
| led validation requests (<eref target="https://github.com/httpwg/http-core/issue | ||||
| s/462" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="validation.response"/>, clarify requirement | ||||
| on storing a full response to a conditional request (<eref target="https://githu | ||||
| b.com/httpwg/http-core/issues/463" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="field.age"/>, clarify error handling (<eref | ||||
| target="https://github.com/httpwg/http-core/issues/471" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="expiration.model"/>, remove spurious "UTC" ( | ||||
| <eref target="https://github.com/httpwg/http-core/issues/472" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="expiration.model"/>, correct the date-relate | ||||
| d rule names to consider case-insensitive (<eref target="https://github.com/http | ||||
| wg/http-core/issues/473" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="history.lists"/>, strengthen recommendation | ||||
| for application caches to pay attention to cache directives (<eref target="https | ||||
| ://github.com/httpwg/http-core/issues/474" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="constructing.responses.from.caches"/>, menti | ||||
| on collapsed requests (<eref target="https://github.com/httpwg/http-core/issues/ | ||||
| 475" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="invalidation"/>, relax requirements on Conte | ||||
| nt-Location and Location invalidation (<eref target="https://github.com/httpwg/h | ||||
| ttp-core/issues/478" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="freshening.responses"/>, refine the exceptio | ||||
| ns to update on a 304 (<eref target="https://github.com/httpwg/http-core/issues/ | ||||
| 488" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Moved table of Cache-Control directives into <xref target="ca | ||||
| che.directive.registration"/> (<eref target="https://github.com/httpwg/http-core | ||||
| /issues/506" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="notation"/>, remove unused core ABNF rules ( | ||||
| <eref target="https://github.com/httpwg/http-core/issues/529" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Changed to using "payload data" when defining requirements ab | ||||
| out the data being conveyed within a message, instead of the terms "payload body | ||||
| " or "response body" or "representation body", since they often get confused wit | ||||
| h the HTTP/1.1 message body (which includes transfer coding) (<eref target="http | ||||
| s://github.com/httpwg/http-core/issues/553" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.13" title="Since draft-ietf-httpbis-cach | ||||
| e-13"> | ||||
| <ul> | ||||
| <li>In <xref target="cache-response-directive.must-revalidate"/>, | ||||
| clarify requirements around generating an error response (<eref target="https:/ | ||||
| /github.com/httpwg/http-core/issues/608" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Changed to using "content" instead of "payload" or "payload d | ||||
| ata" to avoid confusion with the payload of version-specific messaging frames (< | ||||
| eref target="https://github.com/httpwg/http-core/issues/654" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="freshening.responses"/>, clarify how multipl | ||||
| e validators are handled (<eref target="https://github.com/httpwg/http-core/issu | ||||
| es/659" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="age.calculations"/>, <xref target="field.cac | ||||
| he-control"/>, and <xref target="cache-response-directive.no-cache"/>, remove no | ||||
| tes about very old HTTP/1.0 behaviours (<eref target="https://github.com/httpwg/ | ||||
| http-core/issues/660" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="cache-response-directive.must-understand"/>, | ||||
| modify operation to be more backwards-compatible with existing implementations | ||||
| (<eref target="https://github.com/httpwg/http-core/issues/661" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.14" title="Since draft-ietf-httpbis-cach | ||||
| e-14"> | ||||
| <ul> | ||||
| <li>Fix subsection ordering in <xref target="cache-response-direc | ||||
| tive"/> (<eref target="https://github.com/httpwg/http-core/issues/674" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="caching.overview"/>, define what a cache key | ||||
| is (<eref target="https://github.com/httpwg/http-core/issues/728" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="storing.fields"/>, clarify what cache proxy | ||||
| headers apply to (<eref target="https://github.com/httpwg/http-core/issues/729" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="cache.poisoning"/>, cache poisoning can affe | ||||
| ct private caches too (<eref target="https://github.com/httpwg/http-core/issues/ | ||||
| 730" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="field.age"/>, adjust handling of invalid val | ||||
| ues to match most deployed caches (<eref target="https://github.com/httpwg/http- | ||||
| core/issues/778" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="field.expires"/>, mention parsing requiremen | ||||
| t relaxation (<eref target="https://github.com/httpwg/http-core/issues/779" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.15" title="Since draft-ietf-httpbis-cach | ||||
| e-15"> | ||||
| <ul> | ||||
| <li>In <xref target="validation.sent"/>, tune description of rela | ||||
| tion between cache keys and validators (<eref target="https://github.com/httpwg/ | ||||
| http-core/issues/832" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.16" title="Since draft-ietf-httpbis-cach | ||||
| e-16"> | ||||
| <t> | ||||
| This draft addresses mostly editorial issues raised during or past IETF | ||||
| Last Call; see <eref target="https://github.com/httpwg/http-core/issues?q=labe | ||||
| l%3Acaching+created%3A%3E2021-05-26" | ||||
| brackets="angle"/> | ||||
| for a summary. | ||||
| </t> | ||||
| <t> | ||||
| Furthermore: | ||||
| </t> | ||||
| <ul> | ||||
| <li>Addressed Genart last call review comments (<eref target="htt | ||||
| ps://github.com/httpwg/http-core/issues/847" | ||||
| brackets="angle"/>)</li> | ||||
| <li>In <xref target="freshening.responses"/>, clarify that only s | ||||
| electable responses are updated (<eref target="https://github.com/httpwg/http-co | ||||
| re/issues/839" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.17" title="Since draft-ietf-httpbis-cach | ||||
| e-17"> | ||||
| <ul> | ||||
| <li>Made reference to <xref target="HTTP11"/> informative only (< | ||||
| eref target="https://github.com/httpwg/http-core/issues/911" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Move cache-related aspects of validator use from <xref target | ||||
| ="HTTP"/> into <xref target="validation.sent"/> (<eref target="https://github.co | ||||
| m/httpwg/http-core/issues/933" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Use term "clock" defined in <xref target="HTTP" section="6.6. | ||||
| 1"/> throughout (<eref target="https://github.com/httpwg/http-core/issues/953" | ||||
| brackets="angle"/>)</li> | ||||
| <li>Throughout, disambiguate "selected representation" and "selec | ||||
| ted response" (now "chosen response") (<eref target="https://github.com/httpwg/h | ||||
| ttp-core/issues/958" | ||||
| brackets="angle"/>)</li> | ||||
| </ul> | ||||
| </section> | ||||
| <section anchor="changes.since.18" title="Since draft-ietf-httpbis-cach | ||||
| e-18"> | ||||
| <ul> | ||||
| <li>None.</li> | ||||
| </ul> | ||||
| </section> | ||||
| </section> | ||||
| <section anchor="acks" numbered="false" title="Acknowledgements"> | <section anchor="acks" numbered="false" title="Acknowledgements"> | |||
| <t> | <t> | |||
| See Appendix "Acknowledgements" of <xref target="HTTP"/>. | See Appendix "Acknowledgements" of <xref target="HTTP"/>, which applies to thi s document as well. | |||
| </t> | </t> | |||
| </section> | </section> | |||
| </back> | </back> | |||
| </rfc> | </rfc> | |||
| End of changes. 195 change blocks. | ||||
| 929 lines changed or deleted | 358 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||