import { tap, expect } from '@git.zone/tstest/tapbundle'; import * as plugins from '../ts/plugins.js'; import { SmartProxy } from '../ts/index.js'; tap.test('should handle HTTP requests on port 80 for ACME challenges', async (tools) => { tools.timeout(10000); // Track HTTP requests that are handled const handledRequests: any[] = []; const settings = { routes: [ { name: 'acme-test-route', match: { ports: [18080], // Use high port to avoid permission issues path: '/.well-known/acme-challenge/*' }, action: { type: 'static' as const, handler: async (context) => { handledRequests.push({ path: context.path, method: context.method, headers: context.headers }); // Simulate ACME challenge response const token = context.path?.split('/').pop() || ''; return { status: 200, headers: { 'Content-Type': 'text/plain' }, body: `challenge-response-for-${token}` }; } } } ] }; const proxy = new SmartProxy(settings); // Mock NFTables manager (proxy as any).nftablesManager = { ensureNFTablesSetup: async () => {}, stop: async () => {} }; await proxy.start(); // Make an HTTP request to the challenge endpoint const response = await fetch('http://localhost:18080/.well-known/acme-challenge/test-token', { method: 'GET' }); // Verify response expect(response.status).toEqual(200); const body = await response.text(); expect(body).toEqual('challenge-response-for-test-token'); // Verify request was handled expect(handledRequests.length).toEqual(1); expect(handledRequests[0].path).toEqual('/.well-known/acme-challenge/test-token'); expect(handledRequests[0].method).toEqual('GET'); await proxy.stop(); }); tap.test('should parse HTTP headers correctly', async (tools) => { tools.timeout(10000); const capturedContext: any = {}; const settings = { routes: [ { name: 'header-test-route', match: { ports: [18081] }, action: { type: 'static' as const, handler: async (context) => { Object.assign(capturedContext, context); return { status: 200, headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ received: context.headers }) }; } } } ] }; const proxy = new SmartProxy(settings); // Mock NFTables manager (proxy as any).nftablesManager = { ensureNFTablesSetup: async () => {}, stop: async () => {} }; await proxy.start(); // Make request with custom headers const response = await fetch('http://localhost:18081/test', { method: 'POST', headers: { 'X-Custom-Header': 'test-value', 'User-Agent': 'test-agent' } }); expect(response.status).toEqual(200); const body = await response.json(); // Verify headers were parsed correctly expect(capturedContext.headers['x-custom-header']).toEqual('test-value'); expect(capturedContext.headers['user-agent']).toEqual('test-agent'); expect(capturedContext.method).toEqual('POST'); expect(capturedContext.path).toEqual('/test'); await proxy.stop(); }); tap.start();