UNPKG

@push.rocks/smartproxy

Version:

A powerful proxy package with unified route-based configuration for high traffic management. Features include SSL/TLS support, flexible routing patterns, WebSocket handling, advanced security options, and automatic ACME certificate management.

172 lines 12.9 kB
import { ForwardingHandler } from '../handlers/base-handler.js'; import { HttpForwardingHandler } from '../handlers/http-handler.js'; import { HttpsPassthroughHandler } from '../handlers/https-passthrough-handler.js'; import { HttpsTerminateToHttpHandler } from '../handlers/https-terminate-to-http-handler.js'; import { HttpsTerminateToHttpsHandler } from '../handlers/https-terminate-to-https-handler.js'; /** * Factory for creating forwarding handlers based on the configuration type */ export class ForwardingHandlerFactory { /** * Create a forwarding handler based on the configuration * @param config The forwarding configuration * @returns The appropriate forwarding handler */ static createHandler(config) { // Create the appropriate handler based on the forwarding type switch (config.type) { case 'http-only': return new HttpForwardingHandler(config); case 'https-passthrough': return new HttpsPassthroughHandler(config); case 'https-terminate-to-http': return new HttpsTerminateToHttpHandler(config); case 'https-terminate-to-https': return new HttpsTerminateToHttpsHandler(config); default: // Type system should prevent this, but just in case: throw new Error(`Unknown forwarding type: ${config.type}`); } } /** * Apply default values to a forwarding configuration based on its type * @param config The original forwarding configuration * @returns A configuration with defaults applied */ static applyDefaults(config) { // Create a deep copy of the configuration const result = JSON.parse(JSON.stringify(config)); // Apply defaults based on forwarding type switch (config.type) { case 'http-only': // Set defaults for HTTP-only mode result.http = { enabled: true, ...config.http }; // Set default port and socket if not provided if (!result.port) { result.port = 80; } if (!result.socket) { result.socket = `/tmp/forwarding-${config.type}-${result.port}.sock`; } break; case 'https-passthrough': // Set defaults for HTTPS passthrough result.https = { forwardSni: true, ...config.https }; // SNI forwarding doesn't do HTTP result.http = { enabled: false, ...config.http }; // Set default port and socket if not provided if (!result.port) { result.port = 443; } if (!result.socket) { result.socket = `/tmp/forwarding-${config.type}-${result.port}.sock`; } break; case 'https-terminate-to-http': // Set defaults for HTTPS termination to HTTP result.https = { ...config.https }; // Support HTTP access by default in this mode result.http = { enabled: true, redirectToHttps: true, ...config.http }; // Enable ACME by default result.acme = { enabled: true, maintenance: true, ...config.acme }; // Set default port and socket if not provided if (!result.port) { result.port = 443; } if (!result.socket) { result.socket = `/tmp/forwarding-${config.type}-${result.port}.sock`; } break; case 'https-terminate-to-https': // Similar to terminate-to-http but with different target handling result.https = { ...config.https }; result.http = { enabled: true, redirectToHttps: true, ...config.http }; result.acme = { enabled: true, maintenance: true, ...config.acme }; // Set default port and socket if not provided if (!result.port) { result.port = 443; } if (!result.socket) { result.socket = `/tmp/forwarding-${config.type}-${result.port}.sock`; } break; } return result; } /** * Validate a forwarding configuration * @param config The configuration to validate * @throws Error if the configuration is invalid */ static validateConfig(config) { // Validate common properties if (!config.target) { throw new Error('Forwarding configuration must include a target'); } if (!config.target.host || (Array.isArray(config.target.host) && config.target.host.length === 0)) { throw new Error('Target must include a host or array of hosts'); } // Validate port if it's a number if (typeof config.target.port === 'number') { if (config.target.port <= 0 || config.target.port > 65535) { throw new Error('Target must include a valid port (1-65535)'); } } else if (config.target.port !== 'preserve' && typeof config.target.port !== 'function') { throw new Error('Target port must be a number, "preserve", or a function'); } // Type-specific validation switch (config.type) { case 'http-only': // HTTP-only needs http.enabled to be true if (config.http?.enabled === false) { throw new Error('HTTP-only forwarding must have HTTP enabled'); } break; case 'https-passthrough': // HTTPS passthrough doesn't support HTTP if (config.http?.enabled === true) { throw new Error('HTTPS passthrough does not support HTTP'); } // HTTPS passthrough doesn't work with ACME if (config.acme?.enabled === true) { throw new Error('HTTPS passthrough does not support ACME'); } break; case 'https-terminate-to-http': case 'https-terminate-to-https': // These modes support all options, nothing specific to validate break; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9yd2FyZGluZy1mYWN0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9yd2FyZGluZy9mYWN0b3J5L2ZvcndhcmRpbmctZmFjdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNoRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxnREFBZ0QsQ0FBQztBQUM3RixPQUFPLEVBQUUsNEJBQTRCLEVBQUUsTUFBTSxpREFBaUQsQ0FBQztBQUUvRjs7R0FFRztBQUNILE1BQU0sT0FBTyx3QkFBd0I7SUFDbkM7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxhQUFhLENBQUMsTUFBc0I7UUFDaEQsOERBQThEO1FBQzlELFFBQVEsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ3BCLEtBQUssV0FBVztnQkFDZCxPQUFPLElBQUkscUJBQXFCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFM0MsS0FBSyxtQkFBbUI7Z0JBQ3RCLE9BQU8sSUFBSSx1QkFBdUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUU3QyxLQUFLLHlCQUF5QjtnQkFDNUIsT0FBTyxJQUFJLDJCQUEyQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBRWpELEtBQUssMEJBQTBCO2dCQUM3QixPQUFPLElBQUksNEJBQTRCLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFbEQ7Z0JBQ0UscURBQXFEO2dCQUNyRCxNQUFNLElBQUksS0FBSyxDQUFDLDRCQUE2QixNQUFjLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RSxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSSxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQXNCO1FBQ2hE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