183 lines
5.1 KiB
TypeScript
183 lines
5.1 KiB
TypeScript
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
import * as net from 'net';
|
|
|
|
// Unit test for the HTTP forwarding fix
|
|
tap.test('should forward non-TLS connections on HttpProxy ports', async (tapTest) => {
|
|
// Test configuration
|
|
const testPort = 8080;
|
|
const httpProxyPort = 8844;
|
|
|
|
// Track forwarding logic
|
|
let forwardedToHttpProxy = false;
|
|
let setupDirectConnection = false;
|
|
|
|
// Create mock settings
|
|
const mockSettings = {
|
|
useHttpProxy: [testPort],
|
|
httpProxyPort: httpProxyPort,
|
|
routes: [{
|
|
name: 'test-route',
|
|
match: { ports: testPort },
|
|
action: {
|
|
type: 'forward',
|
|
target: { host: 'localhost', port: 8181 }
|
|
}
|
|
}]
|
|
};
|
|
|
|
// Create mock connection record
|
|
const mockRecord = {
|
|
id: 'test-connection',
|
|
localPort: testPort,
|
|
remoteIP: '127.0.0.1',
|
|
isTLS: false
|
|
};
|
|
|
|
// Mock HttpProxyBridge
|
|
const mockHttpProxyBridge = {
|
|
getHttpProxy: () => ({ available: true }),
|
|
forwardToHttpProxy: async () => {
|
|
forwardedToHttpProxy = true;
|
|
}
|
|
};
|
|
|
|
// Test the logic from handleForwardAction
|
|
const route = mockSettings.routes[0];
|
|
const action = route.action as any;
|
|
|
|
// Simulate the fixed logic
|
|
if (!action.tls) {
|
|
// No TLS settings - check if this port should use HttpProxy
|
|
const isHttpProxyPort = mockSettings.useHttpProxy?.includes(mockRecord.localPort);
|
|
|
|
if (isHttpProxyPort && mockHttpProxyBridge.getHttpProxy()) {
|
|
// Forward non-TLS connections to HttpProxy if configured
|
|
console.log(`Using HttpProxy for non-TLS connection on port ${mockRecord.localPort}`);
|
|
await mockHttpProxyBridge.forwardToHttpProxy();
|
|
} else {
|
|
// Basic forwarding
|
|
console.log(`Using basic forwarding`);
|
|
setupDirectConnection = true;
|
|
}
|
|
}
|
|
|
|
// Verify the fix works correctly
|
|
expect(forwardedToHttpProxy).toEqual(true);
|
|
expect(setupDirectConnection).toEqual(false);
|
|
|
|
console.log('Test passed: Non-TLS connections on HttpProxy ports are forwarded correctly');
|
|
});
|
|
|
|
// Test that non-HttpProxy ports still use direct connection
|
|
tap.test('should use direct connection for non-HttpProxy ports', async (tapTest) => {
|
|
let forwardedToHttpProxy = false;
|
|
let setupDirectConnection = false;
|
|
|
|
const mockSettings = {
|
|
useHttpProxy: [80, 443], // Different ports
|
|
httpProxyPort: 8844,
|
|
routes: [{
|
|
name: 'test-route',
|
|
match: { ports: 8080 }, // Not in useHttpProxy
|
|
action: {
|
|
type: 'forward',
|
|
target: { host: 'localhost', port: 8181 }
|
|
}
|
|
}]
|
|
};
|
|
|
|
const mockRecord = {
|
|
id: 'test-connection-2',
|
|
localPort: 8080, // Not in useHttpProxy
|
|
remoteIP: '127.0.0.1',
|
|
isTLS: false
|
|
};
|
|
|
|
const mockHttpProxyBridge = {
|
|
getHttpProxy: () => ({ available: true }),
|
|
forwardToHttpProxy: async () => {
|
|
forwardedToHttpProxy = true;
|
|
}
|
|
};
|
|
|
|
const route = mockSettings.routes[0];
|
|
const action = route.action as any;
|
|
|
|
// Test the logic
|
|
if (!action.tls) {
|
|
const isHttpProxyPort = mockSettings.useHttpProxy?.includes(mockRecord.localPort);
|
|
|
|
if (isHttpProxyPort && mockHttpProxyBridge.getHttpProxy()) {
|
|
console.log(`Using HttpProxy for non-TLS connection on port ${mockRecord.localPort}`);
|
|
await mockHttpProxyBridge.forwardToHttpProxy();
|
|
} else {
|
|
console.log(`Using basic forwarding for port ${mockRecord.localPort}`);
|
|
setupDirectConnection = true;
|
|
}
|
|
}
|
|
|
|
// Verify port 8080 uses direct connection when not in useHttpProxy
|
|
expect(forwardedToHttpProxy).toEqual(false);
|
|
expect(setupDirectConnection).toEqual(true);
|
|
|
|
console.log('Test passed: Non-HttpProxy ports use direct connection');
|
|
});
|
|
|
|
// Test HTTP-01 ACME challenge scenario
|
|
tap.test('should handle ACME HTTP-01 challenges on port 80 with HttpProxy', async (tapTest) => {
|
|
let forwardedToHttpProxy = false;
|
|
|
|
const mockSettings = {
|
|
useHttpProxy: [80], // Port 80 configured for HttpProxy
|
|
httpProxyPort: 8844,
|
|
acme: {
|
|
port: 80,
|
|
email: 'test@example.com'
|
|
},
|
|
routes: [{
|
|
name: 'acme-challenge',
|
|
match: {
|
|
ports: 80,
|
|
paths: ['/.well-known/acme-challenge/*']
|
|
},
|
|
action: {
|
|
type: 'forward',
|
|
target: { host: 'localhost', port: 8080 }
|
|
}
|
|
}]
|
|
};
|
|
|
|
const mockRecord = {
|
|
id: 'acme-connection',
|
|
localPort: 80,
|
|
remoteIP: '127.0.0.1',
|
|
isTLS: false
|
|
};
|
|
|
|
const mockHttpProxyBridge = {
|
|
getHttpProxy: () => ({ available: true }),
|
|
forwardToHttpProxy: async () => {
|
|
forwardedToHttpProxy = true;
|
|
}
|
|
};
|
|
|
|
const route = mockSettings.routes[0];
|
|
const action = route.action as any;
|
|
|
|
// Test the fix for ACME HTTP-01 challenges
|
|
if (!action.tls) {
|
|
const isHttpProxyPort = mockSettings.useHttpProxy?.includes(mockRecord.localPort);
|
|
|
|
if (isHttpProxyPort && mockHttpProxyBridge.getHttpProxy()) {
|
|
console.log(`Using HttpProxy for ACME challenge on port ${mockRecord.localPort}`);
|
|
await mockHttpProxyBridge.forwardToHttpProxy();
|
|
}
|
|
}
|
|
|
|
// Verify HTTP-01 challenges on port 80 go through HttpProxy
|
|
expect(forwardedToHttpProxy).toEqual(true);
|
|
|
|
console.log('Test passed: ACME HTTP-01 challenges on port 80 use HttpProxy');
|
|
});
|
|
|
|
tap.start(); |