Skip to content
Prev Previous commit
Next Next commit
Fixed link header processing
  • Loading branch information
pmeenan committed Feb 11, 2026
commit 763cdd84b4eeae19fc36e23dcb9fdba827697b15
27 changes: 13 additions & 14 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -27791,17 +27791,19 @@ document.body.appendChild(wbr);</code></pre>
removed.</p></li>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I know this is copied from prefetch, but for future reference this does not really match what browsers do, at least Chromium can also process link elements after mutations of type attribute, media attribute etc https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/core/html/html_link_element.cc?q=HTMLLinkElement::ParseAttribute&ss=chromium%2Fchromium%2Fsrc ; see also #11400 for some interpretation of "changes".

</ul>

<p>The <span>fetch and process the linked resource</span> algorithm for <code
data-x="rel-compression-dictionary">compression-dictionary</code> links, given a
<code>link</code> element <var>el</var>, is as follows:</p>
<p>The <span>fetch and process the linked resource</span> steps for this type of linked resource,
given a <code>link</code> element <var>el</var>, are to <span
data-x="create link options from element">create link options</span> from <var>el</var> and

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So I guess there is a bunch of options to be tested here: https://html.spec.whatwg.org/#create-link-options-from-element ; dictionary-fetch-with-link-element.tentative.https.html seems quite limited with only a test for crossorigin=anonymous (which is also default).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Chromium does not seem to pass down the nonce attribute down to the fetch algorithm. I tried a WPT test and a patch here, but I'm not quite sure it's correct: https://chromium-review.googlesource.com/c/chromium/src/+/8098863

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

OK, I went over https://html.spec.whatwg.org/multipage/semantics.html#create-link-options-from-element and I think we have some satisfying coverage here:

crossorigin: https://chromium-review.googlesource.com/c/chromium/src/+/8098207
referrer policy: https://chromium-review.googlesource.com/c/chromium/src/+/8118407
source set: Not exposed by https://fetch.spec.whatwg.org/#request-class, this only seems to be used for rel=preload and destination=image, added a tentative test at https://chromium-review.googlesource.com/c/chromium/src/+/8124456
baseURL: Added https://chromium-review.googlesource.com/c/chromium/src/+/8117615
origin: Not exposed by https://fetch.spec.whatwg.org/#request-class, this only seems to be used for rel=preconnect
environment: Relevant usage seems to be to use request's client https://html.spec.whatwg.org/multipage/semantics.html#fetching-and-processing-a-resource-from-a-link-element:link-options-environment which is used for many things in the fetch spec, including checking that compression-dictionary don't work in insecure context (test dictionary-insecure-context.tentative.http.html).
policy container: Likely covered by any tests involving policies, e.g. web-platform-tests/wpt#61309
document: This only seems to be used by rel=preload
cryptographic nonce metadata: Not exposed by https://fetch.spec.whatwg.org/#request-class, attribute should not affect CSP, tentative test at https://chromium-review.googlesource.com/c/chromium/src/+/8098863
fetch priority: Not exposed by https://fetch.spec.whatwg.org/#request-class, attribute can affect server-side prioritization of requests, but that's implementation-defined and so we can't have a shared WPT.
href: Covered by any test registering the dictionary, there are many of them!
integrity: Attribute is not accepted and shouldn't be transmitted to the fetch, tentative test at https://chromium-review.googlesource.com/c/chromium/src/+/8117450
type: Not exposed by https://fetch.spec.whatwg.org/#request-class, type attribute is somehow tested in web-platform-tests/wpt#61211 ; the link option does not seem to be used for rel=compression-dictionary.

to <span>load a compression dictionary</span> given the result and <var>el</var>.</p>

<ol>
<li><p>If <var>el</var>'s <code data-x="attr-link-href">href</code> attribute's value is the
empty string, then return.</p></li>
<p>The <span>process a link header</span> step for this type of linked resource given a <span

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.

