<?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.6.39 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-meenan-httpbis-compression-dictionary-05" category="info" submissionType="independent" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.5 -->
  <front>
    <title abbrev="compression-dictionary">Compression Dictionary Transport</title>
    <seriesInfo name="Internet-Draft" value="draft-meenan-httpbis-compression-dictionary-05"/>
    <author initials="P." surname="Meenan" fullname="Patrick Meenan">
      <organization>Google LLC</organization>
      <address>
        <email>pmeenan@google.com</email>
      </address>
    </author>
    <author initials="Y." surname="Weiss" fullname="Yoav Weiss">
      <organization>Google LLC</organization>
      <address>
        <email>yoavweiss@google.com</email>
      </address>
    </author>
    <date year="2023" month="August" day="09"/>
    <area>Applications and Real-Time</area>
    <workgroup>HTTP</workgroup>
    <keyword>compression dictionary</keyword>
    <keyword>shared brotli</keyword>
    <keyword>zstandard dictionary</keyword>
    <abstract>
      <?line 52?>

<t>This specification defines a mechanism for using designated <xref target="HTTP"/> responses
as an external dictionary for future HTTP responses for compression schemes
that support using external dictionaries (e.g. Brotli <xref target="RFC7932"/> and Zstandard
<xref target="RFC8878"/>).</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://pmeenan.github.io/i-d-compression-dictionary/draft-meenan-httpbis-compression-dictionary.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-meenan-httpbis-compression-dictionary/"/>.
      </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/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/pmeenan/i-d-compression-dictionary"/>.</t>
    </note>
  </front>
  <middle>
    <?line 59?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>This specification defines a mechanism for using designated <xref target="HTTP"/> responses
as an external dictionary for future HTTP responses for compression schemes
that support using external dictionaries (e.g. Brotli <xref target="RFC7932"/> and Zstandard
<xref target="RFC8878"/>).</t>
      <t>This document describes the HTTP headers used for negotiating dictionary usage
and registers media types for content encoding Brotli and Zstandard using a
negotiated dictionary.</t>
      <t>This document uses the line folding strategies described in <xref target="FOLDING"/>.</t>
    </section>
    <section anchor="dictionary-negotiation">
      <name>Dictionary Negotiation</name>
      <section anchor="use-as-dictionary">
        <name>Use-As-Dictionary</name>
        <t>When responding to a HTTP Request, a server can advertise that the response can
be used as a dictionary for future requests for URLs that match the pattern
specified in the Use-As-Dictionary response header.</t>
        <t>The Use-As-Dictionary response header is a Structured Field <xref target="RFC8941"/>
sf-dictionary with values for "match", "ttl", "type" and "hashes".</t>
        <section anchor="match">
          <name>match</name>
          <t>The "match" value of the Use-As-Dictionary header is a sf-string value that
provides an URL-matching pattern for requests where the dictionary can be used.</t>
          <t>The sf-string is parsed as a URL <xref target="RFC3986"/>, and supports absolute URLs
as well as relative URLs. When stored, any relative URLs MUST be expanded
so that only absolute URL patterns are used for matching against requests.</t>
          <t>The match URL supports using * as a wildcard within the match string for
pattern-matching multiple URLs. URLs with a natural * in them are not directly
supported unless they can rely on the behavior of * matching an arbitrary
string.</t>
          <t>The <xref target="Origin"/> of the URL in the "match" pattern MUST be the same as the
origin of the request that specifies the "Use-As-Dictionary" response and MUST
not include a * wildcard.</t>
          <t>The "match" value is required and MUST be included in the Use-As-Dictionary
sf-dictionary for the dictionary to be considered valid.</t>
        </section>
        <section anchor="ttl">
          <name>ttl</name>
          <t>The "ttl" value of the Use-As-Dictionary header is a sf-integer value that
provides the time in seconds that the dictionary is valid for (time to live).</t>
          <t>The "ttl" is independent of the cache lifetime of the resource being used for
