Skip to content

Commit 85223ea

Browse files
committed
[fix] Manage bookkeeping for incoming requests to the underlying sockets behind reverse proxied websocket events. Only use the appropriate variables in the closure scope of the upgrade event from this bookkeeping
1 parent 6c80177 commit 85223ea

File tree

1 file changed

+47
-21
lines changed

1 file changed

+47
-21
lines changed

lib/node-http-proxy.js

+47-21
Original file line numberDiff line numberDiff line change
@@ -530,24 +530,30 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
530530
}
531531
}
532532

533-
function onUpgrade(reverseProxy) {
533+
function onUpgrade(out, reverseProxy) {
534+
if (!out) {
535+
reverseProxy.end();
536+
socket.end();
537+
return;
538+
}
539+
534540
var listeners = {};
535541

536542
// We're now connected to the server, so lets change server socket
537543
reverseProxy.on('data', listeners._r_data = function(data) {
538544
// Pass data to client
539-
if (socket.writable) {
545+
if (out.incoming.socket.writable) {
540546
try {
541-
socket.write(data);
547+
out.incoming.socket.write(data);
542548
}
543549
catch (e) {
544-
socket.end();
550+
out.incoming.socket.end();
545551
reverseProxy.end();
546552
}
547553
}
548554
});
549555

550-
socket.on('data', listeners._data = function(data) {
556+
out.incoming.socket.on('data', listeners._data = function(data) {
551557
// Pass data from client to server
552558
try {
553559
reverseProxy.write(data);
@@ -562,13 +568,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
562568
function detach() {
563569
reverseProxy.removeListener('close', listeners._r_close);
564570
reverseProxy.removeListener('data', listeners._r_data);
565-
socket.removeListener('data', listeners._data);
566-
socket.removeListener('close', listeners._close);
571+
out.incoming.socket.removeListener('data', listeners._data);
572+
out.incoming.socket.removeListener('close', listeners._close);
567573
}
568574

569575
// Hook disconnections
570576
reverseProxy.on('end', listeners._r_close = function() {
571-
socket.end();
577+
out.incoming.socket.end();
572578
detach();
573579
});
574580

@@ -592,27 +598,47 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
592598
outgoing = {
593599
host: options.host,
594600
port: options.port,
595-
agent: agent,
596601
method: 'GET',
597602
path: req.url,
598-
headers: req.headers
603+
headers: req.headers,
599604
};
600605

601606
// Make the outgoing WebSocket request
602-
var request = http.request(outgoing, function () { });
603-
604-
// Not disconnect on update
605-
agent.on('upgrade', function(request, remoteSocket, head) {
606-
// Prepare socket
607-
_socket(remoteSocket, true);
607+
var request = agent.appendMessage(outgoing);
608608

609-
// Emit event
610-
onUpgrade(remoteSocket);
611-
});
609+
//
610+
// Here we set the incoming `req`, `socket` and `head` data to the outgoing
611+
// request so that we can reuse this data later on in the closure scope
612+
// available to the `upgrade` event. This bookkeeping is not tracked anywhere
613+
// in nodejs core and is **very** specific to proxying WebSockets.
614+
//
615+
request.agent = agent;
616+
request.incoming = {
617+
request: req,
618+
socket: socket,
619+
head: head
620+
};
621+
622+
//
623+
// If the agent for this particular `host` and `port` combination
624+
// is not already listening for the `upgrade` event, then do so once.
625+
// This will force us not to disconnect.
626+
//
627+
// In addition, it's important to note the closure scope here. Since
628+
// there is no mapping of the
629+
//
630+
if (!agent._events || agent._events['upgrade'].length === 0) {
631+
agent.on('upgrade', function (out, remoteSocket, head) {
632+
// Prepare socket
633+
_socket(remoteSocket, true);
634+
635+
// Emit event
636+
onUpgrade(remoteSocket._httpMessage, remoteSocket);
637+
});
638+
}
612639

613-
var handshake;
614640
if (typeof request.socket !== 'undefined') {
615-
request.socket.on('data', handshake = function(data) {
641+
request.socket.on('data', function handshake (data) {
616642
// Handshaking
617643

618644
// Ok, kind of harmfull part of code

0 commit comments

Comments
 (0)