<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.29 (Ruby 3.4.4) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-httpbis-no-vary-search-03" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.30.2 -->
  <front>
    <title abbrev="No-Vary-Search">The No-Vary-Search HTTP Response Header Field</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-no-vary-search-03"/>
    <author fullname="Domenic Denicola">
      <organization>Google LLC</organization>
      <address>
        <email>d@domenic.me</email>
      </address>
    </author>
    <author fullname="Jeremy Roman">
      <organization>Google LLC</organization>
      <address>
        <email>jbroman@chromium.org</email>
      </address>
    </author>
    <date year="2025" month="September" day="29"/>
    <area>Web and Internet Transport</area>
    <workgroup>HyperText Transfer Protocol</workgroup>
    <keyword>http</keyword>
    <keyword>caching</keyword>
    <abstract>
      <?line 106?>

<t>This specification defines a proposed HTTP response header field for changing how URL search parameters impact caching.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://httpwg.org/http-extensions/draft-ietf-httpbis-no-vary-search.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-ietf-httpbis-no-vary-search/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        HTTP Working Group mailing list (<eref target="mailto:ietf-http-wg@w3.org"/>),
        which is archived at <eref target="https://lists.w3.org/Archives/Public/ietf-http-wg/"/>.
        Working Group information can be found at <eref target="https://httpwg.org/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/httpwg/http-extensions/labels/no-vary-search"/>.</t>
    </note>
  </front>
  <middle>
    <?line 110?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>HTTP caching <xref target="HTTP-CACHING"/> is based on reusing resources which match across a number of cache keys. One of the most prominent is the presented target URI (<xref section="7.1" sectionFormat="of" target="HTTP"/>). However, sometimes multiple URLs can represent the same resource. This leads to caches not always being as helpful as they could be: if the cache contains the resource under one URI, but the resource is then requested under another, the cached version will be ignored.</t>
      <t>The <tt>No-Vary-Search</tt> HTTP header field tackles a specific subset of this general problem, for when a resource has multiple URLs which differ only in certain query components. It allows resources to declare that some or all parts of the query do not semantically affect the served resource, and thus can be ignored for cache matching purposes. For example, if the order of the query parameter keys do not semantically affect the served resource, this is indicated using</t>
      <sourcecode type="http-message"><![CDATA[
No-Vary-Search: key-order
]]></sourcecode>
      <t>If the specific query parameters (e.g., ones indicating something for analytics) do not semantically affect the served resource, this is indicated using</t>
      <sourcecode type="http-message"><![CDATA[
No-Vary-Search: params=("utm_source" "utm_medium" "utm_campaign")
]]></sourcecode>
      <t>And if the resource instead wants to take an allowlist-based approach, where only certain known query parameters semantically affect the served resource, they can use</t>
      <sourcecode type="http-message"><![CDATA[
No-Vary-Search: params, except=("productId")
]]></sourcecode>
      <t><xref target="header-definition"/> defines the header, using the <xref target="STRUCTURED-FIELDS"/> framework. <xref target="data-model"/> and <xref target="parsing"/> illustrate the data model for how the header can be represented in specifications, and the process for parsing the raw output from the structured field parser into that data model. <xref target="comparing"/> gives the key algorithm for comparing if two URLs are equivalent under the influence of the header; notably, it leans on the decomposition of the query component into keys and values given by the <eref target="https://url.spec.whatwg.org/#concept-urlencoded">application/x-www-form-urlencoded</eref> format specified in <xref target="WHATWG-URL"/>. (As such, this header is not useful for URLs whose query component does not follow that format.) Finally, <xref target="caching"/> explains how to modify <xref target="HTTP-CACHING"/> to take into account this new equivalence.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<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>
      <?line -18?>

