<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.5.2 -->
<?rfc toc="yes"?>
<?rfc tocindent="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<?rfc strict="yes"?>
<?rfc compact="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc-ext html-pretty-print="prettyprint https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"?>
<rfc xmlns:x="http://purl.org/net/xml2rfc/ext"
     category="std"
     docName="draft-ietf-httpbis-targeted-cache-control-00"
     ipr="trust200902"
     submissionType="IETF">
   <x:feedback template="mailto:ietf-http-wg@w3.org?subject={docname},%20%22{section}%22\&amp;amp;body=%3c{ref}%3e:"/>
   <front>
      <title>Targeted HTTP Cache Control</title>
      <author fullname="Stephen Ludin" initials="S." surname="Ludin">
         <organization>Akamai</organization>
         <address>
            <email>sludin@ludin.org</email>
         </address>
      </author>
      <author fullname="Mark Nottingham" initials="M." surname="Nottingham">
         <organization>Fastly</organization>
         <address>
            <postal>
               <postalLine>Prahran</postalLine>
               <postalLine>VIC</postalLine>
               <postalLine>Australia</postalLine>
            </postal>
            <email>mnot@mnot.net</email>
            <uri>https://www.mnot.net/</uri>
         </address>
      </author>
      <author fullname="Yuchen Wu" initials="Y." surname="Wu">
         <organization>Cloudflare</organization>
         <address>
            <email>me@yuchenwu.net</email>
         </address>
      </author>
      <date year="2021" month="July" day="26"/>
      <area>General</area>
      <workgroup>HTTP</workgroup>
      <keyword>CDN</keyword>
      <keyword>Content Delivery Network</keyword>
      <keyword>Caching</keyword>
      <abstract>
         <t>This specification defines a convention for HTTP response header fields that allow directives controlling caching to be targeted at specific caches or classes of caches. It also defines one such header field, targeted at Content Delivery Network (CDN) caches.</t>
      </abstract>
      <note title="Note to Readers">
         <t>
            <em>RFC EDITOR: please remove this section before publication</em>
         </t>
         <t>The issues list for this draft can be found at <eref target="https://github.com/httpwg/http-extensions/labels/targeted-cc">https://github.com/httpwg/http-extensions/labels/targeted-cc</eref>.</t>
         <t>The most recent (often, unpublished) draft is at <eref target="https://httpwg.org/http-extensions/draft-ietf-httpbis-targeted-cache-control.html">https://httpwg.org/http-extensions/draft-ietf-httpbis-targeted-cache-control.html</eref>.</t>
         <t>See also the draft's current status in the IETF datatracker, at <eref target="https://datatracker.ietf.org/doc/draft-ietf-httpbis-targeted-cache-control/">https://datatracker.ietf.org/doc/draft-ietf-httpbis-targeted-cache-control/</eref>.</t>
      </note>
   </front>
   <middle>
      <section anchor="introduction">
         <name>Introduction</name>
         <t>Modern deployments of HTTP often use multiple layers of caching with varying properties. For example, a Web site might use a cache on the origin server itself; it might deploy a caching layer in the same network as the origin server, it might use one or more Content Delivery Networks (CDNs) that are distributed throughout the Internet, and it might utilise browser caching as well.</t>
         <t>Because it is often desirable to control these different classes of caches separately, some means of targeting directives at them is necessary.</t>
         <t>The HTTP Cache-Control response header field is widely used to direct caching behavior. However, it is relatively undifferentiated; while some directives (e.g., s-maxage) are targeted at a specific class of caches (for s-maxage, shared caches), that is not consistently available across all existing cache directives (e.g., stale-while-revalidate). This is problematic, especially as the number of caching extensions grows, along with the number of potential targets.</t>
         <t>Some caches have defined ad hoc control mechanisms to overcome this issue, but interoperability is low. <xref target="targeted"/> defines a standard framework for targeted cache control using HTTP response headers, and <xref target="cdn-cache-control"/> defines one such header: the CDN-Cache-Control response header field.</t>
         <section anchor="notational-conventions">
            <name>Notational Conventions</name>
            <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" 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>
         </section>
      </section>
      <section anchor="targeted">
         <name>Targeted Cache-Control Header Fields</name>
         <t>A Targeted Cache-Control Header Field (hereafter, "targeted field") is a HTTP response header field that has the same syntax and semantics as the Cache-Control response header field <xref section="5.2" sectionFormat="comma" target="I-D.ietf-httpbis-cache"/>. However, it has a distinct field name that indicates the target for its directives.</t>
         <t>For example:</t>
         <figure>
            <sourcecode type="http-message">
