import http from "node:http"; import { readFile } from "node:fs/promises"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const __dirname = dirname(fileURLToPath(import.meta.url)); const htmlPath = join(__dirname, "lucky-gift-test.html"); const port = Number(process.env.PORT || 8788); const upstreamBase = (process.env.LUCKY_GIFT_API_BASE || "http://127.0.0.1:13000").replace(/\/+$/, ""); function readBody(req) { return new Promise((resolve, reject) => { const chunks = []; req.on("data", (chunk) => chunks.push(chunk)); req.on("end", () => resolve(Buffer.concat(chunks))); req.on("error", reject); }); } function copyProxyHeaders(req) { const headers = new Headers(); for (const [key, value] of Object.entries(req.headers)) { if (!value) continue; const lower = key.toLowerCase(); if (["host", "origin", "referer", "connection", "content-length", "accept-encoding"].includes(lower)) continue; headers.set(key, Array.isArray(value) ? value.join(", ") : value); } headers.set("Accept-Encoding", "identity"); return headers; } async function proxyAPI(req, res) { const body = req.method === "GET" || req.method === "HEAD" ? undefined : await readBody(req); const upstream = await fetch(`${upstreamBase}${req.url}`, { method: req.method, headers: copyProxyHeaders(req), body, redirect: "manual", }); const responseBody = Buffer.from(await upstream.arrayBuffer()); res.writeHead(upstream.status, { "Content-Type": upstream.headers.get("content-type") || "application/octet-stream", "Cache-Control": "no-store", }); res.end(responseBody); } const server = http.createServer(async (req, res) => { try { if (req.method === "OPTIONS") { res.writeHead(204); res.end(); return; } if (req.url === "/" || req.url === "/lucky-gift-test.html") { const html = await readFile(htmlPath); res.writeHead(200, { "Content-Type": "text/html; charset=utf-8", "Cache-Control": "no-store", }); res.end(html); return; } if (req.url?.startsWith("/api/")) { await proxyAPI(req, res); return; } res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" }); res.end("not found"); } catch (err) { res.writeHead(502, { "Content-Type": "text/plain; charset=utf-8" }); res.end(err instanceof Error ? err.message : String(err)); } }); server.listen(port, "127.0.0.1", () => { console.log(`Lucky gift test page: http://127.0.0.1:${port}`); console.log(`Proxy upstream: ${upstreamBase}`); });