<t>This document also adopts some conventions and notation typical in WHATWG and W3C usage, especially as it relates to algorithms. See <xref target="WHATWG-INFRA"/>, and in particular:</t>
      <ul spacing="normal">
        <li>
          <t>its definition of lists, including the list literal notation « 1, 2, 3 ».</t>
        </li>
        <li>
          <t>its definition of strings, including their representation as code units.</t>
        </li>
      </ul>
      <t>(Other concepts used are called out using inline references.)</t>
    </section>
    <section anchor="header-definition">
      <name>HTTP header field definition</name>
      <t>The <tt>No-Vary-Search</tt> HTTP header field is a structured field <xref target="STRUCTURED-FIELDS"/> whose value <bcp14>MUST</bcp14> be a dictionary (<xref section="3.2" sectionFormat="of" target="STRUCTURED-FIELDS"/>).</t>
      <t>It has the following authoring conformance requirements:</t>
      <ul spacing="normal">
        <li>
          <t>If present, the <tt>key-order</tt> entry's value <bcp14>MUST</bcp14> be a boolean (<xref section="3.3.6" sectionFormat="of" target="STRUCTURED-FIELDS"/>).</t>
        </li>
        <li>
          <t>If present, the <tt>params</tt> entry's value <bcp14>MUST</bcp14> be either a boolean (<xref section="3.3.6" sectionFormat="of" target="STRUCTURED-FIELDS"/>) or an inner list (<xref section="3.1.1" sectionFormat="of" target="STRUCTURED-FIELDS"/>).</t>
        </li>
        <li>
          <t>If present, the <tt>except</tt> entry's value <bcp14>MUST</bcp14> be an inner list (<xref section="3.1.1" sectionFormat="of" target="STRUCTURED-FIELDS"/>).</t>
        </li>
        <li>
          <t>The <tt>except</tt> entry <bcp14>MUST</bcp14> only be present if the <tt>params</tt> entry is also present, and the <tt>params</tt> entry's value is the boolean value true.</t>
        </li>
      </ul>
      <t>The dictionary <bcp14>MAY</bcp14> contain entries whose keys are not one of <tt>key-order</tt>, <tt>params</tt>, and <tt>except</tt>, but their meaning is not defined by this specification. Implementations of this specification will ignore such entries (but future documents might assign meaning to such entries).</t>
      <aside>
        <t>As always, the authoring conformance requirements are not binding on implementations. Implementations instead need to implement the processing model given by the <iref item="obtain a URL search variance"/><xref target="obtain-a-url-search-variance" format="none">obtain a URL search variance</xref> algorithm (<xref target="obtain-a-url-search-variance"/>).</t>
      </aside>
    </section>
    <section anchor="data-model">
      <name>Data model</name>
      <t>A <em>URL search variance</em> consists of the following:</t>
      <dl newline="true">
        <dt>no-vary params</dt>
        <dd>
          <t>either the special value <strong>wildcard</strong> or a list of strings</t>
        </dd>
        <dt>vary params</dt>
        <dd>
          <t>either the special value <strong>wildcard</strong> or a list of strings</t>
        </dd>
        <dt>vary on key order</dt>
        <dd>
          <t>a boolean</t>
        </dd>
      </dl>
      <t><iref item="default URL search variance" primary="true"/>
The <em><iref item="default URL search variance"/>default URL search variance</em> is a URL search variance whose no-vary params is an empty list, vary params is <strong>wildcard</strong>, and vary on key order is true.</t>
      <t>The <iref item="obtain a URL search variance"/><xref target="obtain-a-url-search-variance" format="none">obtain a URL search variance</xref> algorithm (<xref target="obtain-a-url-search-variance"/>) ensures that all URL search variances obey the following constraints:</t>
      <ul spacing="normal">
        <li>
          <t>vary params is a list if and only if the no-vary params is <strong>wildcard</strong>; and</t>
        </li>
        <li>
          <t>no-vary params is a list if and only if the vary params is <strong>wildcard</strong>.</t>
        </li>
      </ul>
    </section>
    <section anchor="parsing">
      <name>Parsing</name>
      <section anchor="parse-a-url-search-variance">
        <name>Parse a URL search variance</name>
        <t><iref item="parse a URL search variance" primary="true"/>
