about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorAlan Pearce2023-09-12 16:54:29 +0200
committerAlan Pearce2023-09-12 16:54:29 +0200
commit2f6152539c540697290ec73a7c1b50b9f2db88c6 (patch)
treec500b3dcb57c4a9c35a7c9e001e3e92b127253d2 /src
parent78439b16cc66532225e75c9aa40cf7c49cddc22d (diff)
downloadwebsite-2f6152539c540697290ec73a7c1b50b9f2db88c6.tar.lz
website-2f6152539c540697290ec73a7c1b50b9f2db88c6.tar.zst
website-2f6152539c540697290ec73a7c1b50b9f2db88c6.zip
Use own logic for static file serving
Diffstat (limited to 'src')
-rw-r--r--src/index.ts71
1 files changed, 65 insertions, 6 deletions
diff --git a/src/index.ts b/src/index.ts
index d8c9bf1..ec1c296 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,16 +1,75 @@
 import path from "node:path";
+import fs, { Stats } from "node:fs";
+import fsp from "node:fs/promises";
+import util from "node:util";
+
 import { withHtmlLiveReload } from "bun-html-live-reload";
-import serveStatic from "serve-static-bun";
+import containsPath from "contains-path";
 
 import readConfig from "./config";
 
-const base = Bun.argv.length > 2 ? Bun.argv[Bun.argv.length - 1] : ".";
+const base = "../website/";
+const publicDir = path.resolve(base, "public") + path.sep;
 
 const config = readConfig(base);
+const defaultHeaders = config.extra.headers;
+
+function getFilename(name: string): string {
+  return path.join(publicDir, `${name}`);
+}
+
+let files: Map<string, any> = new Map();
+
+function registerFile(pathname: string, absPath: string, stat: Stats): void {
+  pathname = "/" + (pathname === "." || pathname === "./" ? "" : pathname);
+
+  if (files.get(pathname) !== undefined) {
+    console.warn("File already registered:", pathname);
+  }
+  files.set(pathname, {
+    filename: absPath,
+    size: stat.size,
+    mtime: stat.mtime.toUTCString(),
+  });
+}
+
+function walkDirectory(root: string, dir: string) {
+  const absDir = path.join(root, dir);
+  for (let pathname of fs.readdirSync(absDir)) {
+    const relPath = path.join(dir, pathname);
+    const absPath = path.join(absDir, pathname);
+    const stat = fs.statSync(absPath);
+    if (stat.isDirectory()) {
+      walkDirectory(root, relPath + path.sep);
+    } else if (stat.isFile()) {
+      if (pathname === "index.html") {
+        registerFile(path.dirname(relPath), absPath, stat);
+        registerFile(path.dirname(relPath) + path.sep, absPath, stat);
+      }
+      registerFile(relPath, absPath, stat);
+    }
+  }
+}
+
+walkDirectory(publicDir, "");
 
 export default withHtmlLiveReload({
-  fetch: serveStatic(path.join(base, "public"), {
-    headers: config.extra.headers,
-    dotfiles: "allow",
-  }),
+  fetch: async function (request) {
+    const pathname = new URL(request.url).pathname;
+    if (files.has(pathname)) {
+      const file = files.get(pathname);
+      console.info("filename", file.filename);
+      return new Response(Bun.file(file.filename), {
+        headers: defaultHeaders,
+        status: 200,
+      });
+    }
+    return new Response(Bun.file(getFilename("404.html")), {
+      headers: Object.assign({}, defaultHeaders, {
+        "cache-control": "max-age=5, no-cache",
+      }),
+      status: 404,
+      statusText: "Not Found",
+    });
+  },
 });