-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.mjs
More file actions
52 lines (48 loc) · 1.25 KB
/
server.mjs
File metadata and controls
52 lines (48 loc) · 1.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// Basic static file server
import * as http from "node:http";
import * as fs from "node:fs";
import * as path from "node:path";
const contentTypes = new Map([
[".ico", "image/x-icon"],
[".png", "image/png"],
[".html", "text/html"],
[".css", "text/css"],
[".mjs", "text/javascript"],
[".webmanifest", "application/manifest+json"],
]);
class NotFoundError extends Error {}
export function createServer() {
return http.createServer(handleRequest);
}
async function handleRequest(req, res) {
try {
let file = path.join("static", req.url);
if (req.url.endsWith("/")) {
file = path.join(file, "index.html");
}
const ext = path.extname(file);
const contentType = contentTypes.get(ext);
if (!contentType) {
throw new NotFoundError();
}
const allowed = await fs.promises
.access(file)
.then(() => true)
.catch(() => false);
if (!allowed) {
throw new NotFoundError();
}
const stream = fs.createReadStream(file);
res.writeHead(200, { "Content-Type": contentType });
stream.pipe(res);
} catch (error) {
if (error instanceof NotFoundError) {
res.writeHead(404);
res.end();
} else {
console.error(error);
res.writeHead(500);
res.end();
}
}
}