Skip to content

Commit 9eedcab

Browse files
committed
feat(server/workers): serve b2 assets
1 parent 129b361 commit 9eedcab

File tree

1 file changed

+59
-2
lines changed

1 file changed

+59
-2
lines changed

web/workers/main.ts

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// environment variables
2+
declare const B2_URL: string;
3+
14
import { getAssetFromKV } from "@cloudflare/kv-asset-handler";
25

36
addEventListener("fetch", (event) => {
@@ -9,10 +12,19 @@ addEventListener("fetch", (event) => {
912
});
1013

1114
async function handleEvent(event: FetchEvent): Promise<Response> {
12-
const url = new URL(event.request.url);
15+
const request = event.request;
16+
const url = new URL(request.url);
1317

1418
if (url.pathname.startsWith("/api")) {
15-
return fetch(event.request);
19+
const response = await fetch(request);
20+
21+
return hanldeEtag(request, response);
22+
}
23+
24+
if (url.pathname.startsWith("/thumbnail")) {
25+
const response = await getAssetFromB2(url.pathname.slice(10));
26+
27+
return hanldeEtag(request, response);
1628
}
1729

1830
return getAssetFromKV(event).catch(() =>
@@ -21,3 +33,48 @@ async function handleEvent(event: FetchEvent): Promise<Response> {
2133
})
2234
);
2335
}
36+
37+
async function getAssetFromB2(key: string): Promise<Response> {
38+
const response = await fetch(`${B2_URL}${key}`, {
39+
cf: { cacheEverything: true, cacheTtl: 60 },
40+
});
41+
42+
const headers = new Headers(response.headers);
43+
44+
if (!response.ok) {
45+
headers.set("cache-control", "max-age=0, no-cache, no-store");
46+
47+
return new Response(null, {
48+
status: 404,
49+
headers,
50+
statusText: "Not Found",
51+
});
52+
}
53+
54+
headers.set("cache-control", "public, max-age=3600");
55+
if (headers.has("x-bz-upload-timestamp")) {
56+
headers.set("etag", headers.get("x-bz-upload-timestamp") as string);
57+
}
58+
headers.delete("x-bz-content-sha1");
59+
headers.delete("x-bz-file-id");
60+
headers.delete("x-bz-file-name");
61+
headers.delete("x-bz-upload-timestamp");
62+
63+
return new Response(response.body, { headers });
64+
}
65+
66+
function hanldeEtag(request: Request, response: Response): Response {
67+
if (
68+
response.headers.has("etag") &&
69+
request.headers.has("if-none-match") &&
70+
request.headers.get("if-none-match") === response.headers.get("etag")
71+
) {
72+
return new Response(null, {
73+
status: 304,
74+
headers: response.headers,
75+
statusText: "Not Modified",
76+
});
77+
}
78+
79+
return response;
80+
}

0 commit comments

Comments
 (0)