script: Implement parsing of Link HTTP headers (#39052)

The Link HTTP header can do the same as link elements,
in that they can preload/prefetch/etc... This implements
the basics of header parsing and hooks it up for preload.

Note that we use a new nom-rfc8288 crate that implements
the parsing behavior. However, that crate is too strict
in that empty attributes (;; as part of the header) are
discarded and resulting in a parsing failure. Therefore,
we use its lenient parsing mode.

Part of #35035

---------

Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
Signed-off-by: Tim van der Lippe <TimvdLippe@users.noreply.github.com>
Co-authored-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
Tim van der Lippe 2025-09-28 09:22:09 +02:00 committed by GitHub
parent 41b1a8706b
commit ba5f36b671
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 716 additions and 675 deletions

View file

@ -1,3 +0,0 @@
[link-header-preload-delay-onload.html]
[Makes sure that Link headers preload resources and block window.onload after resource discovery]
expected: FAIL

View file

@ -1,7 +1,4 @@
[link-header-preload-non-html.html]
[XHTML documents should respect preload Link headers]
expected: FAIL
[plain text documents should respect preload Link headers]
expected: FAIL

View file

@ -1,3 +0,0 @@
[link-header-preload-nonce.html]
[with nonce]
expected: FAIL

View file

@ -1,583 +1,300 @@
[preload-referrer-policy.html]
expected: TIMEOUT
[referrer policy ( -> , header, cross-origin)]
expected: TIMEOUT
[referrer policy ( -> , header, same-origin)]
expected: NOTRUN
[referrer policy ( -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> no-referrer, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> no-referrer, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> same-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy ( -> same-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> same-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy ( -> same-origin, header, same-origin)]
expected: NOTRUN
[referrer policy ( -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> origin, element, same-origin)]
expected: NOTRUN
[referrer policy ( -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> origin, header, same-origin)]
expected: NOTRUN
[referrer policy ( -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy ( -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy ( -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy ( -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
[referrer policy ( -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy ( -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy ( -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy ( -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> unsafe-url, element, cross-origin)]
expected: NOTRUN
[referrer policy ( -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy ( -> unsafe-url, header, cross-origin)]
expected: NOTRUN
[referrer policy ( -> unsafe-url, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> , element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> , element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> , header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> , header, same-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> no-referrer, element, cross-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> no-referrer, element, same-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> no-referrer, header, cross-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> no-referrer, header, same-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> same-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> same-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (no-referrer -> same-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> same-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> unsafe-url, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> unsafe-url, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (no-referrer -> unsafe-url, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> , element, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> , element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> , header, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> , header, same-origin)]
expected: NOTRUN
[referrer policy (same-origin -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> no-referrer, element, same-origin)]
expected: NOTRUN
[referrer policy (same-origin -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> no-referrer, header, same-origin)]
expected: NOTRUN
[referrer policy (same-origin -> same-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> same-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (same-origin -> same-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> same-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> unsafe-url, element, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (same-origin -> unsafe-url, header, cross-origin)]
expected: NOTRUN
[referrer policy (same-origin -> unsafe-url, header, same-origin)]
expected: NOTRUN
[referrer policy (origin -> , element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> , element, same-origin)]
expected: NOTRUN
[referrer policy (origin -> , header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> , header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> no-referrer, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> no-referrer, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> same-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> same-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> same-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> same-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin -> origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (origin -> origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin -> origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (origin -> origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> unsafe-url, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> unsafe-url, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin -> unsafe-url, header, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> , element, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> , element, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> , header, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> , header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> no-referrer, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> no-referrer, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> same-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> same-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> same-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> same-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> unsafe-url, element, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (origin-when-cross-origin -> unsafe-url, header, cross-origin)]
expected: NOTRUN
[referrer policy (origin-when-cross-origin -> unsafe-url, header, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> , element, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> , element, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> , header, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> , header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> no-referrer, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> no-referrer, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> same-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> same-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> same-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> same-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> origin, element, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> origin, header, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> unsafe-url, element, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> unsafe-url, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (strict-origin-when-cross-origin -> unsafe-url, header, cross-origin)]
expected: NOTRUN
[referrer policy (strict-origin-when-cross-origin -> unsafe-url, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> , element, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> , element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> , header, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> , header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> no-referrer, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> no-referrer, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> no-referrer, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> no-referrer, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> same-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> same-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> same-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> same-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin, element, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin, header, cross-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> strict-origin-when-cross-origin, element, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> strict-origin-when-cross-origin, element, same-origin)]
expected: NOTRUN
expected: FAIL
[referrer policy (unsafe-url -> strict-origin-when-cross-origin, header, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> strict-origin-when-cross-origin, header, same-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> unsafe-url, element, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> unsafe-url, element, same-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> unsafe-url, header, cross-origin)]
expected: NOTRUN
[referrer policy (unsafe-url -> unsafe-url, header, same-origin)]
expected: NOTRUN
expected: FAIL

View file

@ -25,7 +25,7 @@
expected: FAIL
[Loading style (use-credentials) with link (anonymous) should discard the preloaded response]
expected: TIMEOUT
expected: NOTRUN
[Loading style (use-credentials) with link (use-credentials) should reuse the preloaded response]
expected: NOTRUN
@ -47,3 +47,33 @@
[Loading backgroundImage (same-origin) with link (same-origin) should reuse the preloaded response]
expected: FAIL
[Loading module (use-credentials) with link (anonymous) should discard the preloaded response]
expected: TIMEOUT
[Loading module (use-credentials) with link (use-credentials) should reuse the preloaded response]
expected: NOTRUN
[Loading style (same-origin) with link (same-origin) should reuse the preloaded response]
expected: NOTRUN
[Loading style (no-cors) with link (no-cors) should reuse the preloaded response]
expected: NOTRUN
[Loading style (no-cors) with link (anonymous) should discard the preloaded response]
expected: NOTRUN
[Loading style (no-cors) with link (use-credentials) should discard the preloaded response]
expected: NOTRUN
[Loading style (anonymous) with link (no-cors) should discard the preloaded response]
expected: NOTRUN
[Loading style (anonymous) with link (anonymous) should reuse the preloaded response]
expected: NOTRUN
[Loading style (anonymous) with link (use-credentials) should discard the preloaded response]
expected: NOTRUN
[Loading style (use-credentials) with link (no-cors) should discard the preloaded response]
expected: NOTRUN