46 lines
1.4 KiB
JavaScript
46 lines
1.4 KiB
JavaScript
import http from "node:http";
|
|
import { readFile } from "node:fs/promises";
|
|
import { fileURLToPath } from "node:url";
|
|
import path from "node:path";
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const port = process.env.PORT ? Number(process.env.PORT) : 8080;
|
|
|
|
const server = http.createServer(async (req, res) => {
|
|
try {
|
|
const url = new URL(
|
|
req.url ?? "/",
|
|
`http://${req.headers.host ?? "localhost"}`,
|
|
);
|
|
const pathname = url.pathname === "/" ? "/index.html" : url.pathname;
|
|
|
|
// Only serve files from this folder; keep it intentionally simple.
|
|
const safePath = path.normalize(pathname).replace(/^(\.\.(\/|\\|$))+/, "");
|
|
const filePath = path.join(__dirname, safePath);
|
|
|
|
const data = await readFile(filePath);
|
|
const ext = path.extname(filePath).toLowerCase();
|
|
|
|
const contentType =
|
|
ext === ".html"
|
|
? "text/html; charset=utf-8"
|
|
: ext === ".js"
|
|
? "text/javascript; charset=utf-8"
|
|
: ext === ".css"
|
|
? "text/css; charset=utf-8"
|
|
: "application/octet-stream";
|
|
|
|
res.writeHead(200, { "Content-Type": contentType });
|
|
res.end(data);
|
|
} catch {
|
|
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
|
|
res.end("Not found");
|
|
}
|
|
});
|
|
|
|
server.listen(port, () => {
|
|
// Intentionally minimal output.
|
|
console.log(`Keyboard game running on http://localhost:${port}`);
|
|
});
|