Skip to content
164 changes: 159 additions & 5 deletions fetch.bs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,11 @@ urlPrefix:https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-layered-cooki
url:name-retrieve-cookies;text:retrieve cookies
url:name-serialize-cookies;text:serialize cookies
url:name-garbage-collect-cookies;text:garbage collect cookies

urlPrefix:https://urlpattern.spec.whatwg.org/#;type:dfn;spec:urlpattern
url:url-pattern-create;text:creating a URL pattern
url:url-pattern-has-regexp-groups;text:has regexp groups

</pre>

<pre class=biblio>
Expand Down Expand Up @@ -1818,6 +1823,7 @@ device to assist defining CSP and Mixed Content. It is not exposed to JavaScript
<p>A <dfn export>destination type</dfn> is one of:
the empty string,
"<code>audio</code>",
"<code>compression-dictionary</code>",
"<code>audioworklet</code>",
"<code>document</code>",
"<code>embed</code>",
Expand Down Expand Up @@ -1874,7 +1880,7 @@ not always relevant and might require different behavior.
<th>CSP directive
<th>Features
<tr>
<td rowspan=21>""
<td rowspan=22>""
<td>"<code>report</code>"
<td rowspan=2>&mdash;
<td>CSP, NEL reports.
Expand Down Expand Up @@ -1962,6 +1968,10 @@ not always relevant and might require different behavior.
<td>"<code>video</code>"
<td><code>media-src</code>
<td>HTML's <code>&lt;video></code> element
<tr>
<td>"<code>compression-dictionary</code>"
<td><code>connect-src</code>
<td>HTML's <code>&lt;link rel=compression-dictionary&gt;</code>
<tr>
<td>"<code>download</code>"
<td>""
Expand Down Expand Up @@ -2294,9 +2304,14 @@ Unless stated otherwise, it is unset.
<dfn export for=request id=timing-allow-failed>timing allow failed flag</dfn>. Unless stated
otherwise, it is unset.

<p>A <a for=/>request</a> has an associated
<dfn export for=request id=compression-dictionary-disallowed>compression dictionary disallowed flag</dfn>.
Unless stated otherwise, it is unset.

<p class=note>A <a for=/>request</a>'s <a for=request>URL list</a>, <a for=request>current URL</a>,
<a for=request>redirect count</a>, <a for=request>response tainting</a>,
<a for=request>done flag</a>, and <a for=request>timing allow failed flag</a> are used as
<a for=request>done flag</a>, <a for=request>timing allow failed flag</a>, and
<a for=request>compression dictionary disallowed flag</a> are used as
bookkeeping details by the <a for=/>fetch</a> algorithm.

<hr>
Expand Down Expand Up @@ -3300,6 +3315,22 @@ or an <a>implementation-defined</a> value.
</div>


<h3 id=compression-dictionary-cache-partitions>Compression-dictionary cache partitions</h3>

<div algorithm>
<p>To <dfn>determine the compression-dictionary cache partition</dfn>, given a <a for=/>request</a> <var>request</var>:

<ol>
<li><p>Let <var>key</var> be the result of <a for=request>determining the network partition key</a>
given <var>request</var>.

<li><p>If <var>key</var> is null, then return null.

<li><p>Return the unique compression-dictionary cache associated with <var>key</var>. [[!RFC9842]]
</ol>
</div>


<h3 id=port-blocking>Port blocking</h3>

<p class=note>New protocols can avoid the need for blocking ports by negotiating the protocol
Expand Down Expand Up @@ -4962,6 +4993,18 @@ steps:
</ol>
</dl>

<li><p>If <var>request</var>'s <a for=request>response tainting</a> is "<code>opaque</code>",
then:

<ol>
<li><p>Let <var>corpPolicy</var> be the result of <a for="header list">getting</a>
`<a http-header><code>Cross-Origin-Resource-Policy</code></a>` from <var>response</var>'s
<a for=response>header list</a>.

<li><p>If <var>corpPolicy</var> is not `<code>cross-origin</code>`, then set
<var>request</var>'s <a for=request>compression dictionary disallowed flag</a>.
</ol>

<li><p>If <var>recursive</var> is true, then return <var>response</var>.

<li>
Expand Down Expand Up @@ -6331,8 +6374,9 @@ run these steps:
<li><p>If <var>httpRequest</var>'s <a for=request>cache mode</a> is
"<code>only-if-cached</code>", then return a <a>network error</a>.

