agent-orchestrator/packages/web/scripts/dev-next-proxy.mjs

80 lines
2.3 KiB
JavaScript

import { createServer } from "node:http";
import { createConnection } from "node:net";
import next from "next";
const port = Number.parseInt(process.env.PORT ?? "3000", 10);
const hostname = process.env.HOST ?? "0.0.0.0";
const app = next({ dev: true, dir: process.cwd(), hostname, port });
const handle = app.getRequestHandler();
function getTerminalProxyTarget(requestUrl) {
const url = new URL(requestUrl ?? "/", "ws://localhost");
if (url.pathname === "/ao-terminal-mux") {
url.pathname = "/mux";
return `${url.pathname}${url.search}`;
}
if (url.pathname.startsWith("/ao-terminal/")) {
url.pathname = url.pathname.slice("/ao-terminal".length);
return `${url.pathname}${url.search}`;
}
return null;
}
function proxyTerminalUpgrade(request, socket, head) {
const targetPath = getTerminalProxyTarget(request.url);
if (!targetPath) return false;
const directTerminalPort = Number.parseInt(process.env.DIRECT_TERMINAL_PORT ?? "14801", 10);
const upstream = createConnection({ host: "127.0.0.1", port: directTerminalPort });
upstream.on("connect", () => {
const headers = Object.entries(request.headers)
.flatMap(([name, value]) => {
if (Array.isArray(value)) return value.map((item) => `${name}: ${item}`);
return value === undefined ? [] : [`${name}: ${value}`];
})
.join("\r\n");
upstream.write(`GET ${targetPath} HTTP/${request.httpVersion}\r\n${headers}\r\n\r\n`);
if (head.length > 0) upstream.write(head);
socket.pipe(upstream).pipe(socket);
});
upstream.on("error", () => {
socket.destroy();
});
socket.on("error", () => {
upstream.destroy();
});
return true;
}
await app.prepare();
const handleUpgrade = typeof app.getUpgradeHandler === "function" ? app.getUpgradeHandler() : null;
const server = createServer((req, res) => {
void handle(req, res);
});
server.on("upgrade", (request, socket, head) => {
if (proxyTerminalUpgrade(request, socket, head)) {
return;
}
if (handleUpgrade) {
void handleUpgrade(request, socket, head);
} else {
socket.destroy();
}
});
server.listen(port, hostname, () => {
process.stdout.write(`[next] ready on http://${hostname}:${port}\n`);
});
function shutdown() {
server.close(() => process.exit(0));
}
process.on("SIGINT", shutdown);
process.on("SIGTERM", shutdown);