@@ -26,7 +26,9 @@ export interface ProxyTargetDetailed {
26
26
}
27
27
export type ProxyType = "ws" | "web" ;
28
28
export type ProxyTarget = ProxyTargetUrl | ProxyTargetDetailed ;
29
- export type ProxyTargetUrl = URL | string | { port : number ; host : string } ;
29
+ export type ProxyTargetUrl = URL | string | { port : number ; host : string ; protocol ?: string } ;
30
+
31
+ export type NormalizeProxyTarget < T extends ProxyTargetUrl > = Exclude < T , string > | URL ;
30
32
31
33
export interface ServerOptions {
32
34
// NOTE: `options.target and `options.forward` cannot be both missing when the
@@ -83,6 +85,18 @@ export interface ServerOptions {
83
85
selfHandleResponse ?: boolean ;
84
86
/** Buffer */
85
87
buffer ?: Stream ;
88
+ /** Explicitly set the method type of the ProxyReq */
89
+ method ?: string ;
90
+ /**
91
+ * Optionally override the trusted CA certificates.
92
+ * This is passed to https.request.
93
+ */
94
+ ca ?: string ;
95
+ }
96
+
97
+ export interface NormalizedServerOptions extends ServerOptions {
98
+ target ?: NormalizeProxyTarget < ProxyTarget > ;
99
+ forward ?: NormalizeProxyTarget < ProxyTargetUrl > ;
86
100
}
87
101
88
102
export type ErrorCallback =
@@ -106,6 +120,7 @@ type ProxyServerEventMap = {
106
120
req : http . IncomingMessage ,
107
121
res : http . ServerResponse ,
108
122
options : ServerOptions ,
123
+ socket : net . Socket ,
109
124
] ;
110
125
proxyRes : [
111
126
proxyRes : http . IncomingMessage ,
@@ -137,56 +152,75 @@ type ProxyServerEventMap = {
137
152
] ;
138
153
}
139
154
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 : (
155
+ type ProxyMethodArgs = {
156
+ ws : [
157
+ req : http . IncomingMessage ,
158
+ socket : any ,
159
+ head : any ,
149
160
...args :
150
161
[
151
- req : http . IncomingMessage ,
152
- socket : any ,
153
- head : any ,
154
162
options ?: ServerOptions ,
155
163
callback ?: ErrorCallback ,
156
164
]
157
165
| [
158
- req : http . IncomingMessage ,
159
- socket : any ,
160
- head : any ,
161
166
callback ?: ErrorCallback ,
162
167
]
163
- ) => void ;
168
+ ]
169
+ web : [
170
+ req : http . IncomingMessage ,
171
+ res : http . ServerResponse ,
172
+ ...args :
173
+ [
174
+ options : ServerOptions ,
175
+ callback ?: ErrorCallback ,
176
+ ]
177
+ | [
178
+ callback ?: ErrorCallback
179
+ ]
180
+ ]
181
+ }
182
+
183
+ type PassFunctions = {
184
+ ws : (
185
+ req : http . IncomingMessage ,
186
+ socket : net . Socket ,
187
+ options : NormalizedServerOptions ,
188
+ head : Buffer | undefined ,
189
+ server : ProxyServer ,
190
+ cb ?: ErrorCallback
191
+ ) => unknown
192
+ web : (
193
+ req : http . IncomingMessage ,
194
+ res : http . ServerResponse ,
195
+ options : NormalizedServerOptions ,
196
+ head : Buffer | undefined ,
197
+ server : ProxyServer ,
198
+ cb ?: ErrorCallback
199
+ ) => unknown
200
+ }
201
+
202
+ export class ProxyServer extends EventEmitter < ProxyServerEventMap > {
203
+ /**
204
+ * Used for proxying WS(S) requests
205
+ * @param req - Client request.
206
+ * @param socket - Client socket.
207
+ * @param head - Client head.
208
+ * @param options - Additional options.
209
+ */
210
+ public readonly ws : ( ...args : ProxyMethodArgs [ "ws" ] ) => void ;
164
211
165
212
/**
166
213
* Used for proxying regular HTTP(S) requests
167
214
* @param req - Client request.
168
215
* @param res - Client response.
169
216
* @param options - Additional options.
170
217
*/
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 ;
218
+ public readonly web : ( ...args : ProxyMethodArgs [ "web" ] ) => void ;
185
219
186
220
private options : ServerOptions ;
187
- private webPasses ;
188
- private wsPasses ;
189
- private _server ?;
221
+ private webPasses : Array < PassFunctions [ 'web' ] > ;
222
+ private wsPasses : Array < PassFunctions [ 'ws' ] > ;
223
+ private _server ?: http . Server | https . Server | null ;
190
224
191
225
/**
192
226
* Creates the proxy server with specified options.
@@ -233,10 +267,10 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
233
267
234
268
// createRightProxy - Returns a function that when called creates the loader for
235
269
// either `ws` or `web`'s passes.
236
- createRightProxy = ( type : ProxyType ) : Function => {
270
+ createRightProxy = < PT extends ProxyType > ( type : PT ) : Function => {
237
271
log ( "createRightProxy" , { type } ) ;
238
- return ( options ) => {
239
- return ( ...args : any [ ] /* req, res, [head], [opts] */ ) => {
272
+ return ( options : ServerOptions ) => {
273
+ return ( ...args : ProxyMethodArgs [ PT ] /* req, res, [head], [opts] */ ) => {
240
274
const req = args [ 0 ] ;
241
275
log ( "proxy: " , { type, path : req . url } ) ;
242
276
const res = args [ 1 ] ;
@@ -255,16 +289,16 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
255
289
} ) ;
256
290
}
257
291
let counter = args . length - 1 ;
258
- let head ;
259
- let cb ;
292
+ let head : Buffer | undefined ;
293
+ let cb : ErrorCallback | undefined ;
260
294
261
295
// optional args parse begin
262
296
if ( typeof args [ counter ] === "function" ) {
263
297
cb = args [ counter ] ;
264
298
counter -- ;
265
299
}
266
300
267
- let requestOptions ;
301
+ let requestOptions : ServerOptions ;
268
302
if ( ! ( args [ counter ] instanceof Buffer ) && args [ counter ] !== res ) {
269
303
// Copy global options, and overwrite with request options
270
304
requestOptions = { ...options , ...args [ counter ] } ;
@@ -277,7 +311,7 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
277
311
head = args [ counter ] ;
278
312
}
279
313
280
- for ( const e of [ "target" , "forward" ] ) {
314
+ for ( const e of [ "target" , "forward" ] as const ) {
281
315
if ( typeof requestOptions [ e ] === "string" ) {
282
316
requestOptions [ e ] = toURL ( requestOptions [ e ] ) ;
283
317
}
@@ -297,7 +331,7 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
297
331
* refer to the connection socket
298
332
* pass(req, socket, options, head)
299
333
*/
300
- if ( pass ( req , res , requestOptions , head , this , cb ) ) {
334
+ if ( pass ( req , res , requestOptions as NormalizedServerOptions , head , this , cb ) ) {
301
335
// passes can return a truthy value to halt the loop
302
336
break ;
303
337
}
@@ -356,12 +390,12 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
356
390
} ) ;
357
391
} ;
358
392
359
- before = ( type : ProxyType , passName : string , cb : Function ) => {
393
+ before = < PT extends ProxyType > ( type : PT , passName : string , cb : PassFunctions [ PT ] ) => {
360
394
if ( type !== "ws" && type !== "web" ) {
361
395
throw new Error ( "type must be `web` or `ws`" ) ;
362
396
}
363
- const passes = type === "ws" ? this . wsPasses : this . webPasses ;
364
- let i = false ;
397
+ const passes = ( type === "ws" ? this . wsPasses : this . webPasses ) as PassFunctions [ PT ] [ ] ;
398
+ let i : false | number = false ;
365
399
366
400
passes . forEach ( ( v , idx ) => {
367
401
if ( v . name === passName ) {
@@ -376,12 +410,12 @@ export class ProxyServer extends EventEmitter<ProxyServerEventMap> {
376
410
passes . splice ( i , 0 , cb ) ;
377
411
} ;
378
412
379
- after = ( type : ProxyType , passName : string , cb : Function ) => {
413
+ after = < PT extends ProxyType > ( type : PT , passName : string , cb : PassFunctions [ PT ] ) => {
380
414
if ( type !== "ws" && type !== "web" ) {
381
415
throw new Error ( "type must be `web` or `ws`" ) ;
382
416
}
383
- const passes = type === "ws" ? this . wsPasses : this . webPasses ;
384
- let i = false ;
417
+ const passes = ( type === "ws" ? this . wsPasses : this . webPasses ) as PassFunctions [ PT ] [ ] ;
418
+ let i : false | number = false ;
385
419
386
420
passes . forEach ( ( v , idx ) => {
387
421
if ( v . name === passName ) {
0 commit comments