forked from mahoudeau/allmiibo-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserve.mjs
More file actions
59 lines (51 loc) · 1.9 KB
/
Copy pathserve.mjs
File metadata and controls
59 lines (51 loc) · 1.9 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
53
54
55
56
57
58
59
#!/usr/bin/env node
// Minimal static server for the web/ directory, using only Node built-ins.
// Web Bluetooth needs a secure context, and http://localhost qualifies —
// opening the page as file:// will not work.
//
// node serve.mjs [port]
import { createServer } from 'node:http';
import { readFile, stat } from 'node:fs/promises';
import { join, normalize, extname } from 'node:path';
import { fileURLToPath } from 'node:url';
const ROOT = join(fileURLToPath(new URL('.', import.meta.url)), 'web');
const PORT = Number(process.argv[2]) || 8080;
const TYPES = {
'.html': 'text/html; charset=utf-8',
'.js': 'text/javascript; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.png': 'image/png',
'.webmanifest': 'application/manifest+json',
'.woff2': 'font/woff2',
'.woff': 'font/woff',
'.ttf': 'font/ttf',
};
const server = createServer(async (req, res) => {
try {
const url = new URL(req.url, `http://${req.headers.host}`);
// normalize() collapses ".." so requests cannot escape ROOT.
const rel = normalize(decodeURIComponent(url.pathname)).replace(/^(\.\.[/\\])+/, '');
let path = join(ROOT, rel);
if (!path.startsWith(ROOT)) {
res.writeHead(403).end('Forbidden');
return;
}
const info = await stat(path).catch(() => null);
if (info?.isDirectory()) path = join(path, 'index.html');
const body = await readFile(path);
res.writeHead(200, {
'Content-Type': TYPES[extname(path)] || 'application/octet-stream',
'Cache-Control': 'no-store',
});
res.end(body);
} catch {
res.writeHead(404, { 'Content-Type': 'text/plain; charset=utf-8' }).end('Not found');
}
});
server.listen(PORT, '127.0.0.1', () => {
console.log(`allmiibo-sync probe: http://localhost:${PORT}/`);
console.log('Open it in Chrome or Edge, then press Connect.');
});