Files
short-video-viral-replicator/agent-studio-mini/sandbox/web.mjs
T

27 lines
1.7 KiB
JavaScript

import http from "node:http";
import { readFile } from "node:fs/promises";
import path from "node:path";
const root = path.resolve("apps/web/dist");
http.createServer(async (req, res) => {
if (!/^localhost(?::\d+)?$|^127\.0\.0\.1(?::\d+)?$/.test(req.headers.host ?? "")) { res.writeHead(403).end(); return; }
if (req.headers.origin && req.headers.origin !== `http://${req.headers.host}`) { res.writeHead(403).end(); return; }
if (req.url?.startsWith("/api/") || req.url === "/health") {
const upstream = http.request({ hostname: "127.0.0.1", port: 3001, path: req.url, method: req.method, headers: { ...req.headers, host: "127.0.0.1:3001" } }, response => {
res.writeHead(response.statusCode ?? 502, response.headers); response.pipe(res);
});
upstream.on("error", () => { if (!res.headersSent) res.writeHead(502); res.end(); });
res.on("close", () => upstream.destroy());
req.pipe(upstream); return;
}
try {
if (req.method !== "GET" && req.method !== "HEAD") { res.writeHead(405).end(); return; }
const pathname = decodeURIComponent(new URL(req.url ?? "/", "http://localhost").pathname);
const file = path.resolve(root, `.${pathname === "/" ? "/index.html" : pathname}`);
if (!file.startsWith(root + path.sep)) { res.writeHead(403).end(); return; }
const bytes = await readFile(file);
const types = { ".html": "text/html", ".js": "text/javascript", ".css": "text/css", ".svg": "image/svg+xml" };
res.writeHead(200, { "content-type": types[path.extname(file)] ?? "application/octet-stream", "x-content-type-options": "nosniff" });
res.end(req.method === "HEAD" ? undefined : bytes);
} catch { res.writeHead(404).end(); }
}).listen(5173, "0.0.0.0");