Monorepo for Aesthetic.Computer aesthetic.computer
at main 46 lines 1.4 kB view raw
1#!/usr/bin/env node 2// help - reverse proxy to NanoClaw running on macbook 3// 4// Proxies all requests to a local port where an SSH reverse tunnel 5// from the macbook exposes NanoClaw's HTTP Help channel. 6// 7// SSH tunnel (run on macbook): 8// ssh -R 3005:localhost:3004 root@help.aesthetic.computer -N -o ServerAliveInterval=30 9// 10// This proxy: :3004 (Caddy) → :3005 (SSH tunnel → macbook NanoClaw) 11 12import "dotenv/config"; 13import http from "http"; 14 15const PORT = parseInt(process.env.PORT || "3004", 10); 16const BACKEND_PORT = parseInt(process.env.BACKEND_PORT || "3005", 10); 17const BACKEND_HOST = process.env.BACKEND_HOST || "127.0.0.1"; 18 19const server = http.createServer((req, res) => { 20 const options = { 21 hostname: BACKEND_HOST, 22 port: BACKEND_PORT, 23 path: req.url, 24 method: req.method, 25 headers: req.headers, 26 }; 27 28 const proxy = http.request(options, (proxyRes) => { 29 res.writeHead(proxyRes.statusCode, proxyRes.headers); 30 proxyRes.pipe(res, { end: true }); 31 }); 32 33 proxy.on("error", (err) => { 34 console.error(`proxy error: ${err.message}`); 35 if (!res.headersSent) { 36 res.writeHead(502, { "Content-Type": "application/json" }); 37 res.end(JSON.stringify({ error: "NanoClaw backend unreachable. Is the SSH tunnel running?" })); 38 } 39 }); 40 41 req.pipe(proxy, { end: true }); 42}); 43 44server.listen(PORT, () => { 45 console.log(`help proxy listening on :${PORT}${BACKEND_HOST}:${BACKEND_PORT}`); 46});