To <em><iref item="parse a URL search variance"/><xref target="parse-a-url-search-variance" format="none">parse a URL search variance</xref></em> given <em>value</em>:</t>
        <ol spacing="normal" type="1"><li>
            <t>If <em>value</em> is null, then return the <iref item="default URL search variance"/>default URL search variance.</t>
          </li>
          <li>
            <t>Let <em>result</em> be a new URL search variance.</t>
          </li>
          <li>
            <t>Set <em>result</em>'s vary on key order to true.</t>
          </li>
          <li>
            <t>If <em>value</em>["<tt>key-order</tt>"] exists:
            </t>
            <ol spacing="normal" type="1"><li>
                <t>If <em>value</em>["<tt>key-order</tt>"] is not a boolean, then return the <iref item="default URL search variance"/>default URL search variance.</t>
              </li>
              <li>
                <t>Set <em>result</em>'s vary on key order to the boolean negation of <em>value</em>["<tt>key-order</tt>"].</t>
              </li>
            </ol>
          </li>
          <li>
            <t>If <em>value</em>["<tt>params</tt>"] exists:
            </t>
            <ol spacing="normal" type="1"><li>
                <t>If <em>value</em>["<tt>params</tt>"] is a boolean:
                </t>
                <ol spacing="normal" type="1"><li>
                    <t>If <em>value</em>["<tt>params</tt>"] is true, then:
                    </t>
                    <ol spacing="normal" type="1"><li>
                        <t>Set <em>result</em>'s no-vary params to <strong>wildcard</strong>.</t>
                      </li>
                      <li>
                        <t>Set <em>result</em>'s vary params to the empty list.</t>
                      </li>
                    </ol>
                  </li>
                  <li>
                    <t>Otherwise:
                    </t>
                    <ol spacing="normal" type="1"><li>
                        <t>Set <em>result</em>'s no-vary params to the empty list.</t>
                      </li>
                      <li>
                        <t>Set <em>result</em>'s vary params to <strong>wildcard</strong>.</t>
                      </li>
                    </ol>
                  </li>
                </ol>
              </li>
              <li>
                <t>Otherwise, if <em>value</em>["<tt>params</tt>"] is an array:
                </t>
                <ol spacing="normal" type="1"><li>
                    <t>If any item in <em>value</em>["<tt>params</tt>"] is not a string, then return the <iref item="default URL search variance"/>default URL search variance.</t>
                  </li>
                  <li>
                    <t>Set <em>result</em>'s no-vary params to the result of applying <iref item="parse a key"/><xref target="parse-a-key" format="none">parse a key</xref> (<xref target="parse-a-key"/>) to each item in <em>value</em>["<tt>params</tt>"].</t>
                  </li>
                  <li>
                    <t>Set <em>result</em>'s vary params to <strong>wildcard</strong>.</t>
                  </li>
                </ol>
              </li>
              <li>
                <t>Otherwise, return the <iref item="default URL search variance"/>default URL search variance.</t>
              </li>
            </ol>
          </li>
          <li>
            <t>If <em>value</em>["<tt>except</tt>"] exists:
            </t>
            <ol spacing="normal" type="1"><li>
                <t>If <em>value</em>["<tt>params</tt>"] is not true, then return the <iref item="default URL search variance"/>default URL search variance.</t>
              </li>
              <li>
                <t>If <em>value</em>["<tt>except</tt>"] is not an array, then return the <iref item="default URL search variance"/>default URL search variance.</t>
              </li>
              <li>
                <t>If any item in <em>value</em>["<tt>except</tt>"] is not a string, then return the <iref item="default URL search variance"/>default URL search variance.</t>
              </li>
              <li>
                <t>Set <em>result</em>'s vary params to the result of applying <iref item="parse a key"/><xref target="parse-a-key" format="none">parse a key</xref> (<xref target="parse-a-key"/>) to each item in <em>value</em>["<tt>except</tt>"].</t>
              </li>
            </ol>
          </li>
          <li>
            <t>Return <em>result</em>.</t>
          </li>
        </ol>
        <aside>
          <t>In general, this algorithm is strict and tends to return the <iref item="default URL search variance"/>default URL search variance whenever it sees something it doesn't recognize. This is because the <iref item="default URL search variance"/>default URL search variance behavior will just cause fewer cache hits, which is an acceptable fallback behavior.</t>
          <t>However, unrecognized keys at the top level are ignored, to make it easier to extend this specification in the future. To avoid misbehavior with existing client software, such extensions will likely expand, rather than reduce, the set of requests that a cached response can match.</t>
        </aside>
        <aside>
          <t>The input to this algorithm is generally obtained by parsing a structured field (<xref section="4.2" sectionFormat="of" target="STRUCTURED-FIELDS"/>) using field_type "dictionary".</t>
        </aside>
      </section>
      <section anchor="obtain-a-url-search-variance">
        <name>Obtain a URL search variance</name>
        <t><iref item="obtain a URL search variance" primary="true"/>
