25
25
*/
26
26
27
27
var events = require ( 'events' ) ,
28
+ http = require ( 'http' ) ,
28
29
util = require ( 'util' ) ,
29
30
httpProxy = require ( '../node-http-proxy' ) ;
30
31
@@ -122,17 +123,37 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
122
123
123
124
//
124
125
// Add common proxy headers to the request so that they can
125
- // be availible to the proxy target server:
126
+ // be availible to the proxy target server. If the proxy is
127
+ // part of proxy chain it will append the address:
126
128
//
127
129
// * `x-forwarded-for`: IP Address of the original request
128
130
// * `x-forwarded-proto`: Protocol of the original request
129
131
// * `x-forwarded-port`: Port of the original request.
130
132
//
131
-
132
133
if ( this . enable . xforward && req . connection && req . socket ) {
133
- req . headers [ 'x-forwarded-for' ] = req . connection . remoteAddress || req . socket . remoteAddress ;
134
- req . headers [ 'x-forwarded-port' ] = req . connection . remotePort || req . socket . remotePort ;
135
- req . headers [ 'x-forwarded-proto' ] = req . connection . pair ? 'https' : 'http' ;
134
+ if ( req . headers [ 'x-forwarded-for' ] ) {
135
+ var addressToAppend = "," + req . connection . remoteAddress || req . socket . remoteAddress ;
136
+ req . headers [ 'x-forwarded-for' ] += addressToAppend ;
137
+ }
138
+ else {
139
+ req . headers [ 'x-forwarded-for' ] = req . connection . remoteAddress || req . socket . remoteAddress ;
140
+ }
141
+
142
+ if ( req . headers [ 'x-forwarded-port' ] ) {
143
+ var portToAppend = "," + req . connection . remotePort || req . socket . remotePort ;
144
+ req . headers [ 'x-forwarded-port' ] += portToAppend ;
145
+ }
146
+ else {
147
+ req . headers [ 'x-forwarded-port' ] = req . connection . remotePort || req . socket . remotePort ;
148
+ }
149
+
150
+ if ( req . headers [ 'x-forwarded-proto' ] ) {
151
+ var protoToAppend = "," + req . connection . pair ? 'https' : 'http' ;
152
+ req . headers [ 'x-forwarded-proto' ] += protoToAppend ;
153
+ }
154
+ else {
155
+ req . headers [ 'x-forwarded-proto' ] = req . connection . pair ? 'https' : 'http' ;
156
+ }
136
157
}
137
158
138
159
//
@@ -213,6 +234,15 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
213
234
delete response . headers [ 'transfer-encoding' ] ;
214
235
}
215
236
237
+ if ( ( response . statusCode === 301 ) || ( response . statusCode === 302 ) ) {
238
+ if ( self . source . https && ! self . target . https ) {
239
+ response . headers . location = response . headers . location . replace ( / ^ h t t p \: / , 'https:' ) ;
240
+ }
241
+ if ( self . target . https && ! self . source . https ) {
242
+ response . headers . location = response . headers . location . replace ( / ^ h t t p s \: / , 'http:' ) ;
243
+ }
244
+ }
245
+
216
246
// Set the headers of the client response
217
247
res . writeHead ( response . statusCode , response . headers ) ;
218
248
@@ -271,11 +301,19 @@ HttpProxy.prototype.proxyRequest = function (req, res, buffer) {
271
301
//
272
302
reverseProxy . once ( 'error' , proxyError ) ;
273
303
304
+ //
305
+ // If `req` is aborted, we abort our `reverseProxy` request as well.
306
+ //
307
+ req . on ( 'aborted' , function ( ) {
308
+ reverseProxy . abort ( ) ;
309
+ } ) ;
310
+
274
311
//
275
312
// For each data `chunk` received from the incoming
276
313
// `req` write it to the `reverseProxy` request.
277
314
//
278
315
req . on ( 'data' , function ( chunk ) {
316
+
279
317
if ( ! errState ) {
280
318
var flushed = reverseProxy . write ( chunk ) ;
281
319
if ( ! flushed ) {
@@ -352,16 +390,37 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
352
390
353
391
//
354
392
// Add common proxy headers to the request so that they can
355
- // be availible to the proxy target server:
393
+ // be availible to the proxy target server. If the proxy is
394
+ // part of proxy chain it will append the address:
356
395
//
357
396
// * `x-forwarded-for`: IP Address of the original request
358
397
// * `x-forwarded-proto`: Protocol of the original request
359
398
// * `x-forwarded-port`: Port of the original request.
360
399
//
361
400
if ( this . enable . xforward && req . connection && req . connection . socket ) {
362
- req . headers [ 'x-forwarded-for' ] = req . connection . remoteAddress || req . connection . socket . remoteAddress ;
363
- req . headers [ 'x-forwarded-port' ] = req . connection . remotePort || req . connection . socket . remotePort ;
364
- req . headers [ 'x-forwarded-proto' ] = req . connection . pair ? 'https' : 'http' ;
401
+ if ( req . headers [ 'x-forwarded-for' ] ) {
402
+ var addressToAppend = "," + req . connection . remoteAddress || req . connection . socket . remoteAddress ;
403
+ req . headers [ 'x-forwarded-for' ] += addressToAppend ;
404
+ }
405
+ else {
406
+ req . headers [ 'x-forwarded-for' ] = req . connection . remoteAddress || req . connection . socket . remoteAddress ;
407
+ }
408
+
409
+ if ( req . headers [ 'x-forwarded-port' ] ) {
410
+ var portToAppend = "," + req . connection . remotePort || req . connection . socket . remotePort ;
411
+ req . headers [ 'x-forwarded-port' ] += portToAppend ;
412
+ }
413
+ else {
414
+ req . headers [ 'x-forwarded-port' ] = req . connection . remotePort || req . connection . socket . remotePort ;
415
+ }
416
+
417
+ if ( req . headers [ 'x-forwarded-proto' ] ) {
418
+ var protoToAppend = "," + req . connection . pair ? 'wss' : 'ws' ;
419
+ req . headers [ 'x-forwarded-proto' ] += protoToAppend ;
420
+ }
421
+ else {
422
+ req . headers [ 'x-forwarded-proto' ] = req . connection . pair ? 'wss' : 'ws' ;
423
+ }
365
424
}
366
425
367
426
//
@@ -527,11 +586,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
527
586
//
528
587
outgoing . host = this . target . host ;
529
588
outgoing . port = this . target . port ;
589
+ outgoing . agent = agent ;
530
590
outgoing . method = 'GET' ;
531
591
outgoing . path = req . url ;
532
592
outgoing . headers = req . headers ;
593
+ outgoing . agent = agent ;
533
594
534
- var reverseProxy = agent . appendMessage ( outgoing ) ;
595
+ var reverseProxy = this . target . protocol . request ( outgoing ) ;
535
596
536
597
//
537
598
// On any errors from the `reverseProxy` emit the
@@ -553,7 +614,6 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
553
614
// available to the `upgrade` event. This bookkeeping is not tracked anywhere
554
615
// in nodejs core and is **very** specific to proxying WebSockets.
555
616
//
556
- reverseProxy . agent = agent ;
557
617
reverseProxy . incoming = {
558
618
request : req ,
559
619
socket : socket ,
@@ -568,24 +628,22 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
568
628
// In addition, it's important to note the closure scope here. Since
569
629
// there is no mapping of the socket to the request bound to it.
570
630
//
571
- if ( ! agent . _events || agent . _events [ 'upgrade' ] . length === 0 ) {
572
- agent . on ( 'upgrade' , function ( _ , remoteSocket , head ) {
573
- //
574
- // Prepare the socket for the reverseProxy request and begin to
575
- // stream data between the two sockets. Here it is important to
576
- // note that `remoteSocket._httpMessage === reverseProxy`.
577
- //
578
- _socket ( remoteSocket , true ) ;
579
- onUpgrade ( remoteSocket . _httpMessage , remoteSocket ) ;
580
- } ) ;
581
- }
631
+ reverseProxy . on ( 'upgrade' , function ( _ , remoteSocket , head ) {
632
+ //
633
+ // Prepare the socket for the reverseProxy request and begin to
634
+ // stream data between the two sockets. Here it is important to
635
+ // note that `remoteSocket._httpMessage === reverseProxy`.
636
+ //
637
+ _socket ( remoteSocket , true ) ;
638
+ onUpgrade ( remoteSocket . _httpMessage , remoteSocket ) ;
639
+ } ) ;
582
640
583
641
//
584
642
// If the reverseProxy connection has an underlying socket,
585
643
// then execute the WebSocket handshake.
586
644
//
587
- if ( typeof reverseProxy . socket !== 'undefined' ) {
588
- reverseProxy . socket . on ( 'data' , function handshake ( data ) {
645
+ reverseProxy . once ( ' socket' , function ( revSocket ) {
646
+ revSocket . on ( 'data' , function handshake ( data ) {
589
647
//
590
648
// Ok, kind of harmfull part of code. Socket.IO sends a hash
591
649
// at the end of handshake if protocol === 76, but we need
@@ -618,12 +676,12 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
618
676
socket . write ( sdata ) ;
619
677
var flushed = socket . write ( data ) ;
620
678
if ( ! flushed ) {
621
- reverseProxy . socket . pause ( ) ;
679
+ revSocket . pause ( ) ;
622
680
socket . once ( 'drain' , function ( ) {
623
- try { reverseProxy . socket . resume ( ) }
681
+ try { revSocket . resume ( ) }
624
682
catch ( er ) { console . error ( "reverseProxy.socket.resume error: %s" , er . message ) }
625
683
} ) ;
626
-
684
+
627
685
//
628
686
// Force the `drain` event in 100ms if it hasn't
629
687
// happened on its own.
@@ -638,7 +696,7 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
638
696
// Remove data listener on socket error because the
639
697
// 'handshake' has failed.
640
698
//
641
- reverseProxy . socket . removeListener ( 'data' , handshake ) ;
699
+ revSocket . removeListener ( 'data' , handshake ) ;
642
700
return proxyError ( ex ) ;
643
701
}
644
702
@@ -648,9 +706,9 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
648
706
//
649
707
// Remove data listener now that the 'handshake' is complete
650
708
//
651
- reverseProxy . socket . removeListener ( 'data' , handshake ) ;
709
+ revSocket . removeListener ( 'data' , handshake ) ;
652
710
} ) ;
653
- }
711
+ } ) ;
654
712
655
713
reverseProxy . on ( 'error' , proxyError ) ;
656
714
@@ -689,9 +747,11 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, buffer)
689
747
HttpProxy . prototype . close = function ( ) {
690
748
[ this . forward , this . target ] . forEach ( function ( proxy ) {
691
749
if ( proxy && proxy . agent ) {
692
- proxy . agent . sockets . forEach ( function ( socket ) {
693
- socket . end ( ) ;
694
- } ) ;
750
+ for ( var host in proxy . agent . sockets ) {
751
+ proxy . agent . sockets [ host ] . forEach ( function ( socket ) {
752
+ socket . end ( ) ;
753
+ } ) ;
754
+ }
695
755
}
696
756
} ) ;
697
757
} ;
0 commit comments