167 lines
4.6 KiB
TypeScript
167 lines
4.6 KiB
TypeScript
import * as path from 'path';
|
|
import { tap, expect } from '@git.zone/tstest/tapbundle';
|
|
|
|
import { SmartProxy } from '../ts/proxies/smart-proxy/index.js';
|
|
import {
|
|
createHttpRoute,
|
|
createHttpsTerminateRoute,
|
|
createHttpsPassthroughRoute,
|
|
createHttpToHttpsRedirect,
|
|
createCompleteHttpsServer,
|
|
createLoadBalancerRoute,
|
|
createApiRoute,
|
|
createWebSocketRoute
|
|
} from '../ts/proxies/smart-proxy/utils/route-helpers.js';
|
|
import type { IRouteConfig } from '../ts/proxies/smart-proxy/models/route-types.js';
|
|
|
|
// Test to demonstrate various route configurations using the new helpers
|
|
tap.test('Route-based configuration examples', async (tools) => {
|
|
// Example 1: HTTP-only configuration
|
|
const httpOnlyRoute = createHttpRoute(
|
|
'http.example.com',
|
|
{
|
|
host: 'localhost',
|
|
port: 3000
|
|
},
|
|
{
|
|
name: 'Basic HTTP Route'
|
|
}
|
|
);
|
|
|
|
console.log('HTTP-only route created successfully:', httpOnlyRoute.name);
|
|
expect(httpOnlyRoute.action.type).toEqual('forward');
|
|
expect(httpOnlyRoute.match.domains).toEqual('http.example.com');
|
|
|
|
// Example 2: HTTPS Passthrough (SNI) configuration
|
|
const httpsPassthroughRoute = createHttpsPassthroughRoute(
|
|
'pass.example.com',
|
|
{
|
|
host: ['10.0.0.1', '10.0.0.2'], // Round-robin target IPs
|
|
port: 443
|
|
},
|
|
{
|
|
name: 'HTTPS Passthrough Route'
|
|
}
|
|
);
|
|
|
|
expect(httpsPassthroughRoute).toBeTruthy();
|
|
expect(httpsPassthroughRoute.action.tls?.mode).toEqual('passthrough');
|
|
expect(Array.isArray(httpsPassthroughRoute.action.target?.host)).toBeTrue();
|
|
|
|
// Example 3: HTTPS Termination to HTTP Backend
|
|
const terminateToHttpRoute = createHttpsTerminateRoute(
|
|
'secure.example.com',
|
|
{
|
|
host: 'localhost',
|
|
port: 8080
|
|
},
|
|
{
|
|
certificate: 'auto',
|
|
name: 'HTTPS Termination to HTTP Backend'
|
|
}
|
|
);
|
|
|
|
// Create the HTTP to HTTPS redirect for this domain
|
|
const httpToHttpsRedirect = createHttpToHttpsRedirect(
|
|
'secure.example.com',
|
|
443,
|
|
{
|
|
name: 'HTTP to HTTPS Redirect for secure.example.com'
|
|
}
|
|
);
|
|
|
|
expect(terminateToHttpRoute).toBeTruthy();
|
|
expect(terminateToHttpRoute.action.tls?.mode).toEqual('terminate');
|
|
expect(httpToHttpsRedirect.action.type).toEqual('socket-handler');
|
|
|
|
// Example 4: Load Balancer with HTTPS
|
|
const loadBalancerRoute = createLoadBalancerRoute(
|
|
'proxy.example.com',
|
|
['internal-api-1.local', 'internal-api-2.local'],
|
|
8443,
|
|
{
|
|
tls: {
|
|
mode: 'terminate-and-reencrypt',
|
|
certificate: 'auto'
|
|
},
|
|
name: 'Load Balanced HTTPS Route'
|
|
}
|
|
);
|
|
|
|
expect(loadBalancerRoute).toBeTruthy();
|
|
expect(loadBalancerRoute.action.tls?.mode).toEqual('terminate-and-reencrypt');
|
|
expect(Array.isArray(loadBalancerRoute.action.target?.host)).toBeTrue();
|
|
|
|
// Example 5: API Route
|
|
const apiRoute = createApiRoute(
|
|
'api.example.com',
|
|
'/api',
|
|
{ host: 'localhost', port: 8081 },
|
|
{
|
|
name: 'API Route',
|
|
useTls: true,
|
|
addCorsHeaders: true
|
|
}
|
|
);
|
|
|
|
expect(apiRoute.action.type).toEqual('forward');
|
|
expect(apiRoute.match.path).toBeTruthy();
|
|
|
|
// Example 6: Complete HTTPS Server with HTTP Redirect
|
|
const httpsServerRoutes = createCompleteHttpsServer(
|
|
'complete.example.com',
|
|
{
|
|
host: 'localhost',
|
|
port: 8080
|
|
},
|
|
{
|
|
certificate: 'auto',
|
|
name: 'Complete HTTPS Server'
|
|
}
|
|
);
|
|
|
|
expect(Array.isArray(httpsServerRoutes)).toBeTrue();
|
|
expect(httpsServerRoutes.length).toEqual(2); // HTTPS route and HTTP redirect
|
|
expect(httpsServerRoutes[0].action.tls?.mode).toEqual('terminate');
|
|
expect(httpsServerRoutes[1].action.type).toEqual('socket-handler');
|
|
|
|
// Example 7: Static File Server - removed (use nginx/apache behind proxy)
|
|
|
|
// Example 8: WebSocket Route
|
|
const webSocketRoute = createWebSocketRoute(
|
|
'ws.example.com',
|
|
'/ws',
|
|
{ host: 'localhost', port: 8082 },
|
|
{
|
|
useTls: true,
|
|
name: 'WebSocket Route'
|
|
}
|
|
);
|
|
|
|
expect(webSocketRoute.action.type).toEqual('forward');
|
|
expect(webSocketRoute.action.websocket?.enabled).toBeTrue();
|
|
|
|
// Create a SmartProxy instance with all routes
|
|
const allRoutes: IRouteConfig[] = [
|
|
httpOnlyRoute,
|
|
httpsPassthroughRoute,
|
|
terminateToHttpRoute,
|
|
httpToHttpsRedirect,
|
|
loadBalancerRoute,
|
|
apiRoute,
|
|
...httpsServerRoutes,
|
|
webSocketRoute
|
|
];
|
|
|
|
// We're not actually starting the SmartProxy in this test,
|
|
// just verifying that the configuration is valid
|
|
const smartProxy = new SmartProxy({
|
|
routes: allRoutes
|
|
});
|
|
|
|
// Just verify that all routes are configured correctly
|
|
console.log(`Created ${allRoutes.length} example routes`);
|
|
expect(allRoutes.length).toEqual(9); // One less without static file route
|
|
});
|
|
|
|
export default tap.start(); |