To <em><iref item="obtain a URL search variance"/><xref target="obtain-a-url-search-variance" format="none">obtain a URL search variance</xref></em> given a <eref target="https://fetch.spec.whatwg.org/#concept-response">response</eref> <em>response</em>:</t>
        <ol spacing="normal" type="1"><li>
            <t>Let <em>fieldValue</em> be the result of <eref target="https://fetch.spec.whatwg.org/#concept-header-list-get-structured-header">getting a structured field value</eref> <xref target="FETCH"/> given `<tt>No-Vary-Search</tt>` and "<tt>dictionary</tt>" from <em>response</em>'s header list.</t>
          </li>
          <li>
            <t>Return the result of parsing a URL search variance (<xref target="parse-a-url-search-variance"/>) given <em>fieldValue</em>. <iref item="parse a URL search variance"/></t>
          </li>
        </ol>
        <section anchor="examples">
          <name>Examples</name>
          <t>The following illustrates how various inputs are parsed, in terms of their impacting on the resulting no-vary params and vary params:</t>
          <table>
            <thead>
              <tr>
                <th align="left">Input</th>
                <th align="left">Result</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params</tt></td>
                <td align="left">no-vary params: <strong>wildcard</strong><br/>vary params: (empty list)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params=("a")</tt></td>
                <td align="left">no-vary params: « "<tt>a</tt>" »<br/>vary params: <strong>wildcard</strong></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params, except=("x")</tt></td>
                <td align="left">no-vary params: <strong>wildcard</strong><br/>vary params: « "<tt>x</tt>" »</td>
              </tr>
            </tbody>
          </table>
          <t>The following inputs are all invalid and will cause the <iref item="default URL search variance"/>default URL search variance to be returned:</t>
          <ul spacing="compact">
            <li>
              <t><tt>No-Vary-Search: unknown-key</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: key-order="not a boolean"</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params="not a boolean or inner list"</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params=(not-a-string)</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params=("a"), except=("x")</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params=(), except=()</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params=?0, except=("x")</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params, except=(not-a-string)</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params, except="not an inner list"</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: params, except=?1</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: except=("x")</tt></t>
            </li>
            <li>
              <t><tt>No-Vary-Search: except=()</tt></t>
            </li>
          </ul>
          <t>The following inputs are valid, but somewhat unconventional. They are shown alongside their more conventional form.</t>
          <table>
            <thead>
              <tr>
                <th align="left">Input</th>
                <th align="left">Conventional form</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params=?1</tt></td>
                <td align="left">
                  <tt>No-Vary-Search: params</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: key-order=?1</tt></td>
                <td align="left">
                  <tt>No-Vary-Search: key-order</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params, key-order, except=("x")</tt></td>
                <td align="left">
                  <tt>No-Vary-Search: key-order, params, except=("x")</tt></td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params=?0</tt></td>
                <td align="left">(omit the header)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: params=()</tt></td>
                <td align="left">(omit the header)</td>
              </tr>
              <tr>
                <td align="left">
                  <tt>No-Vary-Search: key-order=?0</tt></td>
                <td align="left">(omit the header)</td>
              </tr>
            </tbody>
          </table>
        </section>
      </section>
      <section anchor="parse-a-key">
        <name>Parse a key</name>
        <t><iref item="parse a key" primary="true"/>
To <em><iref item="parse a key"/><xref target="parse-a-key" format="none">parse a key</xref></em> given an ASCII string <em>keyString</em>:</t>
        <ol spacing="normal" type="1"><li>
            <t>Let <em>keyBytes</em> be the <eref target="https://infra.spec.whatwg.org/#isomorphic-encode">isomorphic encoding</eref> <xref target="WHATWG-INFRA"/> of <em>keyString</em>.</t>
          </li>
          <li>
            <t>Replace any 0x2B (+) in <em>keyBytes</em> with 0x20 (SP).</t>
          </li>
          <li>
            <t>Let <em>keyBytesDecoded</em> be the <eref target="https://url.spec.whatwg.org/#percent-decode">percent-decoding</eref> <xref target="WHATWG-URL"/> of <em>keyBytes</em>.</t>
          </li>
          <li>
            <t>Let <em>keyStringDecoded</em> be the <eref target="https://encoding.spec.whatwg.org/#utf-8-decode-without-bom">UTF-8 decoding without BOM</eref> <xref target="WHATWG-ENCODING"/> of <em>keyBytesDecoded</em>.</t>
          </li>
          <li>
            <t>Return <em>keyStringDecoded</em>.</t>
          </li>
        </ol>
        <section anchor="examples-1">
          <name>Examples</name>
          <t>The <iref item="parse a key"/><xref target="parse-a-key" format="none">parse a key</xref> algorithm allows encoding non-ASCII key strings in the ASCII structured header format, similar to how the <eref target="https://url.spec.whatwg.org/#concept-urlencoded">application/x-www-form-urlencoded</eref> format <xref target="WHATWG-URL"/> allows encoding an entire entry list of keys and values in ASCII URL format. For example,</t>
          <sourcecode type="http-message"><![CDATA[
No-Vary-Search: params=("%C3%A9+%E6%B0%97")
]]></sourcecode>
          <t>will result in a URL search variance whose vary params are « "<tt>é 気</tt>" ». As explained in a later example, the canonicalization process during equivalence testing means this will treat as equivalent URL strings such as:</t>
          <!-- link "a later example" and "equivalence testing" -->

