SPB Git

spb/earth-now Public License

earth-now.co — real-time planetary dashboard: live world metrics modeled, not streamed.

TypeScript 93% Shell 2.3% SQL 1.4% JavaScript 1.3% Dockerfile 1.2% CSS 0.8%
1.8 KB · 55 lines javascript
Raw Blame History
1/**2 * earth-now.co3 * Author:  Simon-Pierre Boucher4 * Contact: contact@spboucher.ai5 * File:    infra/proxy.mjs6 * Purpose: Zero-dependency reverse proxy (nginx.conf equivalent) — routes /api,/v1,/sse,/badge to the API, the rest to web; SSE-safe (no buffering)7 */89import http from "node:http";1011const PORT = Number(process.env.PROXY_PORT ?? 8080);12const API = { host: "127.0.0.1", port: Number(process.env.API_PORT ?? 4000) };13const WEB = { host: "127.0.0.1", port: Number(process.env.WEB_PORT ?? 4100) };1415const API_PREFIXES = ["/api", "/v1", "/sse", "/badge"];1617function targetFor(url) {18  return API_PREFIXES.some((p) => url === p || url.startsWith(`${p}/`) || url.startsWith(`${p}?`))19    ? API20    : WEB;21}2223const server = http.createServer((req, res) => {24  const target = targetFor(req.url ?? "/");25  const upstream = http.request(26    {27      host: target.host,28      port: target.port,29      path: req.url,30      method: req.method,31      headers: { ...req.headers, host: req.headers.host ?? "www.earth-now.co" },32    },33    (up) => {34      res.writeHead(up.statusCode ?? 502, up.headers);35      // pipe() flushes chunks as they arrive — SSE streams pass through unbuffered.36      up.pipe(res);37    },38  );39  upstream.on("error", () => {40    if (!res.headersSent) res.writeHead(502, { "content-type": "application/json" });41    res.end(JSON.stringify({ error: "upstream unavailable" }));42  });43  req.pipe(upstream);44  // If the client disconnects (closed SSE tab), tear down the upstream leg too.45  res.on("close", () => upstream.destroy());46});4748// Long-lived SSE connections: disable the default 5-minute socket timeout.49server.requestTimeout = 0;50server.headersTimeout = 60_000;5152server.listen(PORT, "127.0.0.1", () => {53  console.log(`earth-now proxy on 127.0.0.1:${PORT} → api :${API.port}, web :${WEB.port}`);54});55