Skip to content

Commit daeaf34

Browse files
committed
speculation-rules test
1 parent b958678 commit daeaf34

File tree

6 files changed

+36
-3
lines changed

6 files changed

+36
-3
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ public/*
4242
!public/favicon.ico
4343
!public/manifest.webmanifest
4444
!public/robots.txt
45+
!public/speculation-rules.json
4546
!public/sw.js

public/_headers

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
permissions-policy: browsing-topics=(),interest-cohort=()
99
referrer-policy: same-origin
1010
x-robots-tag: noai, noimageai
11+
speculation-rules: "/speculation-rules.json?v=%DEPLOY_HASH%"
1112

1213
/assets/*
1314
x-robots-tag: noindex
@@ -24,3 +25,6 @@
2425

2526
/rss.xml
2627
content-type: application/xml; charset=utf-8
28+
29+
/speculation-rules.json
30+
content-type: application/speculationrules+json

public/speculation-rules.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"prefetch": [
3+
{
4+
"source": "document",
5+
"where": {
6+
"and": [
7+
{ "href_matches": "/*", "relative_to": "document" }
8+
]
9+
},
10+
"eagerness": "moderate"
11+
}
12+
]
13+
}

routes/(headers)/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { authorized } from "@src/shared.ts";
44
export const pattern = "/_headers";
55
export const order = 9999;
66

7-
export const GET: HyperHandle = async ({ request, response }) => {
7+
export const GET: HyperHandle = async ({ request, response, platform }) => {
88
if (!authorized(request)) {
99
return null;
1010
}
@@ -17,6 +17,7 @@ export const GET: HyperHandle = async ({ request, response }) => {
1717
`default-src 'self'`;
1818
let body = await response.text();
1919
body = body.replace("%CONTENT_SECURITY_POLICY%", csp);
20+
body = body.replaceAll("%DEPLOY_HASH%", platform.deployHash);
2021
response = new Response(body, response);
2122
response.headers.set("content-length", body.length.toString());
2223
return response;

src/middleware.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ export const middleware: HyperHandle = ({ request, platform }) => {
1919
["x-content-type-options", "nosniff"],
2020
["permissions-policy", "browsing-topics=(),interest-cohort=()"],
2121
["referrer-policy", "same-origin"],
22+
["speculation-rules", '"/speculation-rules.json"'],
2223
["x-img-src", "data:"],
2324
// TODO - generate? - Hash for Logo inline styles
2425
["x-style-src", `'sha256-kXLrG8qzlz0MMhgMvdF9YD6tca5CYXeC1iFSTHDsO8w='`],
25-
// Allow WASM (search)
26+
// "this.rel=`stylesheet`"
27+
["x-script-src", `'unsafe-hashes'`],
28+
["x-script-src", `'sha256-BGXQRYq/G9+8wEtSYSbQRnDRz8/8apfi/W/CUBMh9w0='`],
29+
// Allow search WASM and fallback
2630
["x-script-src", `'wasm-unsafe-eval'`],
2731
["x-form-action", `https://duckduckgo.com`],
2832
];
@@ -32,6 +36,10 @@ export const middleware: HyperHandle = ({ request, platform }) => {
3236
pageHeaders.push(["x-style-src", `'sha256-${style.hash}'`]);
3337
});
3438

39+
if (url.pathname.startsWith("/speculation-rules.json")) {
40+
pageHeaders.push(["content-type", "application/speculationrules+json"]);
41+
}
42+
3543
// CORS headers
3644
if (/\/(rss|sitemap)\.xml$/.test(url.pathname)) {
3745
pageHeaders.push(["access-control-allow-origin", "*"]);

src/shared.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
const SET_HEADERS = new Set(["content-type"]);
2+
13
export const appendHeaders = (
24
response: Response,
35
headers: Array<[string, string]>,
46
) => {
57
try {
68
headers.forEach(([name, value]) => {
7-
response.headers.append(name, value);
9+
if (SET_HEADERS.has(name.toLowerCase())) {
10+
response.headers.set(name, value);
11+
} else {
12+
response.headers.append(name, value);
13+
}
814
});
915
} catch {
1016
// Ignore immutable headers

0 commit comments

Comments
 (0)