My understanding from TPAC is that compression dictionary responses are intended to be processed almost primarily on subresource requests. But this header-processing algorithm does not run in those cases, and in fact we do not have a spec'ed processing model for subresource Link header requests. Is my understanding correct, and do we have tests for this behavior?

We haven't really had a pressing need to spec the Link header processing model on subresource requests, but if that's one of the main and expected ways of engaging with this new feature, and we have tests for it, perhaps it's important enough to invest in.

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 Link header is independent from the use of the dictionaries for compression and is used to trigger the loading of a stand-alone dictionary (instead of the subresource delta-compression model where a response is a dictionary itself).

The main use case envisioned is for a HTML document to trigger the loading of a dictionary that would be used in future document requests (compressing away the common HTML templates).

That said, I am sure someone would have a use case for triggering a separate dictionary request from subresources and that might be something Chrome currently allows (along with preload and preconnect) though there are ongoing discussions about how those should be handled to avoid tracking concerns.

The dictionary use case for subresource link headers should probably be included in whatever spec work we do to specify the behavior for preconnect and preload.

Right now the only WPT tests that use the Link header are for the document itself.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Note that this is also used by https://html.spec.whatwg.org/#process-link-headers

(I guess the use case is even less important, but technically we should have WPT test for that too)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry, I was talking about Early hints here:

https://html.spec.whatwg.org/#process-early-hint-headers

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tentative test for this: web-platform-tests/wpt#61119

This is currently only implemented in Firefox (as I mentioned this use case is probably not super important...)

data-x="link processing options">link processing options</span> <var>options</var> are to
<span>load a compression dictionary</span> given <var>options</var>.</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same here, I don't see a lot of options tested for dictionary-fetch-with-link-header.tentative.https.html

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

As commented above I added several tests for options, although often it's only for the link element only, for which one can configure things via attributes. We could add similar tests for link header.


<li><p>Let <var>options</var> be the result of <span data-x="create link options from
element">creating link options</span> from <var>el</var>.</p></li>
<p>To <dfn>load a compression dictionary</dfn> given a <span>link processing options</span>
<var>options</var> and optional <code>link</code> element <var>el</var>:</p>

<ol>
<li><p>If <var>options</var>'s <span data-x="link options crossorigin">crossorigin</span>
is <span data-x="attr-crossorigin-none">No CORS</span>, set <var>options</var>'s
<span data-x="link options crossorigin">crossorigin</span> to
Expand All @@ -27824,12 +27826,12 @@ document.body.appendChild(wbr);</code></pre>
<span>byte sequence</span> <var>bytesOrNull</var>:</p>

<ol>
<li><p>If <var>response</var> is a <span>network error</span>, <span
<li><p>If <var>response</var> is a <span>network error</span> and <var>el</var> is set, <span
data-x="concept-event-fire">fire an event</span> named <code
data-x="event-error">error</code> at <var>el</var>.</p></li>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can we please add WPT tests for these two events? (for both Link header and element).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Tentative test at https://chromium-review.googlesource.com/c/chromium/src/+/8036725

for Link header, I'm unsure there is reasonable way to check the load/error are not dispatched, since we don't have link anyway...


<li><p>Otherwise, <span data-x="concept-event-fire">fire an event</span> named <code
data-x="event-load">load</code> at <var>el</var>.</p></li>
<li><p>Otherwise, if <var>el</var> is set, <span data-x="concept-event-fire">fire an event</span>
named <code data-x="event-load">load</code> at <var>el</var>.</p></li>
</ol>
</li>

Expand All @@ -27839,9 +27841,6 @@ document.body.appendChild(wbr);</code></pre>
<var>request</var> to prioritize other requests that are necessary for the current document.</p></li>
</ol>

<p>The <span>process a link header</span> steps for this type of linked resource are to do
nothing.</p>


<h5>Link type "<dfn attr-value for="link/rel"><code
data-x="rel-dns-prefetch">dns-prefetch</code></dfn>"</h5>
Expand Down