v3: code quality and visual consistency pass (refactored all forms across the app), fixed filename-related upload bug
All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 47s

This commit is contained in:
khannurien
2026-06-26 22:20:07 +00:00
parent 26f5abfa4e
commit 73e0114bf7
30 changed files with 2369 additions and 2120 deletions

View File

@@ -5,6 +5,23 @@ import { DUMPS_DIR } from "../lib/upload.ts";
const router = new Router({ prefix: "/api/files" });
/**
* Builds an RFC 6266 `Content-Disposition` value that is always a valid
* ByteString. `headers.set` throws a TypeError if the value contains any
* character > U+00FF, so a filename with an emoji / accent / CJK character
* (e.g. an uploaded file) would otherwise crash the response. We provide an
* ASCII-only `filename="…"` fallback plus an RFC 5987 `filename*` with the
* full UTF-8 name for modern browsers.
*/
function contentDisposition(name: string): string {
const asciiFallback = name
.replace(/["\\]/g, "_")
.replace(/[^\x20-\x7e]/g, "_");
return `inline; filename="${asciiFallback}"; filename*=UTF-8''${
encodeURIComponent(name)
}`;
}
router.get("/:dumpId", async (ctx) => {
const { dumpId } = ctx.params;
@@ -36,7 +53,7 @@ router.get("/:dumpId", async (ctx) => {
ctx.response.headers.set("Content-Type", dump.fileMime);
ctx.response.headers.set(
"Content-Disposition",
`inline; filename="${dump.fileName}"`,
contentDisposition(dump.fileName),
);
ctx.response.headers.set("Accept-Ranges", "bytes");