the dictionary. If the underlying resource is evicted from cache then it is
also removed but this allows for setting an explicit time to live for use as a
dictionary independent of the underlying resource in cache. Expired resources
can still be useful as dictionaries while they are in cache and can be used for
fetching updates of the expired resource. It can also be useful to artificially
limit the life of a dictionary in cases where the dictionary is updated
frequently which can help limit the number of possible incoming dictionary
variations.</t>
          <t>The "ttl" value is optional and defaults to 31536000 (1 year).</t>
        </section>
        <section anchor="type">
          <name>type</name>
          <t>The "type" value of the Use-As-Dictionary header is a sf-string value that
describes the file format of the supplied dictionary.</t>
          <t>"raw" is the only defined dictionary format which represents an unformatted
blob of bytes suitable for any compression scheme to use.</t>
          <t>If a client receives a dictionary with a type that it does not understand, it
MUST NOT use the dictionary.</t>
          <t>The "type" value is optional and defaults to "raw".</t>
        </section>
        <section anchor="hashes">
          <name>hashes</name>
          <t>The "hashes" value of the Use-As-Dictionary header is a inner-list value
that provides a list of supported hash algorithms in order of server
preference.</t>
          <t>The dictionaries are identified by the hash of their contents and this value
allows for negotiation of the algorithm to use.</t>
          <t>The "hashes" value is optional and defaults to (sha-256).</t>
        </section>
        <section anchor="examples">
          <name>Examples</name>
          <section anchor="path-prefix">
            <name>Path Prefix</name>
            <t>A response that contained a response header:</t>
            <sourcecode type="http-message"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

Use-As-Dictionary: \
  match="/product/*", ttl=604800, hashes=(sha-256 sha-512)
]]></sourcecode>
            <t>Would specify matching any URL with a path prefix of /product/ on the same
<xref target="Origin"/> as the original request, expiring as a dictionary in 7 days
independent of the cache lifetime of the resource, and advertise support for
both sha-256 and sha-512 hash algorithms.</t>
          </section>
          <section anchor="versioned-directories">
            <name>Versioned Directories</name>
            <t>A response that contained a response header:</t>
            <sourcecode type="http-message"><![CDATA[
Use-As-Dictionary: match="/app/*/main.js"
]]></sourcecode>
            <t>Would match main.js in any directory under /app/, expiring as a dictionary in
one year and support using the sha-256 hash algorithm.</t>
          </section>
        </section>
      </section>
      <section anchor="sec-available-dictionary">
        <name>Sec-Available-Dictionary</name>
        <t>When a HTTP client makes a request for a resource for which it has an
appropriate dictionary, it can add a "Sec-Available-Dictionary" request header
to the request to indicate to the server that it has a dictionary available to
use for compression.</t>
        <t>The "Sec-Available-Dictionary" request header is a lowercase Base16-encoded
<xref target="RFC4648"/> hash of the contents of a single available dictionary calculated
using one of the algorithms advertised as being supported by the server.</t>
        <t>Its syntax is defined by the following <xref target="ABNF"/>:</t>
        <sourcecode type="abnf"><![CDATA[
Sec-Available-Dictionary = hvalue
hvalue                   = 1*hchar
hchar                    = DIGIT / "a" / "b" / "c" / "d" / "e" / "f"
]]></sourcecode>
        <t>The client MUST only send a single "Sec-Available-Dictionary" request header
with a single hash value for the best available match that it has available.</t>
        <t>For example:</t>
        <sourcecode type="http-message"><![CDATA[
NOTE: '\' line wrapping per RFC 8792

Sec-Available-Dictionary: \
  a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
]]></sourcecode>
        <section anchor="dictionary-freshness-requirement">
          <name>Dictionary freshness requirement</name>
          <t>To be considered as a match, the dictionary must not yet be expired as a
