diff --git a/lib/http-proxy/index.ts b/lib/http-proxy/index.ts index 75fa5ee..a04dce7 100644 --- a/lib/http-proxy/index.ts +++ b/lib/http-proxy/index.ts @@ -99,107 +99,107 @@ export interface NormalizedServerOptions extends ServerOptions { forward?: NormalizeProxyTarget; } -export type ErrorCallback = +export type ErrorCallback = ( - err: Error, - req: http.IncomingMessage, - res: http.ServerResponse | net.Socket, + err: TError, + req: InstanceType, + res: InstanceType | net.Socket, target?: ProxyTargetUrl, ) => void; -type ProxyServerEventMap = { - error: Parameters; +type ProxyServerEventMap = { + error: Parameters>; start: [ - req: http.IncomingMessage, - res: http.ServerResponse, + req: InstanceType, + res: InstanceType, target: ProxyTargetUrl, ]; open: [socket: net.Socket]; proxyReq: [ proxyReq: http.ClientRequest, - req: http.IncomingMessage, - res: http.ServerResponse, + req: InstanceType, + res: InstanceType, options: ServerOptions, socket: net.Socket, ]; proxyRes: [ - proxyRes: http.IncomingMessage, - req: http.IncomingMessage, - res: http.ServerResponse, + proxyRes: InstanceType, + req: InstanceType, + res: InstanceType, ]; proxyReqWs: [ proxyReq: http.ClientRequest, - req: http.IncomingMessage, + req: InstanceType, socket: net.Socket, options: ServerOptions, head: any, ]; econnreset: [ err: Error, - req: http.IncomingMessage, - res: http.ServerResponse, + req: InstanceType, + res: InstanceType, target: ProxyTargetUrl, ]; end: [ - req: http.IncomingMessage, - res: http.ServerResponse, - proxyRes: http.IncomingMessage, + req: InstanceType, + res: InstanceType, + proxyRes: InstanceType, ]; close: [ - proxyRes: http.IncomingMessage, + proxyRes: InstanceType, proxySocket: net.Socket, proxyHead: any, ]; } -type ProxyMethodArgs = { +type ProxyMethodArgs = { ws: [ - req: http.IncomingMessage, + req: InstanceType, socket: any, head: any, ...args: - [ - options?: ServerOptions, - callback?: ErrorCallback, - ] + [ + options?: ServerOptions, + callback?: ErrorCallback, + ] | [ - callback?: ErrorCallback, - ] + callback?: ErrorCallback, + ] ] web: [ - req: http.IncomingMessage, - res: http.ServerResponse, + req: InstanceType, + res: InstanceType, ...args: - [ - options: ServerOptions, - callback?: ErrorCallback, - ] - | [ - callback?: ErrorCallback - ] + [ + options: ServerOptions, + callback?: ErrorCallback, + ] + | [ + callback?: ErrorCallback + ] ] } -type PassFunctions = { +type PassFunctions = { ws: ( - req: http.IncomingMessage, + req: InstanceType, socket: net.Socket, options: NormalizedServerOptions, head: Buffer | undefined, - server: ProxyServer, - cb?: ErrorCallback + server: ProxyServer, + cb?: ErrorCallback ) => unknown web: ( - req: http.IncomingMessage, - res: http.ServerResponse, + req: InstanceType, + res: InstanceType, options: NormalizedServerOptions, head: Buffer | undefined, - server: ProxyServer, - cb?: ErrorCallback + server: ProxyServer, + cb?: ErrorCallback ) => unknown } -export class ProxyServer extends EventEmitter { +export class ProxyServer extends EventEmitter> { /** * Used for proxying WS(S) requests * @param req - Client request. @@ -207,7 +207,7 @@ export class ProxyServer extends EventEmitter { * @param head - Client head. * @param options - Additional options. */ - public readonly ws: (...args: ProxyMethodArgs["ws"]) => void; + public readonly ws: (...args: ProxyMethodArgs["ws"]) => void; /** * Used for proxying regular HTTP(S) requests @@ -215,12 +215,12 @@ export class ProxyServer extends EventEmitter { * @param res - Client response. * @param options - Additional options. */ - public readonly web: (...args: ProxyMethodArgs["web"]) => void; + public readonly web: (...args: ProxyMethodArgs["web"]) => void; private options: ServerOptions; - private webPasses: Array; - private wsPasses: Array; - private _server?: http.Server | https.Server | null; + private webPasses: Array['web']>; + private wsPasses: Array['ws']>; + private _server?: http.Server | https.Server | null; /** * Creates the proxy server with specified options. @@ -233,8 +233,8 @@ export class ProxyServer extends EventEmitter { this.options = options; this.web = this.createRightProxy("web")(options); this.ws = this.createRightProxy("ws")(options); - this.webPasses = Object.values(WEB_PASSES); - this.wsPasses = Object.values(WS_PASSES); + this.webPasses = Object.values(WEB_PASSES) as Array['web']>; + this.wsPasses = Object.values(WS_PASSES) as Array['ws']>; this.on("error", this.onError); } @@ -243,8 +243,12 @@ export class ProxyServer extends EventEmitter { * @param options Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ - static createProxyServer(options?: ServerOptions): ProxyServer { - return new ProxyServer(options); + static createProxyServer< + TIncomingMessage extends typeof http.IncomingMessage, + TServerResponse extends typeof http.ServerResponse, + TError = Error + >(options?: ServerOptions): ProxyServer { + return new ProxyServer(options); } /** @@ -252,8 +256,12 @@ export class ProxyServer extends EventEmitter { * @param options Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ - static createServer(options?: ServerOptions): ProxyServer { - return new ProxyServer(options); + static createServer< + TIncomingMessage extends typeof http.IncomingMessage, + TServerResponse extends typeof http.ServerResponse, + TError = Error + >(options?: ServerOptions): ProxyServer { + return new ProxyServer(options); } /** @@ -261,8 +269,12 @@ export class ProxyServer extends EventEmitter { * @param options Config object passed to the proxy * @returns Proxy object with handlers for `ws` and `web` requests */ - static createProxy(options?: ServerOptions): ProxyServer { - return new ProxyServer(options); + static createProxy< + TIncomingMessage extends typeof http.IncomingMessage, + TServerResponse extends typeof http.ServerResponse, + TError = Error + >(options?: ServerOptions): ProxyServer { + return new ProxyServer(options); } // createRightProxy - Returns a function that when called creates the loader for @@ -270,9 +282,9 @@ export class ProxyServer extends EventEmitter { createRightProxy = (type: PT): Function => { log("createRightProxy", { type }); return (options: ServerOptions) => { - return (...args: ProxyMethodArgs[PT] /* req, res, [head], [opts] */) => { + return (...args: ProxyMethodArgs[PT] /* req, res, [head], [opts] */) => { const req = args[0]; - log("proxy: ", { type, path: req.url }); + log("proxy: ", { type, path: (req as http.IncomingMessage).url }); const res = args[1]; const passes = type === "ws" ? this.wsPasses : this.webPasses; if (type == "ws") { @@ -284,13 +296,13 @@ export class ProxyServer extends EventEmitter { // and there's no way for a user of http-proxy-3 to get ahold // of this res object and attach their own error handler until // after the passes. So we better attach one ASAP right here: - (res as net.Socket).on("error", (err) => { + (res as net.Socket).on("error", (err: TError) => { this.emit("error", err, req, res); }); } let counter = args.length - 1; let head: Buffer | undefined; - let cb: ErrorCallback | undefined; + let cb: ErrorCallback | undefined; // optional args parse begin if (typeof args[counter] === "function") { @@ -318,7 +330,7 @@ export class ProxyServer extends EventEmitter { } if (!requestOptions.target && !requestOptions.forward) { - this.emit("error", new Error("Must set target or forward"), req, res); + this.emit("error", new Error("Must set target or forward") as TError, req, res); return; } @@ -340,7 +352,7 @@ export class ProxyServer extends EventEmitter { }; }; - onError = (err: Error) => { + onError = (err: TError) => { // Force people to handle their own errors if (this.listeners("error").length === 1) { throw err; @@ -355,12 +367,16 @@ export class ProxyServer extends EventEmitter { listen = (port: number, hostname?: string) => { log("listen", { port, hostname }); + const requestListener = (req: InstanceType, res: InstanceType) => { + this.web(req, res); + }; + this._server = this.options.ssl - ? https.createServer(this.options.ssl, this.web) - : http.createServer(this.web); + ? https.createServer(this.options.ssl, requestListener) + : http.createServer(requestListener); if (this.options.ws) { - this._server.on("upgrade", (req, socket, head) => { + this._server.on("upgrade", (req: InstanceType, socket, head) => { this.ws(req, socket, head); }); } @@ -390,11 +406,11 @@ export class ProxyServer extends EventEmitter { }); }; - before = (type: PT, passName: string, cb: PassFunctions[PT]) => { + before = (type: PT, passName: string, cb: PassFunctions[PT]) => { if (type !== "ws" && type !== "web") { throw new Error("type must be `web` or `ws`"); } - const passes = (type === "ws" ? this.wsPasses : this.webPasses) as PassFunctions[PT][]; + const passes = (type === "ws" ? this.wsPasses : this.webPasses) as PassFunctions[PT][]; let i: false | number = false; passes.forEach((v, idx) => { @@ -410,11 +426,11 @@ export class ProxyServer extends EventEmitter { passes.splice(i, 0, cb); }; - after = (type: PT, passName: string, cb: PassFunctions[PT]) => { + after = (type: PT, passName: string, cb: PassFunctions[PT]) => { if (type !== "ws" && type !== "web") { throw new Error("type must be `web` or `ws`"); } - const passes = (type === "ws" ? this.wsPasses : this.webPasses) as PassFunctions[PT][]; + const passes = (type === "ws" ? this.wsPasses : this.webPasses) as PassFunctions[PT][]; let i: false | number = false; passes.forEach((v, idx) => { diff --git a/lib/index.ts b/lib/index.ts index fbea2a7..6dac1a6 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -13,6 +13,7 @@ export { type ErrorCallback, }; export { numOpenSockets } from './http-proxy/passes/ws-incoming'; +import * as http from 'node:http'; /** * Creates the proxy server. @@ -29,8 +30,8 @@ export { numOpenSockets } from './http-proxy/passes/ws-incoming'; * @api public */ -function createProxyServer(options: ServerOptions = {}): ProxyServer { - return new ProxyServer(options); +function createProxyServer(options: ServerOptions = {}): ProxyServer { + return new ProxyServer(options); } export {