ci: deploy isolated GPL staging stack
This commit is contained in:
parent
4d75d44a78
commit
f90cf7d2da
6 changed files with 224 additions and 1 deletions
85
workers/cdn/src/index.ts
Normal file
85
workers/cdn/src/index.ts
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
interface Env {
|
||||
BUCKET: R2Bucket;
|
||||
}
|
||||
|
||||
const baseHeaders = (): Headers => {
|
||||
const headers = new Headers();
|
||||
headers.set("Access-Control-Allow-Origin", "*");
|
||||
headers.set("Cross-Origin-Resource-Policy", "cross-origin");
|
||||
headers.set("X-Content-Type-Options", "nosniff");
|
||||
headers.set("X-Robots-Tag", "noindex, nofollow");
|
||||
return headers;
|
||||
};
|
||||
|
||||
export default {
|
||||
async fetch(request: Request, env: Env): Promise<Response> {
|
||||
if (request.method === "OPTIONS") {
|
||||
const headers = baseHeaders();
|
||||
headers.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS");
|
||||
headers.set("Access-Control-Allow-Headers", "Range, If-None-Match");
|
||||
headers.set("Access-Control-Max-Age", "86400");
|
||||
return new Response(null, { status: 204, headers });
|
||||
}
|
||||
if (request.method !== "GET" && request.method !== "HEAD") {
|
||||
return new Response("Method Not Allowed", {
|
||||
status: 405,
|
||||
headers: baseHeaders(),
|
||||
});
|
||||
}
|
||||
|
||||
const url = new URL(request.url);
|
||||
let key: string;
|
||||
try {
|
||||
key = decodeURIComponent(url.pathname.replace(/^\/+/, ""));
|
||||
} catch {
|
||||
return new Response("Bad Request", { status: 400, headers: baseHeaders() });
|
||||
}
|
||||
if (!key) {
|
||||
return Response.json(
|
||||
{ ok: true, service: "pcbjam-cdn-staging" },
|
||||
{ headers: baseHeaders() },
|
||||
);
|
||||
}
|
||||
|
||||
const object = await env.BUCKET.get(key, {
|
||||
range: request.headers,
|
||||
});
|
||||
if (!object) {
|
||||
return new Response("Not Found", { status: 404, headers: baseHeaders() });
|
||||
}
|
||||
|
||||
const headers = baseHeaders();
|
||||
object.writeHttpMetadata(headers);
|
||||
headers.set("ETag", object.httpEtag);
|
||||
headers.set("Accept-Ranges", "bytes");
|
||||
|
||||
if (request.headers.get("If-None-Match") === object.httpEtag) {
|
||||
return new Response(null, { status: 304, headers });
|
||||
}
|
||||
|
||||
let status = 200;
|
||||
if (object.range) {
|
||||
const suffix = "suffix" in object.range ? object.range.suffix : undefined;
|
||||
const length = suffix
|
||||
? Math.min(suffix, object.size)
|
||||
: "length" in object.range && object.range.length !== undefined
|
||||
? object.range.length
|
||||
: object.size - ("offset" in object.range ? (object.range.offset ?? 0) : 0);
|
||||
const offset = suffix
|
||||
? object.size - length
|
||||
: "offset" in object.range
|
||||
? (object.range.offset ?? 0)
|
||||
: 0;
|
||||
headers.set("Content-Range", `bytes ${offset}-${offset + length - 1}/${object.size}`);
|
||||
headers.set("Content-Length", String(length));
|
||||
status = 206;
|
||||
} else {
|
||||
headers.set("Content-Length", String(object.size));
|
||||
}
|
||||
|
||||
return new Response(request.method === "HEAD" ? null : object.body, {
|
||||
status,
|
||||
headers,
|
||||
});
|
||||
},
|
||||
};
|
||||
12
workers/cdn/wrangler.staging.jsonc
Normal file
12
workers/cdn/wrangler.staging.jsonc
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/wrangler/config-schema.json",
|
||||
"name": "pcbjam-cdn-staging",
|
||||
"main": "src/index.ts",
|
||||
"compatibility_date": "2026-07-27",
|
||||
"workers_dev": true,
|
||||
"preview_urls": false,
|
||||
"observability": { "enabled": true },
|
||||
"r2_buckets": [
|
||||
{ "binding": "BUCKET", "bucket_name": "pcbjam-cdn-staging" }
|
||||
]
|
||||
}
|
||||
Loading…
Reference in a new issue