dictionary. When iterating through dictionaries looking for a match, the
expiration time of the dictionary is calculated by taking the last time the
dictionary was written and adding the "ttl" seconds from the
"Use-As-Dictionary" response. If the current time is beyond the expiration time
of the dictionary, it MUST be ignored.</t>
        </section>
        <section anchor="dictionary-url-matching">
          <name>Dictionary URL matching</name>
          <t>When a dictionary is stored as a result of a "Use-As-Dictionary" directive, it
includes a "match" string with the URL pattern of request URLs that the
dictionary can be used for.</t>
          <t>When comparing request URLs to the available dictionary match patterns, the
comparison should account for the * wildcard when matching against request
URLs. This can be accomplished with the following algorithm which returns TRUE
for a successful match and FALSE for no-match:</t>
          <ol spacing="normal" type="1"><li>Let MATCH represent the absolute URL pattern from the "match" value for the
given dictionary.</li>
            <li>LET URL represent the request URL being checked.</li>
            <li>
              <t>If there are no * characters in MATCH:
              </t>
              <ul spacing="normal">
                <li>If the MATCH and URL strings are identical, return TRUE.</li>
                <li>Else, return FALSE.</li>
              </ul>
            </li>
            <li>
              <t>If there is a single * character in MATCH and it is at the end of the
string:
              </t>
              <ul spacing="normal">
                <li>If the MATCH string is identical to the start of the URL string, return
 TRUE.</li>
                <li>Else, return FALSE.</li>
              </ul>
            </li>
            <li>Split the MATCH string by the * character into an array of MATCHES
(excluding the * deliminator from the individual entries).</li>
            <li>
              <t>If there is not a * character at the end of MATCH:
              </t>
              <ul spacing="normal">
                <li>Pop the last entry in MATCHES from the end of the array into PATTERN.</li>
                <li>If PATTERN is identical to the end of the URL string, remove the end of
 the URL string to the beginning of the match to PATTERN.</li>
                <li>Else, return FALSE.</li>
              </ul>
            </li>
            <li>
              <t>Pop the first entry in MATCHES from the front of the array into PATTERN.
              </t>
              <ul spacing="normal">
                <li>If PATTERN is not identical to the start of the URL string, return FALSE.</li>
              </ul>
            </li>
            <li>
              <t>Pop each entry off of the front of the MATCHES array into PATTERN. For
each PATTERN, in order:
              </t>
              <ul spacing="normal">
                <li>Search for the first match of PATTERN in URL, starting from the position
of the end of the previous match.</li>
                <li>If no match is found, return FALSE.</li>
              </ul>
            </li>
            <li>Return TRUE.</li>
          </ol>
        </section>
        <section anchor="multiple-matching-dictionaries">
          <name>Multiple matching dictionaries</name>
          <t>When there are multiple dictionaries that match a given request URL, the client
MUST pick the dictionary with the longest match pattern string length.</t>
        </section>
      </section>
    </section>
    <section anchor="negotiating-the-compression-algorithm">
      <name>Negotiating the compression algorithm</name>
      <t>When a compression dictionary is available for use for a given request, the
algorithm to be used is negotiated through the regular mechanism for
negotiating content encoding in HTTP.</t>
      <t>This document introduces two new content encoding algorithms:</t>
      <table>
        <thead>
          <tr>
            <th align="left">Content-Encoding</th>
            <th align="left">Description</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td align="left">br-d</td>
            <td align="left">Brotli using an external compression dictionary</td>
          </tr>
          <tr>
            <td align="left">zstd-d</td>
            <td align="left">Zstandard using an external compression dictionary</td>
          </tr>
        </tbody>
      </table>
      <t>The dictionary to use is negotiated separately and advertised in the
"Sec-Available-Dictionary" request header.</t>
      <section anchor="accept-encoding">
        <name>Accept-Encoding</name>
        <t>The client adds the algorithms that it supports to the "Accept-Encoding"
