11import * as http from "http" ;
22import * as https from "https" ;
3+ import * as net from "net" ;
34import { WEB_PASSES } from "./passes/web-incoming" ;
45import { WS_PASSES } from "./passes/ws-incoming" ;
56import { EventEmitter } from "events" ;
@@ -32,67 +33,165 @@ export interface ServerOptions {
3233 // actually proxying is called. However, they can be missing when creating the
3334 // proxy server in the first place! E.g., you could make a proxy server P with
3435 // no options, then use P.web(req,res, {target:...}).
35- // URL string to be parsed with the url module.
36+ /** URL string to be parsed with the url module. */
3637 target ?: ProxyTarget ;
37- // URL string to be parsed with the url module or a URL object.
38+ /** URL string to be parsed with the url module or a URL object. */
3839 forward ?: ProxyTargetUrl ;
39- // Object to be passed to http(s).request.
40+ /** Object to be passed to http(s).request. */
4041 agent ?: any ;
41- // Object to be passed to https.createServer().
42+ /** Object to be passed to https.createServer(). */
4243 ssl ?: any ;
43- // If you want to proxy websockets.
44+ /** If you want to proxy websockets. */
4445 ws ?: boolean ;
45- // Adds x- forward headers.
46+ /** Adds x- forward headers. */
4647 xfwd ?: boolean ;
47- // Verify SSL certificate.
48+ /** Verify SSL certificate. */
4849 secure ?: boolean ;
49- // Explicitly specify if we are proxying to another proxy.
50+ /** Explicitly specify if we are proxying to another proxy. */
5051 toProxy ?: boolean ;
51- // Specify whether you want to prepend the target's path to the proxy path.
52+ /** Specify whether you want to prepend the target's path to the proxy path. */
5253 prependPath ?: boolean ;
53- // Specify whether you want to ignore the proxy path of the incoming request.
54+ /** Specify whether you want to ignore the proxy path of the incoming request. */
5455 ignorePath ?: boolean ;
55- // Local interface string to bind for outgoing connections.
56+ /** Local interface string to bind for outgoing connections. */
5657 localAddress ?: string ;
57- // Changes the origin of the host header to the target URL.
58+ /** Changes the origin of the host header to the target URL. */
5859 changeOrigin ?: boolean ;
59- // specify whether you want to keep letter case of response header key
60+ /** specify whether you want to keep letter case of response header key */
6061 preserveHeaderKeyCase ?: boolean ;
61- // Basic authentication i.e. 'user:password' to compute an Authorization header.
62+ /** Basic authentication i.e. 'user:password' to compute an Authorization header. */
6263 auth ?: string ;
63- // Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null.
64+ /** Rewrites the location hostname on (301 / 302 / 307 / 308) redirects, Default: null. */
6465 hostRewrite ?: string ;
65- // Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false.
66+ /** Rewrites the location host/ port on (301 / 302 / 307 / 308) redirects based on requested host/ port.Default: false. */
6667 autoRewrite ?: boolean ;
67- // Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null.
68+ /** Rewrites the location protocol on (301 / 302 / 307 / 308) redirects to 'http' or 'https'.Default: null. */
6869 protocolRewrite ?: string ;
69- // rewrites domain of set-cookie headers.
70+ /** rewrites domain of set-cookie headers. */
7071 cookieDomainRewrite ?: false | string | { [ oldDomain : string ] : string } ;
71- // rewrites path of set-cookie headers. Default: false
72+ /** rewrites path of set-cookie headers. Default: false */
7273 cookiePathRewrite ?: false | string | { [ oldPath : string ] : string } ;
73- // object with extra headers to be added to target requests.
74+ /** object with extra headers to be added to target requests. */
7475 headers ?: { [ header : string ] : string | string [ ] | undefined } ;
75- // Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes)
76+ /** Timeout (in milliseconds) when proxy receives no response from target. Default: 120000 (2 minutes) */
7677 proxyTimeout ?: number ;
77- // Timeout (in milliseconds) for incoming requests
78+ /** Timeout (in milliseconds) for incoming requests */
7879 timeout ?: number ;
79- // Specify whether you want to follow redirects. Default: false
80+ /** Specify whether you want to follow redirects. Default: false */
8081 followRedirects ?: boolean ;
81- // If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event
82+ /** If set to true, none of the webOutgoing passes are called and it's your responsibility to appropriately return the response by listening and acting on the proxyRes event */
8283 selfHandleResponse ?: boolean ;
83- // Buffer
84+ /** Buffer */
8485 buffer ?: Stream ;
8586}
8687
87- export class ProxyServer extends EventEmitter {
88- public readonly ws ;
89- public readonly web ;
88+ export type ErrorCallback =
89+ (
90+ err : Error ,
91+ req : http . IncomingMessage ,
92+ res : http . ServerResponse | net . Socket ,
93+ target ?: ProxyTargetUrl ,
94+ ) => void ;
95+
96+ type ProxyServerEventMap = {
97+ error : Parameters < ErrorCallback > ;
98+ start : [
99+ req : http . IncomingMessage ,
100+ res : http . ServerResponse ,
101+ target : ProxyTargetUrl ,
102+ ] ;
103+ open : [ socket : net . Socket ] ;
104+ proxyReq : [
105+ proxyReq : http . ClientRequest ,
106+ req : http . IncomingMessage ,
107+ res : http . ServerResponse ,
108+ options : ServerOptions ,
109+ ] ;
110+ proxyRes : [
111+ proxyRes : http . IncomingMessage ,
112+ req : http . IncomingMessage ,
113+ res : http . ServerResponse ,
114+ ] ;
115+ proxyReqWs : [
116+ proxyReq : http . ClientRequest ,
117+ req : http . IncomingMessage ,
118+ socket : net . Socket ,
119+ options : ServerOptions ,
120+ head : any ,
121+ ] ;
122+ econnreset : [
123+ err : Error ,
124+ req : http . IncomingMessage ,
125+ res : http . ServerResponse ,
126+ target : ProxyTargetUrl ,
127+ ] ;
128+ end : [
129+ req : http . IncomingMessage ,
130+ res : http . ServerResponse ,
131+ proxyRes : http . IncomingMessage ,
132+ ] ;
133+ close : [
134+ proxyRes : http . IncomingMessage ,
135+ proxySocket : net . Socket ,
136+ proxyHead : any ,
137+ ] ;
138+ }
139+
140+ export class ProxyServer extends EventEmitter < ProxyServerEventMap > {
141+ /**
142+ * Used for proxying WS(S) requests
143+ * @param req - Client request.
144+ * @param socket - Client socket.
145+ * @param head - Client head.
146+ * @param options - Additional options.
147+ */
148+ public readonly ws : (
149+ ...args :
150+ [
151+ req : http . IncomingMessage ,
152+ socket : any ,
153+ head : any ,
154+ options ?: ServerOptions ,
155+ callback ?: ErrorCallback ,
156+ ]
157+ | [
158+ req : http . IncomingMessage ,
159+ socket : any ,
160+ head : any ,
161+ callback ?: ErrorCallback ,
162+ ]
163+ ) => void ;
164+
165+ /**
166+ * Used for proxying regular HTTP(S) requests
167+ * @param req - Client request.
168+ * @param res - Client response.
169+ * @param options - Additional options.
170+ */
171+ public readonly web : (
172+ ...args :
173+ [
174+ req : http . IncomingMessage ,
175+ res : http . ServerResponse ,
176+ options : ServerOptions ,
177+ callback ?: ErrorCallback ,
178+ ]
179+ | [
180+ req : http . IncomingMessage ,
181+ res : http . ServerResponse ,
182+ callback ?: ErrorCallback
183+ ]
184+ ) => void ;
90185
91186 private options : ServerOptions ;
92187 private webPasses ;
93188 private wsPasses ;
94189 private _server ?;
95190
191+ /**
192+ * Creates the proxy server with specified options.
193+ * @param options - Config object passed to the proxy
194+ */
96195 constructor ( options : ServerOptions = { } ) {
97196 super ( ) ;
98197 log ( "creating a ProxyServer" , options ) ;
@@ -105,6 +204,33 @@ export class ProxyServer extends EventEmitter {
105204 this . on ( "error" , this . onError ) ;
106205 }
107206
207+ /**
208+ * Creates the proxy server with specified options.
209+ * @param options Config object passed to the proxy
210+ * @returns Proxy object with handlers for `ws` and `web` requests
211+ */
212+ static createProxyServer ( options ?: ServerOptions ) : ProxyServer {
213+ return new ProxyServer ( options ) ;
214+ }
215+
216+ /**
217+ * Creates the proxy server with specified options.
218+ * @param options Config object passed to the proxy
219+ * @returns Proxy object with handlers for `ws` and `web` requests
220+ */
221+ static createServer ( options ?: ServerOptions ) : ProxyServer {
222+ return new ProxyServer ( options ) ;
223+ }
224+
225+ /**
226+ * Creates the proxy server with specified options.
227+ * @param options Config object passed to the proxy
228+ * @returns Proxy object with handlers for `ws` and `web` requests
229+ */
230+ static createProxy ( options ?: ServerOptions ) : ProxyServer {
231+ return new ProxyServer ( options ) ;
232+ }
233+
108234 // createRightProxy - Returns a function that when called creates the loader for
109235 // either `ws` or `web`'s passes.
110236 createRightProxy = ( type : ProxyType ) : Function => {
@@ -124,8 +250,8 @@ export class ProxyServer extends EventEmitter {
124250 // and there's no way for a user of http-proxy-3 to get ahold
125251 // of this res object and attach their own error handler until
126252 // after the passes. So we better attach one ASAP right here:
127- res . on ( "error" , ( ... args ) => {
128- this . emit ( "error" , ... args ) ;
253+ ( res as net . Socket ) . on ( "error" , ( err ) => {
254+ this . emit ( "error" , err , req , res ) ;
129255 } ) ;
130256 }
131257 let counter = args . length - 1 ;
@@ -158,7 +284,7 @@ export class ProxyServer extends EventEmitter {
158284 }
159285
160286 if ( ! requestOptions . target && ! requestOptions . forward ) {
161- this . emit ( "error" , new Error ( "Must set target or forward" ) ) ;
287+ this . emit ( "error" , new Error ( "Must set target or forward" ) , req , res ) ;
162288 return ;
163289 }
164290
@@ -187,6 +313,11 @@ export class ProxyServer extends EventEmitter {
187313 }
188314 } ;
189315
316+ /**
317+ * A function that wraps the object in a webserver, for your convenience
318+ * @param port - Port to listen on
319+ * @param hostname - The hostname to listen on
320+ */
190321 listen = ( port : number , hostname ?: string ) => {
191322 log ( "listen" , { port, hostname } ) ;
192323
@@ -210,6 +341,9 @@ export class ProxyServer extends EventEmitter {
210341 return this . _server ?. address ( ) ;
211342 } ;
212343
344+ /**
345+ * A function that closes the inner webserver and stops listening on given port
346+ */
213347 close = ( cb ?: Function ) => {
214348 if ( this . _server == null ) {
215349 cb ?.( ) ;
0 commit comments