CDN-Cache-Control: max-age=60
</sourcecode>
         </figure>
         <t>is a targeted field that applies to Content Delivery Networks (CDNs), as defined in <xref target="cdn-cache-control"/>.</t>
         <section anchor="cache-behavior">
            <name>Cache Behavior</name>
            <t>A cache that implement this specification has a <em>target list</em> - an ordered list of the targeted field names that it uses for caching policy, with the order reflecting priority from most applicable to least. The target list might be fixed, user-configurable, or generated per request, depending upon the implementation.</t>
            <t>For example, a CDN cache might support both CDN-Cache-Control and a header specific to that CDN, ExampleCDN-Cache-Control, with the latter overriding the former. Its target list would be:</t>
            <figure>
               <artwork>
  [ExampleCDN-Cache-Control, CDN-Cache-Control]
</artwork>
            </figure>
            <t>When a cache that implements this specification receives a response with one or more of of the header field names on its target list, the cache MUST select the first (in target list order) field with a valid, non-empty value and use that to determine the caching policy for the response, and MUST ignore the Cache-Control and Expires header fields in that response, unless no valid, non-empty value is available from the listed header fields.</t>
            <t>Note that this is on a response-by-response basis; if no applicable targeted field is present, valid and non-empty, a cache falls back to other cache control mechanisms as required by HTTP <xref target="I-D.ietf-httpbis-cache"/>.</t>
            <t>Targeted fields that are not on a cache's target list MUST NOT change that cache's behaviour, and MUST be passed through.</t>
            <t>Caches that use a targeted field MUST implement the semantics of the following cache directives:</t>
            <t>
               <list style="symbols">
                  <t>max-age</t>
                  <t>must-revalidate</t>
                  <t>no-store</t>
                  <t>no-cache</t>
                  <t>private</t>
               </list>
            </t>
            <t>Furthermore, they SHOULD implement other cache directives (including extension cache directives) that they support in the Cache-Control response header field.</t>
            <t>The semantics and precedence of cache directives in a targeted field are the same as those in Cache-Control. In particular, no-store and no-cache make max-age inoperative.</t>
         </section>
         <section anchor="parsing-targeted-fields">
            <name>Parsing Targeted Fields</name>
            <t>Targeted fields MAY be parsed as a Dictionary Structured Field <xref target="RFC8941"/>, and implementations are encouraged to use a parser for that format in the interests of robustness, interoperability and security.</t>
            <t>When an implementation parses a targeted field as a Structured Field, each cache directive will be assigned a value. For example, max-age has an integer value; no-store’s value is boolean true, and no-cache’s value can either be boolean true or a list of field names. Implementations SHOULD NOT accept other values (e.g. coerce a max-age with a decimal value into an integer). Likewise, implementations SHOULD ignore parameters on directives, unless otherwise specified.</t>
            <t>However, implementers MAY reuse a Cache-Control parser for simplicity. If they do so, they SHOULD observe the following points, to aid in a smooth transition to a full Structured Field parser and prevent interoperability issues:</t>
            <t>
               <list style="symbols">
                  <t>If a directive is repeated in the field value (e.g., "max-age=30, max-age=60"), the last value 'wins' (60, in this case)</t>
                  <t>Members of the directives can have parameters (e.g., "max-age=30;a=b;c=d"), which should be ignored unless specified.</t>
               </list>
            </t>
            <t>If a targeted field in a given response is empty, or a parsing error is encountered (when being parsed as a Structured Field), that field SHOULD be ignored by the cache (i.e., it should behave as if the field were not present, likely falling back to other cache control mechanisms present).</t>
         </section>
         <section anchor="defining-targeted-fields">
            <name>Defining Targeted Fields</name>
            <t>A targeted field for a particular class of cache can be defined by requesting registration in the Hypertext Transfer Protocol (HTTP) Field Name Registry <eref target="https://www.iana.org/assignments/http-fields/">https://www.iana.org/assignments/http-fields/</eref>, listing this specification as the specification document. The Comments field of the registration SHOULD clearly define the class of caches that the targeted field applies to.</t>
            <t>By convention, targeted fields SHOULD have the suffix "-Cache-Control": e.g., "ExampleCDN-Cache-Control". However, this suffix MUST NOT be used on its own to identify targeted fields; it is only a convention.</t>
         </section>
      </section>
      <section anchor="cdn-cache-control">
         <name>The CDN-Cache-Control Targeted Field</name>
         <t>The CDN-Cache-Control response header field is a targeted field <xref target="targeted"/> that allows origin servers to control the behaviour of CDN caches interposed between them and clients, separately from other caches that might handle the response.</t>
         <t>It applies to caches that are part of a distributed network that operate on behalf of an origin server (commonly called a Content Delivery Network or CDN).</t>
         <t>CDN caches that use CDN-Cache-Control MAY forward this header so that downstream CDN caches can use it as well. However, doing so exposes its value to all downstream clients, which might be undesirable. As a result, CDN caches that process this header field MAY remove it (for example, when configured to do so because it is known not to be used downstream).</t>
         <section anchor="examples">
            <name>Examples</name>
            <t>For example, the following header fields would instruct a CDN cache to consider the response fresh for 600 seconds, other shared caches for 120 seconds and any remaining caches for 60 seconds:</t>
            <figure>
               <sourcecode type="http-message">
