import { tap, expect } from '@git.zone/tstest/tapbundle'; import { SmartProxy } from '../ts/index.js'; import * as http from 'http'; tap.test('should forward HTTP connections on port 8080 to HttpProxy', async (tapTest) => { // Create a mock HTTP server to act as our target const targetPort = 8181; let receivedRequest = false; let receivedPath = ''; const targetServer = http.createServer((req, res) => { // Log request details for debugging console.log(`Target server received: ${req.method} ${req.url}`); receivedPath = req.url || ''; if (req.url === '/.well-known/acme-challenge/test-token') { receivedRequest = true; res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('test-challenge-response'); } else { res.writeHead(200); res.end('OK'); } }); await new Promise((resolve) => { targetServer.listen(targetPort, () => { console.log(`Target server listening on port ${targetPort}`); resolve(); }); }); // Create SmartProxy with port 8080 configured for HttpProxy const proxy = new SmartProxy({ useHttpProxy: [8080], // Enable HttpProxy for port 8080 httpProxyPort: 8844, enableDetailedLogging: true, routes: [{ name: 'test-route', match: { ports: 8080, domains: ['test.local'] }, action: { type: 'forward', target: { host: 'localhost', port: targetPort } } }] }); await proxy.start(); // Give the proxy a moment to fully initialize await new Promise(resolve => setTimeout(resolve, 500)); // Make an HTTP request to port 8080 const options = { hostname: 'localhost', port: 8080, path: '/.well-known/acme-challenge/test-token', method: 'GET', headers: { 'Host': 'test.local' } }; const response = await new Promise((resolve, reject) => { const req = http.request(options, (res) => resolve(res)); req.on('error', reject); req.end(); }); // Collect response data let responseData = ''; response.setEncoding('utf8'); response.on('data', chunk => responseData += chunk); await new Promise(resolve => response.on('end', resolve)); // Verify the request was properly forwarded expect(response.statusCode).toEqual(200); expect(receivedPath).toEqual('/.well-known/acme-challenge/test-token'); expect(responseData).toEqual('test-challenge-response'); expect(receivedRequest).toEqual(true); await proxy.stop(); await new Promise((resolve) => { targetServer.close(() => resolve()); }); }); tap.test('should handle basic HTTP request forwarding', async (tapTest) => { // Create a simple target server const targetPort = 8182; let receivedRequest = false; const targetServer = http.createServer((req, res) => { console.log(`Target received: ${req.method} ${req.url} from ${req.headers.host}`); receivedRequest = true; res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from target'); }); await new Promise((resolve) => { targetServer.listen(targetPort, () => { console.log(`Target server listening on port ${targetPort}`); resolve(); }); }); // Create a simple proxy without HttpProxy const proxy = new SmartProxy({ routes: [{ name: 'simple-forward', match: { ports: 8081, domains: ['test.local'] }, action: { type: 'forward', target: { host: 'localhost', port: targetPort } } }] }); await proxy.start(); await new Promise(resolve => setTimeout(resolve, 500)); // Make request const options = { hostname: 'localhost', port: 8081, path: '/test', method: 'GET', headers: { 'Host': 'test.local' } }; const response = await new Promise((resolve, reject) => { const req = http.request(options, (res) => resolve(res)); req.on('error', reject); req.end(); }); let responseData = ''; response.setEncoding('utf8'); response.on('data', chunk => responseData += chunk); await new Promise(resolve => response.on('end', resolve)); expect(response.statusCode).toEqual(200); expect(responseData).toEqual('Hello from target'); expect(receivedRequest).toEqual(true); await proxy.stop(); await new Promise((resolve) => { targetServer.close(() => resolve()); }); }); tap.start();