request header. e.g.:</t>
        <sourcecode type="http-message"><![CDATA[
Accept-Encoding: gzip, deflate, br, zstd, br-d, zstd-d
]]></sourcecode>
      </section>
      <section anchor="content-encoding">
        <name>Content-Encoding</name>
        <t>If a server supports one of the dictionary algorithms advertised by the client
and chooses to compress the content of the response using the dictionary that
the client has advertised then it sets the "Content-Encoding" response header
to the appropriate value for the algorithm selected. e.g.:</t>
        <sourcecode type="http-message"><![CDATA[
Content-Encoding: br-d
]]></sourcecode>
        <t>If the response is cacheable, it MUST include a "Vary" header to prevent caches
serving dictionary-compressed resources to clients that don't support them or
serving the response compressed with the wrong dictionary:</t>
        <sourcecode type="http-message"><![CDATA[
Vary: accept-encoding, sec-available-dictionary
]]></sourcecode>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <section anchor="content-encoding-1">
        <name>Content Encoding</name>
        <t>IANA is asked to update the "HTTP Content Coding Registry" registry
(<xref target="RFC9110"/>) according to the table below:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Name</th>
              <th align="left">Description</th>
              <th align="left">Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">br-d</td>
              <td align="left">A stream of bytes compressed using the Brotli protocol with an external dictionary</td>
              <td align="left">
                <xref target="RFC7932"/></td>
            </tr>
            <tr>
              <td align="left">zstd-d</td>
              <td align="left">A stream of bytes compressed using the Zstandard protocol with an external dictionary</td>
              <td align="left">
                <xref target="RFC8878"/></td>
            </tr>
          </tbody>
        </table>
      </section>
      <section anchor="header-field-registration">
        <name>Header Field Registration</name>
        <t>IANA is asked to update the
"Hypertext Transfer Protocol (HTTP) Field Name Registry" registry
(<xref target="RFC9110"/>) according to the table below:</t>
        <table>
          <thead>
            <tr>
              <th align="left">Field Name</th>
              <th align="left">Status</th>
              <th align="left">Reference</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">Use-As-Dictionary</td>
              <td align="left">permanent</td>
              <td align="left">
                <xref target="use-as-dictionary"/> of this document</td>
            </tr>
            <tr>
              <td align="left">Sec-Available-Dictionary</td>
              <td align="left">permanent</td>
              <td align="left">
                <xref target="sec-available-dictionary"/> of this document</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="compatibility-considerations">
      <name>Compatibility Considerations</name>
      <t>To minimize the risk of middle-boxes incorrectly processing
dictionary-compressed responses, compression dictionary transport MUST only
be used in secure contexts (HTTPS).</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>The security considerations for Brotli <xref target="RFC7932"/> and Zstandard
<xref target="RFC8878"/> apply to the dictionary-based versions of the respective
algorithms.</t>
      <section anchor="changing-content">
        <name>Changing content</name>
        <t>The dictionary must be treated with the same security precautions as
the content, because a change to the dictionary can result in a
change to the decompressed content.</t>
      </section>
      <section anchor="reading-content">
        <name>Reading content</name>
        <t>The CRIME attack shows that it's a bad idea to compress data from
mixed (e.g. public and private) sources -- the data sources include
not only the compressed data but also the dictionaries. For example,
if you compress secret cookies using a public-data-only dictionary,
you still leak information about the cookies.</t>
        <t>Not only can the dictionary reveal information about the compressed
data, but vice versa, data compressed with the dictionary can reveal
the contents of the dictionary when an adversary can control parts of
data to compress and see the compressed size. On the other hand, if
the adversary can control the dictionary, the adversary can learn
information about the compressed data.</t>
      </section>
      <section anchor="security-mitigations">
        <name>Security Mitigations</name>
        <t>If any of the mitigations do not pass, the client MUST drop the response and
return an error.</t>
        <section anchor="cross-origin-protection">
          <name>Cross-origin protection</name>
          <t>To make sure that a dictionary can only impact content from the same origin
