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/ |