<li><p>Let <var>forwardResponse</var> be the result of running <a>HTTP-network fetch</a> given
<var>httpFetchParams</var>, <var>includeCredentials</var>, and <var>isNewConnectionFetch</var>.
<li><p>Let <var>forwardResponse</var> be the result of running
<a>HTTP-network compression-dictionary fetch</a> given <var>httpFetchParams</var>,
<var>includeCredentials</var>, and <var>isNewConnectionFetch</var>.

<li><p>If <var>httpRequest</var>'s <a for=request>method</a> is <a>unsafe</a> and
<var>forwardResponse</var>'s <a for=response>status</a> is in the range 200 to 399, inclusive,
Expand Down Expand Up @@ -6481,12 +6525,121 @@ run these steps:
<li><p>If <var>isAuthenticationFetch</var> is true, then create an <a>authentication entry</a> for
<var>request</var> and the given realm.

<li>
<p>If <var>request</var>'s <a for=request>compression dictionary disallowed flag</a> is not set
and <var>response</var>'s <a for=response>header list</a> <a for="header list">contains</a>
`<code>Use-As-Dictionary</code>`:
<!-- This is defined in [[!RFC9842]] -->

<ol>
<li><p>Let <var>dictionaryValue</var> be the result of
<a for="header list">getting a structured field value</a> given `<code>Use-As-Dictionary</code>`,
"<code>dictionary</code>", and <var>response</var>'s <a for=response>header list</a>.

<li><p>If <var>dictionaryValue</var> is null or <var>dictionaryValue</var>["<code>match</code>"]
does not <a for=map>exist</a>, then return <var>response</var>.

<li><p>Let <var>compressionDictionaryCache</var> be the result of
<a>determining the compression-dictionary cache partition</a> given <var>request</var>.

<li><p>If <var>compressionDictionaryCache</var> is null, then return <var>response</var>.

<li><p>Let <var>pattern</var> be the result of
<a for=/>creating a URL pattern</a> from <var>dictionaryValue</var>["<code>match</code>"]
and <var>request</var>'s <a for=request>current URL</a>.

<li><p>If <var>pattern</var> is failure or <var>pattern</var> <a for=/>has regexp groups</a>,
then return <var>response</var>.

<li><p>Let <var>expirationTime</var> be the time at which the <var>response</var> becomes
a <a>stale response</a>.

<li><p>If <var>expirationTime</var> is not in the future, then return <var>response</var>.

<li><p>Store <var>response</var> in <var>compressionDictionaryCache</var> with its associated
<var>pattern</var>, <var>dictionaryValue</var> and <var>expirationTime</var>.
</ol>

<li><p>Return <var>response</var>. <span class=note>Typically <var>response</var>'s
<a for=response>body</a>'s <a for=body>stream</a> is still being enqueued to after
returning.</span>
</ol>
</div>

<h3 id=http-network-compression-dictionary-fetch>HTTP-network compression-dictionary fetch</h3>

<div algorithm>
<p>To <dfn id=concept-http-network-compression-dictionary-fetch>HTTP-network compression-dictionary fetch</dfn>,
given a <a for=/>fetch params</a> <var>fetchParams</var>, an optional boolean
<var>includeCredentials</var> (default false), and an optional boolean <var>forceNewConnection</var>
(default false), run these steps:

<ol>
<li><p>Let <var>request</var> be <var>fetchParams</var>'s <a for="fetch params">request</a>.

<li><p>If <var>request</var>'s <a for=request>mode</a> is "<code>no-cors</code>", then return the
result of running <a>HTTP-network fetch</a> given <var>fetchParams</var>,
<var>includeCredentials</var>, and <var>forceNewConnection</var>.

<li><p>If the user agent is configured to block cookies for <var>request</var>, then return the
result of running <a>HTTP-network fetch</a> given <var>fetchParams</var>,
<var>includeCredentials</var>, and <var>forceNewConnection</var>.
Comment on lines +6584 to +6586
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this. The dictionary is partitioned so how is it different from the HTTP cache?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Use-As-Dictionary response header can attach an arbitrary ID to arbitrary requests from the same origin (that match a given pattern) without having to access the underlying response. This allows non-executable responses to attach a tracking ID to an origin that behaves like a cookie without having to execute code (image-only origins for example).

