@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
JavaScript
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