<?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.26 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-ietf-httpbis-no-vary-search-01" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.28.0 -->
  <front>
    <title>No-Vary-Search</title>
    <seriesInfo name="Internet-Draft" value="draft-ietf-httpbis-no-vary-search-01"/>
    <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="March" day="21"/>
    <area>Applications</area>
    <workgroup>HyperText Transfer Protocol</workgroup>
    <keyword>http</keyword>
    <keyword>caching</keyword>
    <abstract>
      <?line 106?>

<t>This specification defines a proposed HTTP 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>wrlA</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>wrlB</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>Servers <bcp14>SHOULD</bcp14> send no more than one distinct non-empty value for the <tt>No-Vary-Search</tt> field in response to requests for a given pathname.</t>
      <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. Such a cache might take steps like the following to identify a stored response (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>
        <t>Such implementations might "miss" some stored responses that could otherwise have been reused. It is therefore useful for servers to avoid sending different values for the <tt>No-Vary-Search</tt> field when possible.</t>
      </aside>
    </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>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
AAA=

-->

</rfc>
