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.

121 lines 8.01 kB
import * as plugins from '../../plugins.js'; import { ForwardingHandlerEvents } from '../config/forwarding-types.js'; /** * Base class for all forwarding handlers */ export class ForwardingHandler extends plugins.EventEmitter { /** * Create a new ForwardingHandler * @param config The forwarding configuration */ constructor(config) { super(); this.config = config; } /** * Initialize the handler * Base implementation does nothing, subclasses should override as needed */ async initialize() { // Base implementation - no initialization needed } /** * Get a target from the configuration, supporting round-robin selection * @param incomingPort Optional incoming port for 'preserve' mode * @returns A resolved target object with host and port */ getTargetFromConfig(incomingPort = 80) { const { target } = this.config; // Handle round-robin host selection if (Array.isArray(target.host)) { if (target.host.length === 0) { throw new Error('No target hosts specified'); } // Simple round-robin selection const randomIndex = Math.floor(Math.random() * target.host.length); return { host: target.host[randomIndex], port: this.resolvePort(target.port, incomingPort) }; } // Single host return { host: target.host, port: this.resolvePort(target.port, incomingPort) }; } /** * Resolves a port value, handling 'preserve' and function ports * @param port The port value to resolve * @param incomingPort Optional incoming port to use for 'preserve' mode */ resolvePort(port, incomingPort = 80) { if (typeof port === 'function') { try { // Create a minimal context for the function that includes the incoming port const ctx = { port: incomingPort }; return port(ctx); } catch (err) { console.error('Error resolving port function:', err); return incomingPort; // Fall back to incoming port } } else if (port === 'preserve') { return incomingPort; // Use the actual incoming port for 'preserve' } else { return port; } } /** * Redirect an HTTP request to HTTPS * @param req The HTTP request * @param res The HTTP response */ redirectToHttps(req, res) { const host = req.headers.host || ''; const path = req.url || '/'; const redirectUrl = `https://${host}${path}`; res.writeHead(301, { 'Location': redirectUrl, 'Cache-Control': 'no-cache' }); res.end(`Redirecting to ${redirectUrl}`); this.emit(ForwardingHandlerEvents.HTTP_RESPONSE, { statusCode: 301, headers: { 'Location': redirectUrl }, size: 0 }); } /** * Apply custom headers from configuration * @param headers The original headers * @param variables Variables to replace in the headers * @returns The headers with custom values applied */ applyCustomHeaders(headers, variables) { const customHeaders = this.config.advanced?.headers || {}; const result = { ...headers }; // Apply custom headers with variable substitution for (const [key, value] of Object.entries(customHeaders)) { if (typeof value !== 'string') continue; let processedValue = value; // Replace variables in the header value for (const [varName, varValue] of Object.entries(variables)) { processedValue = processedValue.replace(`{${varName}}`, varValue); } result[key] = processedValue; } return result; } /** * Get the timeout for this connection from configuration * @returns Timeout in milliseconds */ getTimeout() { return this.config.advanced?.timeout || 60000; // Default: 60 seconds } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1oYW5kbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vdHMvZm9yd2FyZGluZy9oYW5kbGVycy9iYXNlLWhhbmRsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUs1QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUV4RTs7R0FFRztBQUNILE1BQU0sT0FBZ0IsaUJBQWtCLFNBQVEsT0FBTyxDQUFDLFlBQVk7SUFDbEU7OztPQUdHO0lBQ0gsWUFBc0IsTUFBc0I7UUFDMUMsS0FBSyxFQUFFLENBQUM7UUFEWSxXQUFNLEdBQU4sTUFBTSxDQUFnQjtJQUU1QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ksS0FBSyxDQUFDLFVBQVU7UUFDckIsaURBQWlEO0lBQ25ELENBQUM7SUFlRDs7OztPQUlHO0lBQ08sbUJBQW1CLENBQUMsZUFBdUIsRUFBRTtRQUNyRCxNQUFNLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUUvQixvQ0FBb0M7UUFDcEMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQy9CLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQzdCLE1BQU0sSUFBSSxLQUFLLENBQUMsMkJBQTJCLENBQUMsQ0FBQztZQUMvQyxDQUFDO1lBRUQsK0JBQStCO1lBQy9CLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkUsT0FBTztnQkFDTCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUM7Z0JBQzlCLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxD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