<ul spacing="normal">
            <li>
              <t><tt>https://example.com/?é 気=1</tt></t>
            </li>
            <li>
              <t><tt>https://example.com/?é+気=2</tt></t>
            </li>
            <li>
              <t><tt>https://example.com/?%C3%A9%20気=3</tt></t>
            </li>
            <li>
              <t><tt>https://example.com/?%C3%A9+%E6%B0%97=4</tt></t>
            </li>
          </ul>
          <t>and so on, since they all are <eref target="https://url.spec.whatwg.org/#concept-urlencoded-parser">parsed</eref> <xref target="WHATWG-URL"/> to having the same key "<tt>é 気</tt>".</t>
        </section>
      </section>
    </section>
    <section anchor="comparing">
      <name>Comparing</name>
      <t><iref item="equivalent modulo search variance" primary="true"/>
Two <eref target="https://url.spec.whatwg.org/#concept-url">URLs</eref> <xref target="WHATWG-URL"/> <em>urlA</em> and <em>urlB</em> are <em>equivalent modulo search variance</em> given a URL search variance <em>searchVariance</em> if the following algorithm returns true:</t>
      <ol spacing="normal" type="1"><li>
          <t>If the scheme, username, password, host, port, or path of <em>urlA</em> and <em>urlB</em> differ, then return false.</t>
        </li>
        <li>
          <t>If <em>searchVariance</em> is equivalent to the <iref item="default URL search variance"/>default URL search variance, then:  </t>
          <ol spacing="normal" type="1"><li>
              <t>If <em>urlA</em>'s query equals <em>urlB</em>'s query, then return true.</t>
            </li>
            <li>
              <t>Return false.</t>
            </li>
          </ol>
          <t>
