ace_proxy.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const http = require('http');
  2. const targetPorts = [4534, 4474, 4454, 4494];
  3. targetPorts.forEach((targetPort) => {
  4. const proxyPort = parseInt(`${targetPort}5`);
  5. const server = http.createServer(async (req, res) => {
  6. // Construct the full URL using the host header
  7. const host = req.headers.host || 'localhost';
  8. const url = new URL(req.url, `http://${host}`);
  9. const target = `http://localhost:${targetPort}${url.pathname}${url.search}`;
  10. console.log(`\n[INCOMING] ${req.method} ${url.pathname}`);
  11. // 1. ECLIPSE TO ACE: Intercept headers and rewrite (e.g., 44545 -> 4454)
  12. const aceHeaders = new Headers();
  13. for (const [key, value] of Object.entries(req.headers)) {
  14. const strValue = String(value);
  15. const modifiedValue = strValue.replaceAll(`${targetPort}5`, targetPort.toString());
  16. aceHeaders.set(key, modifiedValue);
  17. if (strValue !== modifiedValue) {
  18. console.log(` -> [TO ACE] Modified Header '${key}': sent as ${modifiedValue}`);
  19. }
  20. }
  21. // Node.js streams the request body, so we need to buffer it manually if it exists
  22. let reqBody;
  23. if (req.method !== "GET" && req.method !== "HEAD") {
  24. const chunks = [];
  25. for await (const chunk of req) {
  26. chunks.push(chunk);
  27. }
  28. reqBody = Buffer.concat(chunks);
  29. }
  30. const init = {
  31. method: req.method,
  32. headers: aceHeaders,
  33. ...(reqBody && { body: reqBody })
  34. };
  35. try {
  36. const response = await fetch(target, init);
  37. console.log(`[ACE RESPONDED] Status: ${response.status}`);
  38. // Transfer headers to the Node response
  39. response.headers.forEach((value, key) => {
  40. // Drop content-length as our payload modification will change the size
  41. if (key.toLowerCase() !== "content-length") {
  42. res.setHeader(key, value);
  43. }
  44. });
  45. res.statusCode = response.status;
  46. res.statusMessage = response.statusText;
  47. // 2. ACE TO ECLIPSE: Intercept JSON payload and rewrite (e.g., 4454 -> 44545)
  48. const contentType = response.headers.get("content-type") || "";
  49. if (contentType.includes("application/json") || contentType.includes("text/")) {
  50. let bodyText = await response.text();
  51. // THE PROOF: Log exactly what ACE sends back BEFORE we touch it
  52. console.log(` -> [RAW ACE RESPONSE]: ${bodyText.substring(0, 250)}...`);
  53. if (bodyText.includes(targetPort.toString())) {
  54. console.log(` -> [INTERCEPT] Found port ${targetPort}. Rewriting to ${targetPort}5...`);
  55. bodyText = bodyText.replaceAll(`localhost:${targetPort}`, `localhost:${targetPort}5`);
  56. bodyText = bodyText.replaceAll(`127.0.0.1:${targetPort}`, `127.0.0.1:${targetPort}5`);
  57. // Log the payload AFTER the rewrite to confirm the change
  58. console.log(` -> [MODIFIED PAYLOAD]: ${bodyText.substring(0, 250)}...`);
  59. }
  60. res.end(bodyText);
  61. } else {
  62. // If it's an image, binary file, or other non-text format, handle it gracefully
  63. const arrayBuffer = await response.arrayBuffer();
  64. res.end(Buffer.from(arrayBuffer));
  65. }
  66. } catch (err) {
  67. console.error(`[ERROR]`, err);
  68. res.writeHead(502);
  69. res.end("Proxy Error");
  70. }
  71. });
  72. server.listen(proxyPort, () => {
  73. console.log(`Listening on ${proxyPort} -> Forwarding to ${targetPort}`);
  74. });
  75. });
  76. console.log(`2-Way Proxy Running. Check the terminal for RAW payload logs...`);