← back to Quadrille Showroom

proto/proxy-server.cjs

56 lines

/* proto-only static + proxy server for v9-walkin.html
   Serves /Users/.../proto/ at root and proxies /api + /gen-tiles + /gen-rooms
   to the showroom backend on 127.0.0.1:7690 so textures/data are same-origin
   (the backend sends no CORS headers; WebGL textures must be same-origin).
   Touches nothing in public/ or shared app files. */
const http = require('http');
const fs = require('fs');
const path = require('path');

const ROOT = __dirname;
const BACKEND = { host: '127.0.0.1', port: 7690 };
const PORT = process.env.PROTO_PORT ? Number(process.env.PROTO_PORT) : 7699;

const MIME = {
  '.html': 'text/html; charset=utf-8',
  '.js': 'text/javascript; charset=utf-8',
  '.css': 'text/css; charset=utf-8',
  '.json': 'application/json; charset=utf-8',
  '.png': 'image/png',
  '.jpg': 'image/jpeg',
  '.jpeg': 'image/jpeg',
  '.svg': 'image/svg+xml',
};

function proxy(req, res) {
  const opts = {
    host: BACKEND.host, port: BACKEND.port,
    method: req.method, path: req.url, headers: { ...req.headers, host: `${BACKEND.host}:${BACKEND.port}` },
  };
  const up = http.request(opts, (r) => {
    res.writeHead(r.statusCode || 502, r.headers);
    r.pipe(res);
  });
  up.on('error', (e) => { res.writeHead(502); res.end('proxy error: ' + e.message); });
  req.pipe(up);
}

const server = http.createServer((req, res) => {
  const url = req.url.split('?')[0];
  if (url.startsWith('/api/') || url.startsWith('/gen-tiles/') || url.startsWith('/gen-rooms/')) {
    return proxy(req, res);
  }
  let rel = url === '/' ? '/v9-walkin.html' : url;
  const file = path.join(ROOT, path.normalize(rel).replace(/^(\.\.[/\\])+/, ''));
  if (!file.startsWith(ROOT)) { res.writeHead(403); return res.end('forbidden'); }
  fs.readFile(file, (err, buf) => {
    if (err) { res.writeHead(404); return res.end('not found: ' + rel); }
    res.writeHead(200, { 'Content-Type': MIME[path.extname(file)] || 'application/octet-stream' });
    res.end(buf);
  });
});

server.listen(PORT, '127.0.0.1', () => {
  console.log(`[proto] walk-in room: http://127.0.0.1:${PORT}/  (proxying api/tiles -> ${BACKEND.host}:${BACKEND.port})`);
});