where the dictionary was served, the "match" pattern used for matching a
dictionary to requests MUST be for the same origin that the dictionary
is served from.</t>
        </section>
        <section anchor="response-readability">
          <name>Response readability</name>
          <t>For clients, like web browsers, that provide additional protection against the
readability of the payload of a response and against user tracking, additional
protections MUST be taken to make sure that the use of dictionary-based
compression does not reveal information that would not otherwise be available.</t>
          <t>In these cases, dictionary compression MUST only be used when both the
dictionary and the compressed response are fully readable by the client.</t>
          <t>In browser terms, that means that both are either same-origin to the context
they are being fetched from or that the response is cross-origin and passes
the CORS check (https://fetch.spec.whatwg.org/#cors-check).</t>
          <section anchor="same-origin">
            <name>Same-Origin</name>
            <t>On the client-side, same-origin determination is defined in the fetch spec (https://html.spec.whatwg.org/multipage/browsers.html#origin).</t>
            <t>On the server-side, a request with a "Sec-Fetch-Site:" request header with a value of "same-origin" is to be considered a same-origin request.</t>
            <ul spacing="normal">
              <li>
                <t>For any request that is same-origin:
                </t>
                <ul spacing="normal">
                  <li>Response MAY be used as a dictionary.</li>
                  <li>Response MAY be compressed by an available dictionary.</li>
                </ul>
              </li>
            </ul>
          </section>
          <section anchor="cross-origin">
            <name>Cross-Origin</name>
            <t>For requests that are not same-origin (<xref target="same-origin"/>), the "mode" of the request can be used to determine the readability of the response.</t>
            <t>For clients that conform to the fetch spec, the mode of the request is stored in the RequestMode attribute of the request (https://fetch.spec.whatwg.org/#requestmode).</t>
            <t>For servers responding to clients that expose the request mode information, the value of the mode is sent in the "Sec-Fetch-Mode" request header.</t>
            <t>If a "Sec-Fetch-Mode" request header is not present, the server SHOULD allow for the dictionary compression to be used.</t>
            <ol spacing="normal" type="1"><li>
                <t>If the mode is "navigate" or "same-origin":
                </t>
                <ul spacing="normal">
                  <li>Response MAY be used as a dictionary.</li>
                  <li>Response MAY be compressed by an available dictionary.</li>
                </ul>
              </li>
              <li>
                <t>If the mode is "cors":
                </t>
                <ul spacing="normal">
                  <li>
                    <t>For clients, apply the CORS check from the fetch spec (https://fetch.spec.whatwg.org/#cors-check) which includes credentials checking restrictions that may not be possible to check on the server.
                    </t>
                    <ul spacing="normal">
                      <li>
                        <t>If the CORS check passes:
                        </t>
                        <ul spacing="normal">
                          <li>Response MAY be used as a dictionary.</li>
                          <li>Response MAY be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                      <li>
                        <t>Else:
                        </t>
                        <ul spacing="normal">
                          <li>Response MUST NOT be used as a dictionary.</li>
                          <li>Response MUST NOT be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                    </ul>
                  </li>
                  <li>
                    <t>For servers:
                    </t>
                    <ul spacing="normal">
                      <li>
                        <t>If the response does not include an "Access-Control-Allow-Origin" response header:
                        </t>
                        <ul spacing="normal">
                          <li>Response MUST NOT be used as a dictionary.</li>
                          <li>Response MUST NOT be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                      <li>
                        <t>If the request does not include an "Origin" request header:
                        </t>
                        <ul spacing="normal">
                          <li>Response MUST NOT be used as a dictionary.</li>
                          <li>Response MUST NOT be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                      <li>
                        <t>If the value of the "Access-Control-Allow-Origin" response header is "*":
                        </t>
                        <ul spacing="normal">
                          <li>Response MAY be used as a dictionary.</li>
                          <li>Response MAY be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                      <li>
                        <t>If the value of the "Access-Control-Allow-Origin" response header matches the value of the "Origin" request header:
                        </t>
                        <ul spacing="normal">
                          <li>Response MAY be used as a dictionary.</li>
                          <li>Response MAY be compressed by an available dictionary.</li>
                        </ul>
                      </li>
                    </ul>
                  </li>
                </ul>
              </li>
              <li>
                <t>If the mode is any other value (including "no-cors"):
                </t>
                <ul spacing="normal">
                  <li>Response MUST NOT be used as a dictionary.</li>
                  <li>Response MUST NOT be compressed by an available dictionary.</li>
                </ul>
              </li>
            </ol>
          </section>
        </section>
      </section>
    </section>
    <section anchor="privacy-considerations">
      <name>Privacy Considerations</name>
      <t>Since dictionaries are advertised in future requests using the hash of the
content of the dictionary, it is possible to abuse the dictionary to turn it
into a tracking cookie.</t>
      <t>To mitigate any additional tracking concerns, clients MUST treat dictionaries
in the same way that they treat cookies. This includes partitioning the storage
as cookies are partitioned as well as clearing the dictionaries whenever
cookies are cleared.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="FOLDING">
          <front>
            <title>Handling Long Lines in Content of Internet-Drafts and RFCs</title>
            <author fullname="K. Watsen" initials="K." surname="Watsen"/>
            <author fullname="E. Auerswald" initials="E." surname="Auerswald"/>
            <author fullname="A. Farrel" initials="A." surname="Farrel"/>
            <author fullname="Q. Wu" initials="Q." surname="Wu"/>
            <date month="June" year="2020"/>
            <abstract>
              <t>This document defines two strategies for handling long lines in width-bounded text content. One strategy, called the "single backslash" strategy, is based on the historical use of a single backslash ('\') character to indicate where line-folding has occurred, with the continuation occurring with the first character that is not a space character (' ') on the next line. The second strategy, called the "double backslash" strategy, extends the first strategy by adding a second backslash character to identify where the continuation begins and is thereby able to handle cases not supported by the first strategy. Both strategies use a self-describing header enabling automated reconstitution of the original content.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8792"/>
          <seriesInfo name="DOI" value="10.17487/RFC8792"/>
        </reference>
        <reference anchor="RFC9110">
          <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>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="HTTP">
          <front>
            <title>Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing</title>
            <author fullname="R. Fielding" initials="R." role="editor" surname="Fielding"/>
            <author fullname="J. Reschke" initials="J." role="editor" surname="Reschke"/>
            <date month="June" year="2014"/>
            <abstract>
              <t>The Hypertext Transfer Protocol (HTTP) is a stateless application-level protocol for distributed, collaborative, hypertext information systems. This document provides an overview of HTTP architecture and its associated terminology, defines the "http" and "https" Uniform Resource Identifier (URI) schemes, defines the HTTP/1.1 message syntax and parsing requirements, and describes related security concerns for implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7230"/>
          <seriesInfo name="DOI" value="10.17487/RFC7230"/>
        </reference>
        <reference anchor="Origin">
          <front>
            <title>The Web Origin Concept</title>
            <author fullname="A. Barth" initials="A." surname="Barth"/>
            <date month="December" year="2011"/>
            <abstract>
              <t>This document defines the concept of an "origin", which is often used as the scope of authority or privilege by user agents. Typically, user agents isolate content retrieved from different origins to prevent malicious web site operators from interfering with the operation of benign web sites. In addition to outlining the principles that underlie the concept of origin, this document details how to determine the origin of a URI and how to serialize an origin into a string. It also defines an HTTP header field, named "Origin", that indicates which origins are associated with an HTTP request. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="6454"/>
          <seriesInfo name="DOI" value="10.17487/RFC6454"/>
        </reference>
        <reference anchor="ABNF">
          <front>
            <title>Augmented BNF for Syntax Specifications: ABNF</title>
            <author fullname="D. Crocker" initials="D." role="editor" surname="Crocker"/>
            <author fullname="P. Overell" initials="P." surname="Overell"/>
            <date month="January" year="2008"/>
            <abstract>
              <t>Internet technical specifications often need to define a formal syntax. Over the years, a modified version of Backus-Naur Form (BNF), called Augmented BNF (ABNF), has been popular among many Internet specifications. The current specification documents ABNF. It balances compactness and simplicity with reasonable representational power. The differences between standard BNF and ABNF involve naming rules, repetition, alternatives, order-independence, and value ranges. This specification also supplies additional rule definitions and encoding for a core lexical analyzer of the type common to several Internet specifications. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="68"/>
          <seriesInfo name="RFC" value="5234"/>
          <seriesInfo name="DOI" value="10.17487/RFC5234"/>
        </reference>
        <reference anchor="RFC3986">
          <front>
            <title>Uniform Resource Identifier (URI): Generic Syntax</title>
            <author fullname="T. Berners-Lee" initials="T." surname="Berners-Lee"/>
            <author fullname="R. Fielding" initials="R." surname="Fielding"/>
            <author fullname="L. Masinter" initials="L." surname="Masinter"/>
            <date month="January" year="2005"/>
            <abstract>
              <t>A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource. This specification defines the generic URI syntax and a process for resolving URI references that might be in relative form, along with guidelines and security considerations for the use of URIs on the Internet. The URI syntax defines a grammar that is a superset of all valid URIs, allowing an implementation to parse the common components of a URI reference without knowing the scheme-specific requirements of every possible identifier. This specification does not define a generative grammar for URIs; that task is performed by the individual specifications of each URI scheme. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="STD" value="66"/>
          <seriesInfo name="RFC" value="3986"/>
          <seriesInfo name="DOI" value="10.17487/RFC3986"/>
        </reference>
        <reference anchor="RFC8941">
          <front>
            <title>Structured Field Values for HTTP</title>
            <author fullname="M. Nottingham" initials="M." surname="Nottingham"/>
            <author fullname="P-H. Kamp" 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="RFC4648">
          <front>
            <title>The Base16, Base32, and Base64 Data Encodings</title>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
            <date month="October" year="2006"/>
            <abstract>
              <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="4648"/>
          <seriesInfo name="DOI" value="10.17487/RFC4648"/>
        </reference>
        <reference anchor="RFC7932">
          <front>
            <title>Brotli Compressed Data Format</title>
            <author fullname="J. Alakuijala" initials="J." surname="Alakuijala"/>
            <author fullname="Z. Szabadka" initials="Z." surname="Szabadka"/>
            <date month="July" year="2016"/>
            <abstract>
              <t>This specification defines a lossless compressed data format that compresses data using a combination of the LZ77 algorithm and Huffman coding, with efficiency comparable to the best currently available general-purpose compression methods.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7932"/>
          <seriesInfo name="DOI" value="10.17487/RFC7932"/>
        </reference>
        <reference anchor="RFC8878">
          <front>
            <title>Zstandard Compression and the 'application/zstd' Media Type</title>
            <author fullname="Y. Collet" initials="Y." surname="Collet"/>
            <author fullname="M. Kucherawy" initials="M." role="editor" surname="Kucherawy"/>
            <date month="February" year="2021"/>
            <abstract>
              <t>Zstandard, or "zstd" (pronounced "zee standard"), is a lossless data compression mechanism. This document describes the mechanism and registers a media type, content encoding, and a structured syntax suffix to be used when transporting zstd-compressed content via MIME.</t>
              <t>Despite use of the word "standard" as part of Zstandard, readers are advised that this document is not an Internet Standards Track specification; it is being published for informational purposes only.</t>
              <t>This document replaces and obsoletes RFC 8478.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8878"/>
          <seriesInfo name="DOI" value="10.17487/RFC8878"/>
        </reference>
      </references>
    </references>
    <?line 450?>



  </back>
  <!-- ##markdown-source:
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
SlCiKJIxECnE/wJ+Oh37XEYAAA==

-->

</rfc>
