update
This commit is contained in:
parent
ab1ea95070
commit
30ff3b7d8a
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"expiryDate": "2025-08-27T10:55:18.793Z",
|
"expiryDate": "2025-08-27T12:49:18.738Z",
|
||||||
"issueDate": "2025-05-29T10:55:18.793Z",
|
"issueDate": "2025-05-29T12:49:18.738Z",
|
||||||
"savedAt": "2025-05-29T10:55:18.795Z"
|
"savedAt": "2025-05-29T12:49:18.740Z"
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ tap.test('should defer certificate provisioning until after ports are listening'
|
|||||||
// Create proxy with ACME certificate requirement
|
// Create proxy with ACME certificate requirement
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
useHttpProxy: [acmePort],
|
useHttpProxy: [acmePort],
|
||||||
httpProxyPort: 8844,
|
httpProxyPort: 8845, // Use different port to avoid conflicts
|
||||||
acme: {
|
acme: {
|
||||||
email: 'test@test.local',
|
email: 'test@test.local',
|
||||||
useProduction: false,
|
useProduction: false,
|
||||||
@ -56,21 +56,12 @@ tap.test('should defer certificate provisioning until after ports are listening'
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Track certificate provisioning
|
// Track that we created a certificate manager and SmartProxy will call provisionAllCertificates
|
||||||
const originalProvisionAll = proxy['certManager'] ?
|
let certManagerCreated = false;
|
||||||
proxy['certManager']['provisionAllCertificates'] : null;
|
|
||||||
|
|
||||||
if (proxy['certManager']) {
|
// Override createCertificateManager to set up our tracking
|
||||||
proxy['certManager']['provisionAllCertificates'] = async function() {
|
const originalCreateCertManager = (proxy as any).createCertificateManager;
|
||||||
operationLog.push('Starting certificate provisioning');
|
(proxy as any).certManagerCreated = false;
|
||||||
// Check if port 80 is listening
|
|
||||||
if (!port80Listening) {
|
|
||||||
operationLog.push('ERROR: Certificate provisioning started before ports ready');
|
|
||||||
}
|
|
||||||
// Don't actually provision certificates in the test
|
|
||||||
operationLog.push('Certificate provisioning completed');
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mock certificate manager to avoid real ACME initialization
|
// Mock certificate manager to avoid real ACME initialization
|
||||||
(proxy as any).createCertificateManager = async function() {
|
(proxy as any).createCertificateManager = async function() {
|
||||||
@ -81,17 +72,21 @@ tap.test('should defer certificate provisioning until after ports are listening'
|
|||||||
setGlobalAcmeDefaults: () => {},
|
setGlobalAcmeDefaults: () => {},
|
||||||
setAcmeStateManager: () => {},
|
setAcmeStateManager: () => {},
|
||||||
initialize: async () => {
|
initialize: async () => {
|
||||||
|
operationLog.push('Certificate manager initialized');
|
||||||
|
},
|
||||||
|
provisionAllCertificates: async () => {
|
||||||
operationLog.push('Starting certificate provisioning');
|
operationLog.push('Starting certificate provisioning');
|
||||||
if (!port80Listening) {
|
if (!port80Listening) {
|
||||||
operationLog.push('ERROR: Certificate provisioning started before ports ready');
|
operationLog.push('ERROR: Certificate provisioning started before ports ready');
|
||||||
}
|
}
|
||||||
operationLog.push('Certificate provisioning completed');
|
operationLog.push('Certificate provisioning completed');
|
||||||
},
|
},
|
||||||
provisionAllCertificates: async () => {},
|
|
||||||
stop: async () => {},
|
stop: async () => {},
|
||||||
getAcmeOptions: () => ({ email: 'test@test.local', useProduction: false }),
|
getAcmeOptions: () => ({ email: 'test@test.local', useProduction: false }),
|
||||||
getState: () => ({ challengeRouteActive: false })
|
getState: () => ({ challengeRouteActive: false })
|
||||||
};
|
};
|
||||||
|
certManagerCreated = true;
|
||||||
|
(proxy as any).certManager = mockCertManager;
|
||||||
return mockCertManager;
|
return mockCertManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,7 +115,7 @@ tap.test('should have ACME challenge route ready before certificate provisioning
|
|||||||
|
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
useHttpProxy: [8080],
|
useHttpProxy: [8080],
|
||||||
httpProxyPort: 8844,
|
httpProxyPort: 8846, // Use different port to avoid conflicts
|
||||||
acme: {
|
acme: {
|
||||||
email: 'test@test.local',
|
email: 'test@test.local',
|
||||||
useProduction: false,
|
useProduction: false,
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
||||||
import { SmartProxy } from '../ts/index.js';
|
|
||||||
import * as net from 'net';
|
|
||||||
|
|
||||||
tap.test('basic forward action should work correctly', async (t) => {
|
|
||||||
t.timeout(10000);
|
|
||||||
|
|
||||||
// Create a simple echo server as the target
|
|
||||||
const targetServer = net.createServer((socket) => {
|
|
||||||
console.log('Target server: Client connected');
|
|
||||||
socket.write('Hello from target server\n');
|
|
||||||
|
|
||||||
socket.on('data', (data) => {
|
|
||||||
console.log(`Target server received: ${data.toString().trim()}`);
|
|
||||||
socket.write(`Echo: ${data}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
socket.on('error', (err) => {
|
|
||||||
console.error('Target server socket error:', err);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise<void>((resolve) => {
|
|
||||||
targetServer.listen(7777, '127.0.0.1', () => {
|
|
||||||
console.log('Target server listening on port 7777');
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Create SmartProxy with forward route
|
|
||||||
const proxy = new SmartProxy({
|
|
||||||
enableDetailedLogging: true,
|
|
||||||
routes: [{
|
|
||||||
name: 'test-forward',
|
|
||||||
match: { ports: 7778 },
|
|
||||||
action: {
|
|
||||||
type: 'forward',
|
|
||||||
target: { host: '127.0.0.1', port: 7777 }
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
await proxy.start();
|
|
||||||
console.log('Proxy started on port 7778');
|
|
||||||
|
|
||||||
// Test the connection
|
|
||||||
const client = new net.Socket();
|
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
let received = '';
|
|
||||||
|
|
||||||
let testMessageSent = false;
|
|
||||||
|
|
||||||
client.on('data', (data) => {
|
|
||||||
received += data.toString();
|
|
||||||
console.log('Client received:', data.toString().trim());
|
|
||||||
|
|
||||||
if (received.includes('Hello from target server') && !testMessageSent) {
|
|
||||||
// Send test data only once
|
|
||||||
testMessageSent = true;
|
|
||||||
client.write('Test message\n');
|
|
||||||
} else if (received.includes('Echo: Test message')) {
|
|
||||||
// Test successful
|
|
||||||
client.end();
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
client.on('error', reject);
|
|
||||||
|
|
||||||
client.connect(7778, '127.0.0.1', () => {
|
|
||||||
console.log('Client connected to proxy');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add timeout
|
|
||||||
setTimeout(() => {
|
|
||||||
reject(new Error('Test timeout - no response received'));
|
|
||||||
}, 5000);
|
|
||||||
});
|
|
||||||
|
|
||||||
await proxy.stop();
|
|
||||||
targetServer.close();
|
|
||||||
|
|
||||||
console.log('Test completed successfully');
|
|
||||||
});
|
|
||||||
|
|
||||||
tap.start();
|
|
@ -97,7 +97,7 @@ tap.test('regular forward route should work correctly', async () => {
|
|||||||
await smartProxy.stop();
|
await smartProxy.stop();
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.skip('NFTables forward route should not terminate connections (requires root)', async () => {
|
tap.skip.test('NFTables forward route should not terminate connections (requires root)', async () => {
|
||||||
smartProxy = new SmartProxy({
|
smartProxy = new SmartProxy({
|
||||||
routes: [{
|
routes: [{
|
||||||
id: 'nftables-test',
|
id: 'nftables-test',
|
||||||
|
@ -40,7 +40,8 @@ tap.test('should detect and forward non-TLS connections on useHttpProxy ports',
|
|||||||
isTLS: false
|
isTLS: false
|
||||||
}),
|
}),
|
||||||
initiateCleanupOnce: () => {},
|
initiateCleanupOnce: () => {},
|
||||||
cleanupConnection: () => {}
|
cleanupConnection: () => {},
|
||||||
|
getConnectionCount: () => 1
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mock route manager that returns a matching route
|
// Mock route manager that returns a matching route
|
||||||
@ -127,7 +128,8 @@ tap.test('should handle TLS connections normally', async (tapTest) => {
|
|||||||
tlsHandshakeComplete: false
|
tlsHandshakeComplete: false
|
||||||
}),
|
}),
|
||||||
initiateCleanupOnce: () => {},
|
initiateCleanupOnce: () => {},
|
||||||
cleanupConnection: () => {}
|
cleanupConnection: () => {},
|
||||||
|
getConnectionCount: () => 1
|
||||||
};
|
};
|
||||||
|
|
||||||
const mockTlsManager = {
|
const mockTlsManager = {
|
||||||
|
@ -10,11 +10,11 @@ tap.test('should detect and forward non-TLS connections on HttpProxy ports', asy
|
|||||||
|
|
||||||
// Create a SmartProxy instance first
|
// Create a SmartProxy instance first
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
useHttpProxy: [8080],
|
useHttpProxy: [8081], // Use different port to avoid conflicts
|
||||||
httpProxyPort: 8844,
|
httpProxyPort: 8847, // Use different port to avoid conflicts
|
||||||
routes: [{
|
routes: [{
|
||||||
name: 'test-http-forward',
|
name: 'test-http-forward',
|
||||||
match: { ports: 8080 },
|
match: { ports: 8081 },
|
||||||
action: {
|
action: {
|
||||||
type: 'forward',
|
type: 'forward',
|
||||||
target: { host: 'localhost', port: 8181 }
|
target: { host: 'localhost', port: 8181 }
|
||||||
@ -47,8 +47,8 @@ tap.test('should detect and forward non-TLS connections on HttpProxy ports', asy
|
|||||||
const client = new net.Socket();
|
const client = new net.Socket();
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
client.connect(8080, 'localhost', () => {
|
client.connect(8081, 'localhost', () => {
|
||||||
console.log('Client connected to proxy on port 8080');
|
console.log('Client connected to proxy on port 8081');
|
||||||
// Send a non-TLS HTTP request
|
// Send a non-TLS HTTP request
|
||||||
client.write('GET / HTTP/1.1\r\nHost: test.local\r\n\r\n');
|
client.write('GET / HTTP/1.1\r\nHost: test.local\r\n\r\n');
|
||||||
resolve();
|
resolve();
|
||||||
@ -67,7 +67,9 @@ tap.test('should detect and forward non-TLS connections on HttpProxy ports', asy
|
|||||||
client.destroy();
|
client.destroy();
|
||||||
await proxy.stop();
|
await proxy.stop();
|
||||||
|
|
||||||
// Restore original method
|
// Wait a bit to ensure port is released
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
// Restore original method
|
// Restore original method
|
||||||
(proxy as any).httpProxyBridge.forwardToHttpProxy = originalForward;
|
(proxy as any).httpProxyBridge.forwardToHttpProxy = originalForward;
|
||||||
});
|
});
|
||||||
@ -94,12 +96,12 @@ tap.test('should properly detect non-TLS connections on HttpProxy ports', async
|
|||||||
let httpProxyForwardCalled = false;
|
let httpProxyForwardCalled = false;
|
||||||
|
|
||||||
const proxy = new SmartProxy({
|
const proxy = new SmartProxy({
|
||||||
useHttpProxy: [8080],
|
useHttpProxy: [8082], // Use different port to avoid conflicts
|
||||||
httpProxyPort: 8844,
|
httpProxyPort: 8848, // Use different port to avoid conflicts
|
||||||
routes: [{
|
routes: [{
|
||||||
name: 'test-route',
|
name: 'test-route',
|
||||||
match: {
|
match: {
|
||||||
ports: 8080
|
ports: 8082
|
||||||
},
|
},
|
||||||
action: {
|
action: {
|
||||||
type: 'forward',
|
type: 'forward',
|
||||||
@ -126,7 +128,7 @@ tap.test('should properly detect non-TLS connections on HttpProxy ports', async
|
|||||||
const client = new net.Socket();
|
const client = new net.Socket();
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
client.connect(8080, 'localhost', () => {
|
client.connect(8082, 'localhost', () => {
|
||||||
console.log('Connected to proxy');
|
console.log('Connected to proxy');
|
||||||
client.write('GET / HTTP/1.1\r\nHost: test.local\r\n\r\n');
|
client.write('GET / HTTP/1.1\r\nHost: test.local\r\n\r\n');
|
||||||
resolve();
|
resolve();
|
||||||
@ -147,8 +149,11 @@ tap.test('should properly detect non-TLS connections on HttpProxy ports', async
|
|||||||
targetServer.close(() => resolve());
|
targetServer.close(() => resolve());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Wait a bit to ensure port is released
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 100));
|
||||||
|
|
||||||
// Restore original method
|
// Restore original method
|
||||||
proxy['httpProxyBridge'].forwardToHttpProxy = originalForward;
|
proxy['httpProxyBridge'].forwardToHttpProxy = originalForward;
|
||||||
});
|
});
|
||||||
|
|
||||||
tap.start();
|
export default tap.start();
|
@ -1,59 +0,0 @@
|
|||||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
|
||||||
import * as net from 'net';
|
|
||||||
import { SmartProxy } from '../ts/index.js';
|
|
||||||
|
|
||||||
tap.test('simple socket handler test', async () => {
|
|
||||||
const proxy = new SmartProxy({
|
|
||||||
routes: [{
|
|
||||||
name: 'simple-handler',
|
|
||||||
match: {
|
|
||||||
ports: 8888
|
|
||||||
// No domains restriction - will match all connections on this port
|
|
||||||
},
|
|
||||||
action: {
|
|
||||||
type: 'socket-handler',
|
|
||||||
socketHandler: (socket, context) => {
|
|
||||||
console.log('Handler called!');
|
|
||||||
socket.write('HELLO\n');
|
|
||||||
socket.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
enableDetailedLogging: true
|
|
||||||
});
|
|
||||||
|
|
||||||
await proxy.start();
|
|
||||||
|
|
||||||
// Test connection
|
|
||||||
const client = new net.Socket();
|
|
||||||
let response = '';
|
|
||||||
|
|
||||||
client.on('data', (data) => {
|
|
||||||
response += data.toString();
|
|
||||||
});
|
|
||||||
|
|
||||||
await new Promise<void>((resolve, reject) => {
|
|
||||||
client.connect(8888, 'localhost', () => {
|
|
||||||
console.log('Connected');
|
|
||||||
// Send some initial data to trigger the handler
|
|
||||||
client.write('test\n');
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
client.on('error', reject);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for response
|
|
||||||
await new Promise(resolve => {
|
|
||||||
client.on('close', () => {
|
|
||||||
console.log('Connection closed');
|
|
||||||
resolve(undefined);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log('Got response:', response);
|
|
||||||
expect(response).toEqual('HELLO\n');
|
|
||||||
|
|
||||||
await proxy.stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
export default tap.start();
|
|
Loading…
x
Reference in New Issue
Block a user