fix(smartproxy): Improve error handling in forwarding connection handler and refine domain matching logic
This commit is contained in:
131
test/test.forwarding-fix-verification.ts
Normal file
131
test/test.forwarding-fix-verification.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as net from 'net';
|
||||
import { SmartProxy } from '../ts/proxies/smart-proxy/smart-proxy.js';
|
||||
|
||||
let testServer: net.Server;
|
||||
let smartProxy: SmartProxy;
|
||||
|
||||
tap.test('setup test server', async () => {
|
||||
// Create a test server that handles connections
|
||||
testServer = await new Promise<net.Server>((resolve) => {
|
||||
const server = net.createServer((socket) => {
|
||||
console.log('Test server: Client connected');
|
||||
socket.write('Welcome from test server\n');
|
||||
|
||||
socket.on('data', (data) => {
|
||||
console.log(`Test server received: ${data.toString().trim()}`);
|
||||
socket.write(`Echo: ${data}`);
|
||||
});
|
||||
|
||||
socket.on('close', () => {
|
||||
console.log('Test server: Client disconnected');
|
||||
});
|
||||
});
|
||||
|
||||
server.listen(6789, () => {
|
||||
console.log('Test server listening on port 6789');
|
||||
resolve(server);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
tap.test('regular forward route should work correctly', async () => {
|
||||
smartProxy = new SmartProxy({
|
||||
routes: [{
|
||||
id: 'test-forward',
|
||||
name: 'Test Forward Route',
|
||||
match: { ports: 7890 },
|
||||
action: {
|
||||
type: 'forward',
|
||||
target: { host: 'localhost', port: 6789 }
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
await smartProxy.start();
|
||||
|
||||
// Create a client connection
|
||||
const client = await new Promise<net.Socket>((resolve, reject) => {
|
||||
const socket = net.connect(7890, 'localhost', () => {
|
||||
console.log('Client connected to proxy');
|
||||
resolve(socket);
|
||||
});
|
||||
socket.on('error', reject);
|
||||
});
|
||||
|
||||
// Test data exchange
|
||||
const response = await new Promise<string>((resolve) => {
|
||||
client.on('data', (data) => {
|
||||
resolve(data.toString());
|
||||
});
|
||||
});
|
||||
|
||||
expect(response).toContain('Welcome from test server');
|
||||
|
||||
// Send data through proxy
|
||||
client.write('Test message');
|
||||
|
||||
const echo = await new Promise<string>((resolve) => {
|
||||
client.once('data', (data) => {
|
||||
resolve(data.toString());
|
||||
});
|
||||
});
|
||||
|
||||
expect(echo).toContain('Echo: Test message');
|
||||
|
||||
client.end();
|
||||
await smartProxy.stop();
|
||||
});
|
||||
|
||||
tap.test('NFTables forward route should not terminate connections', async () => {
|
||||
smartProxy = new SmartProxy({
|
||||
routes: [{
|
||||
id: 'nftables-test',
|
||||
name: 'NFTables Test Route',
|
||||
match: { ports: 7891 },
|
||||
action: {
|
||||
type: 'forward',
|
||||
forwardingEngine: 'nftables',
|
||||
target: { host: 'localhost', port: 6789 }
|
||||
}
|
||||
}]
|
||||
});
|
||||
|
||||
await smartProxy.start();
|
||||
|
||||
// Create a client connection
|
||||
const client = await new Promise<net.Socket>((resolve, reject) => {
|
||||
const socket = net.connect(7891, 'localhost', () => {
|
||||
console.log('Client connected to NFTables proxy');
|
||||
resolve(socket);
|
||||
});
|
||||
socket.on('error', reject);
|
||||
});
|
||||
|
||||
// With NFTables, the connection should stay open at the application level
|
||||
// even though forwarding happens at kernel level
|
||||
let connectionClosed = false;
|
||||
client.on('close', () => {
|
||||
connectionClosed = true;
|
||||
});
|
||||
|
||||
// Wait a bit to ensure connection isn't immediately closed
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
expect(connectionClosed).toBe(false);
|
||||
console.log('NFTables connection stayed open as expected');
|
||||
|
||||
client.end();
|
||||
await smartProxy.stop();
|
||||
});
|
||||
|
||||
tap.test('cleanup', async () => {
|
||||
if (testServer) {
|
||||
testServer.close();
|
||||
}
|
||||
if (smartProxy) {
|
||||
await smartProxy.stop();
|
||||
}
|
||||
});
|
||||
|
||||
export default tap.start();
|
Reference in New Issue
Block a user