In this case, even URL pairs that might appear the same after running the <eref target="https://url.spec.whatwg.org/#concept-urlencoded-parser">application/x-www-form-urlencoded parser</eref> <xref target="WHATWG-URL"/> on their queries, such as <tt>https://example.com/a</tt> and <tt>https://example.com/a?</tt>, or <tt>https://example.com/foo?a=b&amp;&amp;&amp;c</tt> and <tt>https://example.com/foo?a=b&amp;c=</tt>, will be treated as inequivalent.</t>
        </li>
        <li>
          <t>Let <em>searchParamsA</em> and <em>searchParamsB</em> be empty lists.</t>
        </li>
        <li>
          <t>If <em>urlA</em>'s query is not null, then set <em>searchParamsA</em> to the result of running the <eref target="https://url.spec.whatwg.org/#concept-urlencoded-parser">application/x-www-form-urlencoded parser</eref> <xref target="WHATWG-URL"/> given the <eref target="https://infra.spec.whatwg.org/#isomorphic-encode">isomorphic encoding</eref> <xref target="WHATWG-INFRA"/> of <em>urlA</em>'s query.</t>
        </li>
        <li>
          <t>If <em>urlB</em>'s query is not null, then set <em>searchParamsB</em> to the result of running the <eref target="https://url.spec.whatwg.org/#concept-urlencoded-parser">application/x-www-form-urlencoded parser</eref> <xref target="WHATWG-URL"/> given the <eref target="https://infra.spec.whatwg.org/#isomorphic-encode">isomorphic encoding</eref> <xref target="WHATWG-INFRA"/> of <em>urlB</em>'s query.</t>
        </li>
        <li>
          <t>If <em>searchVariance</em>'s no-vary params is a list, then:  </t>
          <ol spacing="normal" type="1"><li>
              <t>Set <em>searchParamsA</em> to a list containing those items <em>pair</em> in <em>searchParamsA</em> where <em>searchVariance</em>'s no-vary params does not contain <em>pair</em>[0].</t>
            </li>
            <li>
              <t>Set <em>searchParamsB</em> to a list containing those items <em>pair</em> in <em>searchParamsB</em> where <em>searchVariance</em>'s no-vary params does not contain <em>pair</em>[0].</t>
            </li>
          </ol>
        </li>
        <li>
          <t>Otherwise, if <em>searchVariance</em>'s vary params is a list, then:  </t>
          <ol spacing="normal" type="1"><li>
              <t>Set <em>searchParamsA</em> to a list containing those items <em>pair</em> in <em>searchParamsA</em> where <em>searchVariance</em>'s vary params contains <em>pair</em>[0].</t>
            </li>
            <li>
              <t>Set <em>searchParamsB</em> to a list containing those items <em>pair</em> in <em>searchParamsB</em> where <em>searchVariance</em>'s vary params contains <em>pair</em>[0].</t>
            </li>
          </ol>
        </li>
        <li>
          <t>If <em>searchVariance</em>'s vary on key order is false, then:  </t>
          <ol spacing="normal" type="1"><li>
              <t>Let <em>keyLessThan</em> be an algorithm taking as inputs two pairs (<em>keyA</em>, <em>valueA</em>) and (<em>keyB</em>, <em>valueB</em>), which returns whether <em>keyA</em> is <eref target="https://infra.spec.whatwg.org/#code-unit-less-than">code unit less than</eref> <xref target="WHATWG-INFRA"/> <em>keyB</em>.</t>
            </li>
            <li>
              <t>Set <em>searchParamsA</em> to the result of sorting <em>searchParamsA</em> in ascending order with <em>keyLessThan</em>.</t>
            </li>
            <li>
              <t>Set <em>searchParamsB</em> to the result of sorting <em>searchParamsB</em> in ascending order with <em>keyLessThan</em>.</t>
            </li>
          </ol>
        </li>
        <li>
          <t>If <em>searchParamsA</em>'s size is not equal to <em>searchParamsB</em>'s size, then return false.</t>
        </li>
        <li>
          <t>Let <em>i</em> be 0.</t>
        </li>
        <li>
          <t>While <em>i</em> &lt; <em>searchParamsA</em>'s size:  </t>
          <ol spacing="normal" type="1"><li>
              <t>If <em>searchParamsA</em>[<em>i</em>][0] does not equal <em>searchParamsB</em>[<em>i</em>][0], then return false.</t>
            </li>
            <li>
              <t>If <em>searchParamsA</em>[<em>i</em>][1] does not equal <em>searchParamsB</em>[<em>i</em>][1], then return false.</t>
            </li>
            <li>
              <t>Set <em>i</em> to <em>i</em> + 1.</t>
            </li>
          </ol>
        </li>
        <li>
          <t>Return true.</t>
        </li>
      </ol>
      <section anchor="examples-2">
        <name>Examples</name>
        <t>Due to how the application/x-www-form-urlencoded parser canonicalizes query strings, there are some cases where query strings which do not appear obviously equivalent, will end up being treated as equivalent after parsing.</t>
        <t>So, for example, given any non-default value for <tt>No-Vary-Search</tt>, such as <tt>No-Vary-Search: key-order</tt>, we will have the following equivalences:</t>
        <dl newline="true">
          <dt>
        <tt>https://example.com</tt>
            <br/>
            <tt>https://example.com/?</tt>
          </dt>
          <dd>A null query is parsed the same as an empty string</dd>
          <dt>
        <tt>https://example.com/?a=x</tt>
            <br/>
            <tt>https://example.com/?%61=%78</tt>
          </dt>
          <dd>Parsing performs percent-decoding</dd>
          <dt>
        <tt>https://example.com/?a=é</tt>
            <br/>
            <tt>https://example.com/?a=%C3%A9</tt>
          </dt>
          <dd>Parsing performs percent-decoding</dd>
          <dt>
        <tt>https://example.com/?a=%f6</tt>
            <br/>
            <tt>https://example.com/?a=%ef%bf%bd</tt>
          </dt>
          <dd>Both values are parsed as U+FFFD (�)</dd>
          <dt>
        <tt>https://example.com/?a=x&amp;&amp;&amp;&amp;</tt>
            <br/>
            <tt>https://example.com/?a=x</tt>
          </dt>
          <dd>Parsing splits on     <tt>&amp;</tt>
 and discards empty strings</dd>
          <dt>
        <tt>https://example.com/?a=</tt>
            <br/>
            <tt>https://example.com/?a</tt>
          </dt>
          <dd>Both parse as having an empty string value for     <tt>a</tt>
          </dd>
          <dt>
        <tt>https://example.com/?a=%20</tt>
            <br/>
            <tt>https://example.com/?a=+</tt>
            <br/>
            <tt>https://example.com/?a= &amp;</tt>
          </dt>
          <dd>
            <tt>+</tt>
 and     <tt>%20</tt>
 are both parsed as U+0020 SPACE</dd>
        </dl>
      </section>
    </section>
    <section anchor="caching">
      <name>Caching</name>
      <t>If a cache <xref target="HTTP-CACHING"/> implements this specification, the presented target URI requirement in <xref section="4" sectionFormat="of" target="HTTP-CACHING"/> is replaced with:</t>
      <ul spacing="normal">
        <li>
          <t>one of the following:
          </t>
          <ul spacing="normal">
            <li>
              <t>the presented target URI (<xref section="7.1" sectionFormat="of" target="HTTP"/>) and that of the stored response match, or</t>
            </li>
            <li>
              <t>the presented target URI and that of the stored response are equivalent modulo search variance (<xref target="comparing"/>), given the variance obtained (<xref target="obtain-a-url-search-variance"/>) from the stored response.</t>
            </li>
          </ul>
        </li>
      </ul>
      <t>Cache implementations <bcp14>MAY</bcp14> fail to reuse a stored response whose target URI matches <em>only</em> modulo URL search variance, if the cache has more recently stored a response which:</t>
      <ul spacing="normal">
        <li>
          <t>has a target URI which is equal to the presented target URI, excluding the query, and</t>
        </li>
        <li>
          <t>has a non-empty value for the <tt>No-Vary-Search</tt> field, and</t>
        </li>
        <li>
          <t>has a <tt>No-Vary-Search</tt> field value different from the stored response being considered for reuse.</t>
        </li>
      </ul>
      <aside>
        <t>Caches aren't required to reuse stored responses, generally. However, the above expressly empowers caches to, if it is advantageous for performance or other reasons, search a smaller number of stored responses.</t>
        <t>That is, because caches might store more than one response for a given pathname, they need a way to efficiently look up the No-Vary-Search value without accessing all cached responses. Such a cache might take steps like the following to identify a stored response in a performant way, before checking the other conditions in <xref section="4" sectionFormat="of" target="HTTP-CACHING"/>:</t>
        <ol spacing="normal" type="1"><li>
            <t>Let exactMatch be cache[presentedTargetURI]. If it is a stored response that can be reused, return it.</t>
          </li>
          <li>
            <t>Let targetPath be presentedTargetURI, with query parameters removed.</t>
          </li>
          <li>
            <t>Let lastNVS be mostRecentNVS[targetPath]. If it does not exist, return null.</t>
          </li>
          <li>
            <t>Let simplifiedURL be the result of simplifying presentedTargetURI according to lastNVS (by removing query parameters which are not significant, and stable sorting parameters by key, if key order is to be be ignored).</t>
          </li>
          <li>
            <t>Let nvsMatch be cache[simplifiedURL]. If it does not exist, return null. (It is assumed that this was written when storing in the cache, in addition to the exact URL.)</t>
          </li>
          <li>
            <t>Let searchVariance be obtained (<xref target="obtain-a-url-search-variance"/>) from nvsMatch.</t>
          </li>
          <li>
            <t>If nvsMatch's target URI and presentedTargetURI are not equivalent modulo search variance (<xref target="comparing"/>) given searchVariance, then return null.</t>
          </li>
          <li>
            <t>If nvsMatch is a stored response that can be reused, return it. Otherwise, return null.</t>
          </li>
        </ol>
      </aside>
      <t>To aid cache implementation efficiency, servers <bcp14>SHOULD NOT</bcp14> send different non-empty values for the <tt>No-Vary-Search</tt> field in response to requests for a given pathname over time, unless there is a need to update how they handle the query component. Doing so would cause cache implementations that use a strategy like the above to miss some stored responses that could otherwise have been reused.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The main risk to be aware of is the impact of mismatched URLs. In particular, this could cause the user to see a response that was originally fetched from a URL different from the one displayed when they hovered a link, or the URL displayed in the URL bar.</t>
      <t>However, since the impact is limited to query parameters, this does not cross the relevant security boundary, which is the <eref target="https://html.spec.whatwg.org/multipage/browsers.html#concept-origin">origin</eref> <xref target="HTML"/>. (Or perhaps just the <eref target="https://url.spec.whatwg.org/#concept-url-host">host</eref>, from <eref target="https://url.spec.whatwg.org/#url-rendering-simplification">the perspective of web browser security UI</eref>. <xref target="WHATWG-URL"/>) Indeed, we have already given origins complete control over how they present the (URL, reponse body) pair, including on the client side via technology such as <eref target="https://html.spec.whatwg.org/multipage/nav-history-apis.html#dom-history-replacestate">history.replaceState()</eref> or service workers.</t>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy Considerations</name>
      <t>This proposal is adjacent to the highly-privacy-relevant space of <eref target="https://privacycg.github.io/nav-tracking-mitigations/#terminology">navigational tracking</eref>, which often uses query parameters to pass along user identifiers. However, we believe this proposal itself does not have privacy impacts. It does not interfere with <eref target="https://privacycg.github.io/nav-tracking-mitigations/#deployed-mitigations">existing navigational tracking mitigations</eref>, or any known future ones being contemplated. Indeed, if a page were to encode user identifiers in its URL, the only ability this proposal gives is to <em>reduce</em> such user tracking by preventing server processing of such user IDs (since the server is bypassed in favor of the cache). <xref target="NAV-TRACKING-MITIGATIONS"/></t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>IANA should do the following:</t>
      <section anchor="http-field-names">
        <name>HTTP Field Names</name>
        <t>Enter the following into the Hypertext Transfer Protocol (HTTP) Field Name Registry:</t>
        <dl>
          <dt>Field Name</dt>
          <dd>
            <t><tt>No-Vary-Search</tt></t>
          </dd>
          <dt>Status</dt>
          <dd>
            <t>permanent</t>
          </dd>
          <dt>Structured Type</dt>
          <dd>
            <t>Dictionary</t>
          </dd>
          <dt>Reference</dt>
          <dd>
            <t>this document</t>
          </dd>
          <dt>Comments</dt>
          <dd>
            <t>(none)</t>
          </dd>
        </dl>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="HTTP">
          <front>
            <title>HTTP Semantics</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document describes the overall architecture of HTTP, establishes common terminology, and defines aspects of the protocol that are shared by all versions. In this definition are core protocol elements, extensibility mechanisms, and the "http" and "https" Uniform Resource Identifier (URI) schemes.</t>
              <t>This document updates RFC 3864 and obsoletes RFCs 2818, 7231, 7232, 7233, 7235, 7538, 7615, 7694, and portions of 7230.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="97"/>
          <seriesInfo name="RFC" value="9110"/>
          <seriesInfo name="DOI" value="10.17487/RFC9110"/>
        </reference>
        <reference anchor="HTTP-CACHING">
          <front>
            <title>HTTP Caching</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="M. Nottingham" initials="M." role="editor" surname="Nottingham"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2022"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document defines HTTP caches and the associated header fields that control cache behavior or indicate cacheable response messages.</t>
              <t>This document obsoletes RFC 7234.</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="98"/>
          <seriesInfo name="RFC" value="9111"/>
          <seriesInfo name="DOI" value="10.17487/RFC9111"/>
        </reference>
        <reference anchor="FETCH" target="https://fetch.spec.whatwg.org/">
          <front>
            <title>Fetch Living Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>Apple Inc.</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>WHATWG</annotation>
        </reference>
        <reference anchor="STRUCTURED-FIELDS">
          <front>
            <title>Structured Field Values for HTTP</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <author fullname="P-H. Kamp" surname="P-H. Kamp"/>
            <date month="February" year="2021"/>
            <abstract>
              <t>This document describes a set of data types and associated algorithms that are intended to make it easier and safer to define and handle HTTP header and trailer fields, known as "Structured Fields", "Structured Headers", or "Structured Trailers". It is intended for use by specifications of new HTTP fields that wish to use a common syntax that is more restrictive than traditional HTTP field values.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8941"/>
          <seriesInfo name="DOI" value="10.17487/RFC8941"/>
        </reference>
        <reference anchor="WHATWG-ENCODING" target="https://encoding.spec.whatwg.org/">
          <front>
            <title>Encoding Living Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>Apple Inc.</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>WHATWG</annotation>
        </reference>
        <reference anchor="WHATWG-INFRA" target="https://infra.spec.whatwg.org/">
          <front>
            <title>Infra Living Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>Apple Inc.</organization>
            </author>
            <author initials="D." surname="Denicola" fullname="Domenic Denicola">
              <organization>Google LLC</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>WHATWG</annotation>
        </reference>
        <reference anchor="WHATWG-URL" target="https://url.spec.whatwg.org/">
          <front>
            <title>URL Living Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>Apple Inc.</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>WHATWG</annotation>
        </reference>
        <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"/>
            <abstract>
              <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
            </abstract>
          </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"/>
            <abstract>
              <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
            </abstract>
          </front>
          <seriesInfo name="BCP" value="14"/>
          <seriesInfo name="RFC" value="8174"/>
          <seriesInfo name="DOI" value="10.17487/RFC8174"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="HTML" target="https://html.spec.whatwg.org/">
          <front>
            <title>HTML Living Standard</title>
            <author initials="A." surname="van Kesteren" fullname="Anne van Kesteren">
              <organization>Apple Inc.</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>WHATWG</annotation>
        </reference>
        <reference anchor="NAV-TRACKING-MITIGATIONS" target="https://privacycg.github.io/nav-tracking-mitigations/">
          <front>
            <title>Navigational-Tracking Mitigations</title>
            <author initials="P." surname="Snyder" fullname="Pete Snyder">
              <organization>Brave Software, Inc.</organization>
            </author>
            <author initials="J." surname="Yasskin" fullname="Jeffrey Yasskin">
              <organization>Google LLC</organization>
            </author>
            <date>n.d.</date>
          </front>
          <annotation>W3C Privacy CG</annotation>
        </reference>
      </references>
    </references>
    <?line 501?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>This document benefited from valuable reviews and suggestions by:</t>
      <ul spacing="normal">
        <li>
          <t>Adam Rice</t>
        </li>
        <li>
          <t>Julian Reschke</t>
        </li>
        <li>
          <t>Kevin McNee</t>
        </li>
        <li>
          <t>Liviu Tinta</t>
        </li>
        <li>
          <t>Mark Nottingham</t>
        </li>
        <li>
          <t>Martin Thomson</t>
        </li>
        <li>
          <t>Valentin Gosu</t>
        </li>
      </ul>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
