<?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-02" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.30.1 -->
  <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-02"/>
    <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="17"/>
    <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"/>. 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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
8WEAAA==

-->

</rfc>
