pages-runtime.worker.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. export default {
  2. async fetch(request, env) {
  3. const url = new URL(request.url);
  4. let pathname = url.pathname.replace(/\/{2,}/g, "/");
  5. // Serve admin UI at root /
  6. if (pathname === "/") {
  7. return serveFromKV(env, "admin", "index.html");
  8. }
  9. // Normalize /site -> /site/
  10. if (!pathname.endsWith("/") && pathname.split("/").length === 2) {
  11. const redirectUrl = new URL(url);
  12. redirectUrl.pathname = pathname + "/";
  13. return Response.redirect(redirectUrl.toString(), 301);
  14. }
  15. // Split path
  16. const parts = pathname.replace(/^\/+/, "").split("/");
  17. if (!parts[0]) {
  18. return new Response("Not Found", { status: 404 });
  19. }
  20. const site = parts[0];
  21. const filePath =
  22. parts.length === 1 || parts[1] === ""
  23. ? "index.html"
  24. : parts.slice(1).join("/");
  25. return serveFromKV(env, site, filePath);
  26. },
  27. };
  28. async function serveFromKV(env, site, filePath) {
  29. const key = `site:${site}:${filePath}`;
  30. const content = await env.PAGES_KV.get(key, {
  31. type: "arrayBuffer",
  32. });
  33. if (!content) {
  34. return new Response("Not Found", { status: 404 });
  35. }
  36. return new Response(content, {
  37. headers: {
  38. "Content-Type": contentType(filePath),
  39. "Cache-Control": "public, max-age=300",
  40. },
  41. });
  42. }
  43. function contentType(path) {
  44. if (path.endsWith(".html")) return "text/html; charset=utf-8";
  45. if (path.endsWith(".css")) return "text/css; charset=utf-8";
  46. if (path.endsWith(".js")) return "application/javascript; charset=utf-8";
  47. if (path.endsWith(".json")) return "application/json; charset=utf-8";
  48. if (path.endsWith(".png")) return "image/png";
  49. if (path.endsWith(".jpg") || path.endsWith(".jpeg")) return "image/jpeg";
  50. if (path.endsWith(".svg")) return "image/svg+xml";
  51. if (path.endsWith(".ico")) return "image/x-icon";
  52. if (path.endsWith(".woff")) return "font/woff";
  53. if (path.endsWith(".woff2")) return "font/woff2";
  54. return "application/octet-stream";
  55. }