import http from 'node:http'; import { readFile, realpath, stat } from 'node:fs/promises'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const root = fileURLToPath(new URL('../', import.meta.url)); const mime = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', '.css': 'text/css; charset=utf-8', '.json': 'application/json', '.png': 'image/png', '.jpg': 'image/jpeg', '.svg': 'image/svg+xml', '.wav': 'audio/wav', '.mp3': 'audio/mpeg' }; export function createServer() { return http.createServer(async (req, res) => { try { if (!['GET', 'HEAD'].includes(req.method)) { res.writeHead(405); res.end('Method not allowed'); return; } const url = new URL(req.url, 'http://localhost'); const pathname = decodeURIComponent(url.pathname); // Serve only the product surface and explicitly owned fixture subtree. const route = pathname === '/' ? '/public/index.html' : pathname; const mount = ['/public/', '/src/', '/test-fixtures/'].find(prefix => route.startsWith(prefix)); if (!mount || route.includes('\\') || route.includes('\0')) throw new Error('Not found'); const base = await realpath(path.join(root, mount)); let candidate = await realpath(path.join(root, route)); const relative = path.relative(base, candidate); if (relative.startsWith('..') || path.isAbsolute(relative)) throw new Error('Not found'); if ((await stat(candidate)).isDirectory()) candidate = await realpath(path.join(candidate, 'index.html')); const finalRelative = path.relative(base, candidate); if (finalRelative.startsWith('..') || path.isAbsolute(finalRelative)) throw new Error('Not found'); const content = await readFile(candidate); res.writeHead(200, { 'Content-Type': mime[path.extname(candidate)] ?? 'application/octet-stream', 'Cache-Control': 'no-store', 'X-Content-Type-Options': 'nosniff', 'Content-Length': content.length }); res.end(req.method === 'HEAD' ? undefined : content); } catch { res.writeHead(404, { 'Content-Type': 'text/plain' }); res.end('Not found'); } }); } if (process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) { const port = Number(process.env.PORT ?? 4173); createServer().listen(port, '127.0.0.1', () => console.log(`XZBT-NGN: http://127.0.0.1:${port}`)); }