webchat: improve logging and static serving

This commit is contained in:
Peter Steinberger
2025-12-10 15:32:29 +00:00
parent 4db69c8eac
commit 3796882d22
4 changed files with 81 additions and 25 deletions

View File

@@ -30,6 +30,11 @@ const fetchText = (url: string) =>
.on("error", reject);
});
const fetchHeaders = (url: string) =>
new Promise<http.IncomingHttpHeaders>((resolve, reject) => {
http.get(url, (res) => resolve(res.headers)).on("error", reject);
});
describe("webchat server (static only)", () => {
test("serves index.html over loopback", { timeout: 8000 }, async () => {
const port = await getFreePort();
@@ -41,4 +46,17 @@ describe("webchat server (static only)", () => {
await stopWebChatServer();
}
});
test("serves bundled JS with module-friendly content type", async () => {
const port = await getFreePort();
await startWebChatServer(port);
try {
const headers = await fetchHeaders(
`http://127.0.0.1:${port}/webchat.bundle.js`,
);
expect(headers["content-type"]).toContain("application/javascript");
} finally {
await stopWebChatServer();
}
});
});

View File

@@ -38,6 +38,28 @@ function notFound(res: http.ServerResponse) {
res.end("Not Found");
}
function contentTypeForExt(ext: string) {
switch (ext) {
case ".html":
return "text/html";
case ".js":
return "application/javascript";
case ".css":
return "text/css";
case ".json":
case ".map":
return "application/json";
case ".svg":
return "image/svg+xml";
case ".png":
return "image/png";
case ".ico":
return "image/x-icon";
default:
return "application/octet-stream";
}
}
export async function startWebChatServer(
port = WEBCHAT_DEFAULT_PORT,
): Promise<WebChatServerState | null> {
@@ -67,15 +89,7 @@ export async function startWebChatServer(
}
const data = fs.readFileSync(filePath);
const ext = path.extname(filePath).toLowerCase();
const type =
ext === ".html"
? "text/html"
: ext === ".js"
? "application/javascript"
: ext === ".css"
? "text/css"
: "application/octet-stream";
res.setHeader("Content-Type", type);
res.setHeader("Content-Type", contentTypeForExt(ext));
res.end(data);
return;
}
@@ -93,7 +107,8 @@ export async function startWebChatServer(
const filePath = path.join(root, relPath);
if (filePath.startsWith(root) && fs.existsSync(filePath)) {
const data = fs.readFileSync(filePath);
res.setHeader("Content-Type", "application/octet-stream");
const ext = path.extname(filePath).toLowerCase();
res.setHeader("Content-Type", contentTypeForExt(ext));
res.end(data);
return;
}
@@ -121,7 +136,6 @@ export async function startWebChatServer(
}
state = { server, port };
logDebug(`webchat server listening on 127.0.0.1:${port}`);
return state;
}