function parseRange(encoded) { var _a, _b; if (encoded === null) { return; } const parts = (_b = (_a = encoded.split("bytes=")[1]) === null || _a === void 0 ? void 0 : _a.split("-")) !== null && _b !== void 0 ? _b : []; if (parts.length !== 2) { throw new Error( "Not supported to skip specifying the beginning/ending byte at this time", ); } return { offset: Number(parts[0]), end: Number(parts[1]), length: Number(parts[1]) + 1 - Number(parts[0]), }; } function objectNotFound(objectName) { return new Response( `
R2 object "${objectName}" not found`, { status: 404, headers: { "content-type": "text/html; charset=UTF-8", }, }, ); } export default { async fetch(request, env) { var _a, _b, _c; const url = new URL(request.url); const objectName = url.pathname.slice(1); console.log(`${request.method} object ${objectName}: ${request.url}`); if (request.method === "GET" || request.method === "HEAD") { if (objectName === "") { return new Response("Forbidden", { status: 403 }); } if (request.method === "GET") { const range = parseRange(request.headers.get("range")); const object = await env.CF_WORKERS_R2.get(objectName, { range, onlyIf: request.headers, }); if (object === null) { return objectNotFound(objectName); } const headers = new Headers(); object.writeHttpMetadata(headers); headers.set("etag", object.httpEtag); if (range) { headers.set( "content-range", `bytes ${range.offset}-${range.end}/${object.size}`, ); } const status = object.body ? (range ? 206 : 200) : 304; return new Response(object.body, { headers, status, }); } const object = await env.CF_WORKERS_R2.head(objectName); if (object === null) { return objectNotFound(objectName); } const headers = new Headers(); object.writeHttpMetadata(headers); headers.set("etag", object.httpEtag); return new Response(null, { headers, }); } if (request.method === "PUT" || request.method == "POST") { const object = await env.CF_WORKERS_R2.put(objectName, request.body, { httpMetadata: request.headers, }); return new Response(null, { headers: { etag: object.httpEtag, }, }); } if (request.method === "DELETE") { await env.CF_WORKERS_R2.delete(url.pathname.slice(1)); return new Response(); } return new Response(`Unsupported method`, { status: 400, }); }, };