@@ -136,7 +136,7 @@ exports.createServer = function () {
136
136
server . on ( 'upgrade' , function ( req , socket , head ) {
137
137
// Tunnel websocket requests too
138
138
139
- proxy . proxyWebSocketRequest ( port , host ) ;
139
+ proxy . proxyWebSocketRequest ( req , socket , head , port , host ) ;
140
140
} ) ;
141
141
}
142
142
@@ -444,91 +444,111 @@ HttpProxy.prototype._forwardRequest = function (req) {
444
444
} ) ;
445
445
} ;
446
446
447
- HttpProxy . prototype . proxyWebSocketRequest = function ( port , server , host , data ) {
448
- var self = this , req = self . req , socket = self . sock , head = self . head ,
449
- headers = new _headers ( req . headers ) , CRLF = '\r\n' ;
450
-
451
- // Will generate clone of headers
452
- // To not change original
453
- function _headers ( headers ) {
454
- var h = { } ;
455
- for ( var i in headers ) {
456
- h [ i ] = headers [ i ] ;
457
- }
458
- return h ;
459
- }
447
+ HttpProxy . prototype . proxyWebSocketRequest = function ( req , socket , head , port , host , buffer ) {
448
+ var self = this , CRLF = '\r\n' ;
460
449
461
450
// WebSocket requests has method = GET
462
- if ( req . method !== 'GET' || headers . upgrade . toLowerCase ( ) !== 'websocket' ) {
451
+ if ( req . method !== 'GET' || req . headers . upgrade . toLowerCase ( ) !== 'websocket' ) {
463
452
// This request is not WebSocket request
464
453
return ;
465
454
}
466
455
467
456
// Turn of all bufferings
468
457
// For server set KeepAlive
469
458
// For client set encoding
470
- function _socket ( socket , server ) {
459
+ function _socket ( socket , keepAlive ) {
471
460
socket . setTimeout ( 0 ) ;
472
461
socket . setNoDelay ( true ) ;
473
- if ( server ) {
462
+ if ( keepAlive ) {
474
463
socket . setKeepAlive ( true , 0 ) ;
475
464
}
476
465
else {
477
466
socket . setEncoding ( 'utf8' ) ;
478
467
}
479
468
}
469
+
470
+ function onUpgrade ( reverseProxy ) {
471
+ var listeners = { } ;
472
+
473
+ // We're now connected to the server, so lets change server socket
474
+ reverseProxy . on ( 'data' , listeners . _r_data = function ( data ) {
475
+ // Pass data to client
476
+ if ( socket . writable ) {
477
+ try {
478
+ socket . write ( data ) ;
479
+ }
480
+ catch ( e ) {
481
+ socket . end ( ) ;
482
+ reverseProxy . end ( ) ;
483
+ }
484
+ }
485
+ } ) ;
486
+
487
+ socket . on ( 'data' , listeners . _data = function ( data ) {
488
+ // Pass data from client to server
489
+ try {
490
+ reverseProxy . write ( data ) ;
491
+ }
492
+ catch ( e ) {
493
+ reverseProxy . end ( ) ;
494
+ socket . end ( ) ;
495
+ }
496
+ } ) ;
497
+
498
+ // Detach event listeners from reverseProxy
499
+ function detach ( ) {
500
+ reverseProxy . removeListener ( 'close' , listeners . _r_close ) ;
501
+ reverseProxy . removeListener ( 'data' , listeners . _r_data ) ;
502
+ socket . removeListener ( 'data' , listeners . _data ) ;
503
+ socket . removeListener ( 'close' , listeners . _close ) ;
504
+ }
505
+
506
+ // Hook disconnections
507
+ reverseProxy . on ( 'end' , listeners . _r_close = function ( ) {
508
+ socket . end ( ) ;
509
+ detach ( ) ;
510
+ } ) ;
511
+
512
+ socket . on ( 'end' , listeners . _close = function ( ) {
513
+ reverseProxy . end ( ) ;
514
+ detach ( ) ;
515
+ } ) ;
516
+ } ;
480
517
481
518
// Client socket
482
519
_socket ( socket ) ;
483
-
484
- // If host is undefined
485
- // Get it from headers
486
- if ( ! host ) {
487
- host = headers . Host ;
488
- }
489
520
490
521
// Remote host address
491
- var remote_host = server + ( port - 80 === 0 ? '' : ':' + port ) ;
522
+ var remoteHost = host + ( port - 80 === 0 ? '' : ':' + port ) ,
523
+ agent = _getAgent ( host , port ) ;
492
524
493
525
// Change headers
494
- headers . Host = remote_host ;
495
- headers . Origin = 'http://' + remote_host ;
496
-
497
- // Open request
498
- var p = manager . getPool ( port , server ) ;
499
-
500
- p . getClient ( function ( client ) {
501
- // Based on 'pool/main.js'
502
- var request = client . request ( 'GET' , req . url , headers ) ;
503
-
504
- var errorListener = function ( error ) {
505
- client . removeListener ( 'error' , errorListener ) ;
506
-
507
- // Remove the client from the pool's available clients since it has errored
508
- p . clients . splice ( p . clients . indexOf ( client ) , 1 ) ;
509
- socket . end ( ) ;
510
- }
511
-
512
- // Not disconnect on update
513
- client . on ( 'upgrade' , function ( request , remote_socket , head ) {
514
- // Prepare socket
515
- _socket ( remote_socket , true ) ;
526
+ req . headers . host = remoteHost ;
527
+ req . headers . origin = 'http://' + host ;
528
+
529
+ var opts = {
530
+ host : host ,
531
+ port : port ,
532
+ agent : agent ,
533
+ method : 'GET' ,
534
+ path : req . url ,
535
+ headers : req . headers
536
+ }
516
537
517
- // Emit event
518
- onUpgrade ( remote_socket ) ;
519
- } ) ;
538
+ // Make the outgoing WebSocket request
539
+ var request = http . request ( opts , function ( ) { } ) ;
540
+
541
+ // Not disconnect on update
542
+ agent . on ( 'upgrade' , function ( request , remoteSocket , head ) {
543
+ // Prepare socket
544
+ _socket ( remoteSocket , true ) ;
520
545
521
- client . on ( 'error' , errorListener ) ;
522
- request . on ( 'response' , function ( response ) {
523
- response . on ( 'end' , function ( ) {
524
- client . removeListener ( 'error' , errorListener ) ;
525
- client . busy = false ;
526
- p . onFree ( client ) ;
527
- } )
528
- } )
529
- client . busy = true ;
530
-
531
- var handshake ;
546
+ // Emit event
547
+ onUpgrade ( remoteSocket ) ;
548
+ } ) ;
549
+
550
+ var handshake ;
551
+ if ( typeof request . socket !== 'undefined' ) {
532
552
request . socket . on ( 'data' , handshake = function ( data ) {
533
553
// Handshaking
534
554
@@ -547,8 +567,8 @@ HttpProxy.prototype.proxyWebSocketRequest = function (port, server, host, data)
547
567
data = data . slice ( Buffer . byteLength ( sdata ) , data . length ) ;
548
568
549
569
// Replace host and origin
550
- sdata = sdata . replace ( remote_host , host )
551
- . replace ( remote_host , host ) ;
570
+ sdata = sdata . replace ( remoteHost , host )
571
+ . replace ( remoteHost , host ) ;
552
572
553
573
try {
554
574
// Write printable
@@ -570,65 +590,19 @@ HttpProxy.prototype.proxyWebSocketRequest = function (port, server, host, data)
570
590
// Remove data listener now that the 'handshake' is complete
571
591
request . socket . removeListener ( 'data' , handshake ) ;
572
592
} ) ;
593
+ }
573
594
574
- // Write upgrade-head
575
- try {
576
- request . write ( head ) ;
577
- }
578
- catch ( e ) {
579
- request . end ( ) ;
580
- socket . end ( ) ;
581
- }
582
- self . unwatch ( socket ) ;
583
- } ) ;
584
-
585
- // Request
586
-
587
- function onUpgrade ( reverse_proxy ) {
588
- var listeners = { } ;
589
-
590
- // We're now connected to the server, so lets change server socket
591
- reverse_proxy . on ( 'data' , listeners . _r_data = function ( data ) {
592
- // Pass data to client
593
- if ( socket . writable ) {
594
- try {
595
- socket . write ( data ) ;
596
- }
597
- catch ( e ) {
598
- socket . end ( ) ;
599
- reverse_proxy . end ( ) ;
600
- }
601
- }
602
- } ) ;
603
-
604
- socket . on ( 'data' , listeners . _data = function ( data ) {
605
- // Pass data from client to server
606
- try {
607
- reverse_proxy . write ( data ) ;
608
- }
609
- catch ( e ) {
610
- reverse_proxy . end ( ) ;
611
- socket . end ( ) ;
612
- }
613
- } ) ;
614
-
615
- // Detach event listeners from reverse_proxy
616
- function detach ( ) {
617
- reverse_proxy . removeListener ( 'close' , listeners . _r_close ) ;
618
- reverse_proxy . removeListener ( 'data' , listeners . _r_data ) ;
619
- socket . removeListener ( 'data' , listeners . _data ) ;
620
- socket . removeListener ( 'close' , listeners . _close ) ;
621
- }
622
-
623
- // Hook disconnections
624
- reverse_proxy . on ( 'end' , listeners . _r_close = function ( ) {
625
- socket . end ( ) ;
626
- detach ( ) ;
627
- } ) ;
628
-
629
- socket . on ( 'end' , listeners . _close = function ( ) {
630
- reverse_proxy . end ( ) ;
631
- detach ( ) ;
632
- } ) ;
633
- } ;
595
+ // Write upgrade-head
596
+ try {
597
+ request . write ( head ) ;
598
+ }
599
+ catch ( ex ) {
600
+ request . end ( ) ;
601
+ socket . end ( ) ;
602
+ }
603
+
604
+ // If we have been passed buffered data, resume it.
605
+ if ( buffer && ! errState ) {
606
+ buffer . resume ( ) ;
607
+ }
634
608
} ;
0 commit comments