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.

99 lines 6.39 kB
import * as plugins from '../../plugins.js'; /** * WrappedSocket wraps a regular net.Socket to provide transparent access * to the real client IP and port when behind a proxy using PROXY protocol. * * This is the FOUNDATION for all PROXY protocol support and must be implemented * before any protocol parsing can occur. * * This implementation uses a Proxy to delegate all properties and methods * to the underlying socket while allowing override of specific properties. */ export class WrappedSocket { constructor(socket, realClientIP, realClientPort) { this.socket = socket; this.realClientIP = realClientIP; this.realClientPort = realClientPort; // Create a proxy that delegates everything to the underlying socket return new Proxy(this, { get(target, prop, receiver) { // Override specific properties if (prop === 'remoteAddress') { return target.remoteAddress; } if (prop === 'remotePort') { return target.remotePort; } if (prop === 'socket') { return target.socket; } if (prop === 'realClientIP') { return target.realClientIP; } if (prop === 'realClientPort') { return target.realClientPort; } if (prop === 'isFromTrustedProxy') { return target.isFromTrustedProxy; } if (prop === 'setProxyInfo') { return target.setProxyInfo.bind(target); } if (prop === 'remoteFamily') { return target.remoteFamily; } // For all other properties/methods, delegate to the underlying socket const value = target.socket[prop]; if (typeof value === 'function') { return value.bind(target.socket); } return value; }, set(target, prop, value) { // Set on the underlying socket target.socket[prop] = value; return true; } }); } /** * Returns the real client IP if available, otherwise the socket's remote address */ get remoteAddress() { return this.realClientIP || this.socket.remoteAddress; } /** * Returns the real client port if available, otherwise the socket's remote port */ get remotePort() { return this.realClientPort || this.socket.remotePort; } /** * Indicates if this connection came through a trusted proxy */ get isFromTrustedProxy() { return !!this.realClientIP; } /** * Returns the address family of the remote IP */ get remoteFamily() { const ip = this.realClientIP || this.socket.remoteAddress; if (!ip) return undefined; // Check if it's IPv6 if (ip.includes(':')) { return 'IPv6'; } // Otherwise assume IPv4 return 'IPv4'; } /** * Updates the real client information (called after parsing PROXY protocol) */ setProxyInfo(ip, port) { this.realClientIP = ip; this.realClientPort = port; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3JhcHBlZC1zb2NrZXQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb3JlL21vZGVscy93cmFwcGVkLXNvY2tldC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBRTVDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sT0FBTyxhQUFhO0lBUXhCLFlBQ0UsTUFBMEIsRUFDMUIsWUFBcUIsRUFDckIsY0FBdUI7UUFFdkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsSUFBSSxDQUFDLGNBQWMsR0FBRyxjQUFjLENBQUM7UUFFckMsb0VBQW9FO1FBQ3BFLE9BQU8sSUFBSSxLQUFLLENBQUMsSUFBSSxFQUFFO1lBQ3JCLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLFFBQVE7Z0JBQ3hCLCtCQUErQjtnQkFDL0IsSUFBSSxJQUFJLEtBQUssZUFBZSxFQUFFLENBQUM7b0JBQzdCLE9BQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQztnQkFDOUIsQ0FBQztnQkFDRCxJQUFJLElBQUksS0FBSyxZQUFZLEVBQUUsQ0FBQztvQkFDMUIsT0FBTyxNQUFNLENBQUMsVUFBVSxDQUFDO2dCQUMzQixDQUFDO2dCQUNELElBQUksSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO29CQUN0QixPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUM7Z0JBQ3ZCLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLEtBQUssY0FBYyxFQUFFLENBQUM7b0JBQzVCLE9BQU8sTUFBTSxDQUFDLFlBQVksQ0FBQztnQkFDN0IsQ0FBQztnQkFDRCxJQUFJLElBQUksS0FBSyxnQkFBZ0IsRUFBRSxDQUFDO29CQUM5QixPQUFPLE1BQU0sQ0FBQyxjQUFjLENBQUM7Z0JBQy9CLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLEtBQUssb0JBQW9CLEVBQUUsQ0FBQztvQkFDbEMsT0FBTyxNQUFNLENBQUMsa0JBQWtCLENBQUM7Z0JBQ25DLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLEtBQUssY0FBYyxFQUFFLENBQUM7b0JBQzVCLE9BQU8sTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzFDLENBQUM7Z0JBQ0QsSUFBSSxJQUFJLEtBQUssY0FBYyxFQUFFLENBQUM7b0JBQzVCLE9BQU8sTUFBTSxDQUFDLFlBQVksQ0FBQztnQkFDN0IsQ0FBQztnQkFFRCxzRUFBc0U7Z0JBQ3RFLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBZ0MsQ0FBQyxDQUFDO2dCQUM5RCxJQUFJLE9BQU8sS0FBSyxLQUFLLFVBQVUsRUFBRSxDQUFDO29CQUNoQyxPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuQyxDQUFDO2dCQUNELE9BQU8sS0FBSyxDQUFDO1lBQ2YsQ0FBQztZQUNELEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLEtBQUs7Z0JBQ3JCLCtCQUErQjtnQkFDOUIsTUFBTSxDQUFDLE1BQWMsQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7Z0JBQ3JDLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztTQUNGLENBQVEsQ0FBQztJQUNaLENBQUM7SUFFRDs7T0FFRztJQUNILElBQUksYUFBYTtRQUNmLE9BQU8sSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQztJQUN4RCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUM7SUFDdkQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxrQkFBa0I7UUFDcEIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQztJQUM3QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxJQUFJLFlBQVk7UUFDZCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO1FBQzFELElBQUksQ0FBQyxFQUFFO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFFMUIscUJBQXFCO1FBQ3JCLElBQUksRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sTUFBTSxDQUFDO1FBQ2hCLENBQUM7UUFDRCx3QkFBd0I7UUFDeEIsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsWUFBWSxDQUFDLEVBQVUsRUFBRSxJQUFZO1FBQ25DLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO0lBQzdCLENBQUM7Q0FDRiJ9