Cache-Control: max-age=60, s-maxage=120
CDN-Cache-Control: max-age=600
</sourcecode>
            </figure>
            <t>These header fields would instruct a CDN cache to consider the response fresh for 600 seconds, while all other caches would be prevented from storing it:</t>
            <figure>
               <sourcecode type="http-message">
Cache-Control: no-store
CDN-Cache-Control: max-age=600
</sourcecode>
            </figure>
            <t>Because CDN-Cache-Control is not present, this header field would prevent all caches from storing the response:</t>
            <figure>
               <sourcecode type="http-message">
Cache-Control: no-store
</sourcecode>
            </figure>
            <t>Whereas these would prevent all caches except for CDN caches from storing the response:</t>
            <figure>
               <sourcecode type="http-message">
Cache-Control: no-store
CDN-Cache-Control: none
</sourcecode>
            </figure>
            <t>(note that 'none' is not a registered cache directive; it is here to avoid sending a header field with an empty value, because such a header might not be preserved in all cases)</t>
         </section>
      </section>
      <section anchor="iana-considerations">
         <name>IANA Considerations</name>
         <t>Please register the following entry in the Hypertext Transfer Protocol (HTTP) Field Name Registry defined by <xref target="I-D.ietf-httpbis-semantics"/>:</t>
         <t>
            <list style="symbols">
               <t>Field Name: CDN-Cache-Control</t>
               <t>Status: permanent</t>
               <t>Specification Document: [this document]</t>
               <t>Comments: Cache-Control directives targeted at Content Delivery Networks</t>
            </list>
         </t>
      </section>
      <section anchor="security-considerations">
         <name>Security Considerations</name>
         <t>The security considerations of HTTP caching <xref target="I-D.ietf-httpbis-cache"/> apply.</t>
         <t>The ability to carry multiple caching policies on a response can result in confusion about how a response will be cached in different systems, if not used carefully. This might result in unintentional reuse of responses with sensitive information.</t>
      </section>
   </middle>
   <back>
      <references title="Normative References">
         <reference anchor="RFC2119">
            <front>
               <title>Key words for use in RFCs to Indicate Requirement Levels</title>
               <author fullname="S. Bradner" initials="S." surname="Bradner"/>
               <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">
            <front>
               <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
               <author fullname="B. Leiba" initials="B." surname="Leiba"/>
               <date month="May" year="2017"/>
            </front>
            <seriesInfo name="BCP" value="14"/>
            <seriesInfo name="RFC" value="8174"/>
            <seriesInfo name="DOI" value="10.17487/RFC8174"/>
         </reference>
         <reference anchor="I-D.ietf-httpbis-cache">
            <front>
               <title>HTTP Caching</title>
               <author fullname="Roy T. Fielding">
                  <organization>Adobe</organization>
               </author>
               <author fullname="Mark Nottingham">
                  <organization>Fastly</organization>
               </author>
               <author fullname="Julian Reschke">
                  <organization>greenbytes GmbH</organization>
               </author>
               <date day="25" month="July" year="2021"/>
            </front>
            <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-cache-17"/>
         </reference>
         <reference anchor="RFC8941">
            <front>
               <title>Structured Field Values for HTTP</title>
               <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
               <author fullname="P-H. Kamp" initials="P-H." surname="Kamp"/>
               <date month="February" year="2021"/>
            </front>
            <seriesInfo name="RFC" value="8941"/>
            <seriesInfo name="DOI" value="10.17487/RFC8941"/>
         </reference>
         <reference anchor="I-D.ietf-httpbis-semantics">
            <front>
               <title>HTTP Semantics</title>
               <author fullname="Roy T. Fielding">
                  <organization>Adobe</organization>
               </author>
               <author fullname="Mark Nottingham">
                  <organization>Fastly</organization>
               </author>
               <author fullname="Julian Reschke">
                  <organization>greenbytes GmbH</organization>
               </author>
               <date day="25" month="July" year="2021"/>
            </front>
            <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-semantics-17"/>
         </reference>
      </references>
   </back>
</rfc>