To keep things consistent with dev expectations and CSP, the security and privacy teams requested that they also be treated as cookies and not be allowed in situations where cookies would not have been allowed.


<li><p>Let <var>compressionDictionaryCache</var> be the result of
<a>determining the compression-dictionary cache partition</a> given <var>request</var>.

<li><p>If <var>compressionDictionaryCache</var> is null, then return the result of running
<a>HTTP-network fetch</a> given <var>fetchParams</var>, <var>includeCredentials</var>, and
<var>forceNewConnection</var>.

<li><p>Let <var>bestMatch</var> be the result of finding the best matching dictionary in
<var>compressionDictionaryCache</var> for <var>request</var> as defined in
[[!RFC9842]].

<li><p>If <var>bestMatch</var> is null, then return the result of running <a>HTTP-network fetch</a>
given <var>fetchParams</var>, <var>includeCredentials</var>, and <var>forceNewConnection</var>.

<li><p>Add the `<code>Available-Dictionary</code>` and `<code>Dictionary-ID</code>`
(if applicable) headers to <var>request</var> using <var>bestMatch</var> as defined in
[[!RFC9842]].

<li><p><a for="header list">Combine</a> (`<code>Accept-Encoding</code>`, `<code>dcb</code>`)
in <var>request</var>'s <a for=request>header list</a>.

<li><p><a for="header list">Combine</a> (`<code>Accept-Encoding</code>`, `<code>dcz</code>`)
in <var>request</var>'s <a for=request>header list</a>.
Comment on lines +6606 to +6610
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we doing this even if web developers set these headers? That seems rather sketchy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accept-Encoding is a forbidden request header so developers shouldn't be able to set it.


<li><p>Let <var>response</var> be the result of running <a>HTTP-network fetch</a> given
<var>fetchParams</var>, <var>includeCredentials</var>, and <var>forceNewConnection</var>.

<li><p>Let <var>codings</var> be the result of <a>extracting header list values</a> given
`<code>Content-Encoding</code>` and <var>response</var>'s <a for=response>header list</a>.

<li><p>If <var>codings</var> is null or does not contain `<code>dcb</code>` or `<code>dcz</code>`,
then return <var>response</var>.

<li><p>If <var>request</var>'s <a for=request>compression dictionary disallowed flag</a>
is set, then return a <a>network error</a>.

<li><p>Let <var>availableDictionaryHash</var> be the result of
<a>getting a structured field value</a> given `<code>Available-Dictionary</code>`,
"<code>bytestring</code>", and <var>request</var>'s <a for=request>header list</a>.

<li><p>Let <var>newBody</var> be a new <a for=/>body</a> whose <a for=body>stream</a> is the
result of transforming <var>response</var>'s <a for=response>body</a>'s <a for=body>stream</a>
with an algorithm that verifies that the dictionary hash in the stream matches
<var>availableDictionaryHash</var> and decodes the rest of the stream with the applicable
algorithm as defined in [[!RFC9842]]. If verification or decoding fails,
the transformed stream must error.

<li><p>Set <var>response</var>'s <a for=response>body</a> to <var>newBody</var>.

<li><p><a>Delete</a> `<code>Content-Encoding</code>` from <var>response</var>'s
<a for=response>header list</a>.

<li><p>Return <var>response</var>.
</ol>
</div>

<h3 id=http-network-fetch>HTTP-network fetch</h3>

Expand Down Expand Up @@ -6558,6 +6711,7 @@ optional boolean <var>forceNewConnection</var> (default false), run these steps:

<ul>
<li><p>Follow the relevant requirements from HTTP. [[!HTTP]] [[!HTTP-CACHING]]
[[!RFC9842]]

<li>
<p>If <var>request</var>'s <a for=request>body</a> is non-null, and <var>request</var>'s
Expand Down Expand Up @@ -8414,7 +8568,7 @@ dictionary RequestInit {
any window; // can only be set to null
};

enum RequestDestination { "", "audio", "audioworklet", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" };
enum RequestDestination { "", "audio", "audioworklet", "compression-dictionary", "document", "embed", "font", "frame", "iframe", "image", "json", "manifest", "object", "paintworklet", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt" };
enum RequestMode { "navigate", "same-origin", "no-cors", "cors" };
enum RequestCredentials { "omit", "same-origin", "include" };
enum RequestCache { "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" };
Expand Down