Skip to content

Commit

Permalink
speculation-rules
Browse files Browse the repository at this point in the history
  • Loading branch information
dbushell committed Dec 6, 2024
1 parent b958678 commit 9215fa2
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 3 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,5 @@ public/*
!public/favicon.ico
!public/manifest.webmanifest
!public/robots.txt
!public/speculation-rules.json
!public/sw.js
20 changes: 20 additions & 0 deletions components/my-layout.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,25 @@
</head>
<body>
<ssr-slot />
<script type="speculationrules">
{
"prefetch": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "immediate"
}
],
"prerender": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "conservative"
}
]
}
</script>
</body>
</html>
4 changes: 4 additions & 0 deletions public/_headers
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
permissions-policy: browsing-topics=(),interest-cohort=()
referrer-policy: same-origin
x-robots-tag: noai, noimageai
speculation-rules: "/speculation-rules.json?v=%DEPLOY_HASH%"

/assets/*
x-robots-tag: noindex
Expand All @@ -24,3 +25,6 @@

/rss.xml
content-type: application/xml; charset=utf-8

/speculation-rules.json
content-type: application/speculationrules+json
18 changes: 18 additions & 0 deletions public/speculation-rules.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"prefetch": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "immediate"
}
],
"prerender": [
{
"where": {
"href_matches": "/*"
},
"eagerness": "conservative"
}
]
}
3 changes: 2 additions & 1 deletion routes/(headers)/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { authorized } from "@src/shared.ts";
export const pattern = "/_headers";
export const order = 9999;

export const GET: HyperHandle = async ({ request, response }) => {
export const GET: HyperHandle = async ({ request, response, platform }) => {
if (!authorized(request)) {
return null;
}
Expand All @@ -17,6 +17,7 @@ export const GET: HyperHandle = async ({ request, response }) => {
`default-src 'self'`;
let body = await response.text();
body = body.replace("%CONTENT_SECURITY_POLICY%", csp);
body = body.replaceAll("%DEPLOY_HASH%", platform.deployHash);
response = new Response(body, response);
response.headers.set("content-length", body.length.toString());
return response;
Expand Down
12 changes: 11 additions & 1 deletion src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ export const middleware: HyperHandle = ({ request, platform }) => {
["x-content-type-options", "nosniff"],
["permissions-policy", "browsing-topics=(),interest-cohort=()"],
["referrer-policy", "same-origin"],
["speculation-rules", '"/speculation-rules.json"'],
["x-img-src", "data:"],
// TODO - generate? - Hash for Logo inline styles
["x-style-src", `'sha256-kXLrG8qzlz0MMhgMvdF9YD6tca5CYXeC1iFSTHDsO8w='`],
// Allow WASM (search)
// Inline speculation rules
["x-script-src", `'sha256-mdvvVa+pyyzYFTF9Q4Ik06GKIwN21+J9j1qzXSStiU4='`],
// "this.rel=`stylesheet`"
["x-script-src", `'unsafe-hashes'`],
["x-script-src", `'sha256-BGXQRYq/G9+8wEtSYSbQRnDRz8/8apfi/W/CUBMh9w0='`],
// Allow search WASM and fallback
["x-script-src", `'wasm-unsafe-eval'`],
["x-form-action", `https://duckduckgo.com`],
];
Expand All @@ -32,6 +38,10 @@ export const middleware: HyperHandle = ({ request, platform }) => {
pageHeaders.push(["x-style-src", `'sha256-${style.hash}'`]);
});

if (url.pathname.startsWith("/speculation-rules.json")) {
pageHeaders.push(["content-type", "application/speculationrules+json"]);
}

// CORS headers
if (/\/(rss|sitemap)\.xml$/.test(url.pathname)) {
pageHeaders.push(["access-control-allow-origin", "*"]);
Expand Down
8 changes: 7 additions & 1 deletion src/shared.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
const SET_HEADERS = new Set(["content-type"]);

export const appendHeaders = (
response: Response,
headers: Array<[string, string]>,
) => {
try {
headers.forEach(([name, value]) => {
response.headers.append(name, value);
if (SET_HEADERS.has(name.toLowerCase())) {
response.headers.set(name, value);
} else {
response.headers.append(name, value);
}
});
} catch {
// Ignore immutable headers
Expand Down

0 comments on commit 9215fa2

Please sign in to comment.