[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

This commit is contained in:
indexzero 2011-05-13 17:53:14 -04:00
parent 6c80177340
commit 85223ea080

View File

@ -530,24 +530,30 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
} }
} }
function onUpgrade(reverseProxy) { function onUpgrade(out, reverseProxy) {
if (!out) {
reverseProxy.end();
socket.end();
return;
}
var listeners = {}; var listeners = {};
// We're now connected to the server, so lets change server socket // We're now connected to the server, so lets change server socket
reverseProxy.on('data', listeners._r_data = function(data) { reverseProxy.on('data', listeners._r_data = function(data) {
// Pass data to client // Pass data to client
if (socket.writable) { if (out.incoming.socket.writable) {
try { try {
socket.write(data); out.incoming.socket.write(data);
} }
catch (e) { catch (e) {
socket.end(); out.incoming.socket.end();
reverseProxy.end(); reverseProxy.end();
} }
} }
}); });
socket.on('data', listeners._data = function(data) { out.incoming.socket.on('data', listeners._data = function(data) {
// Pass data from client to server // Pass data from client to server
try { try {
reverseProxy.write(data); reverseProxy.write(data);
@ -562,13 +568,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
function detach() { function detach() {
reverseProxy.removeListener('close', listeners._r_close); reverseProxy.removeListener('close', listeners._r_close);
reverseProxy.removeListener('data', listeners._r_data); reverseProxy.removeListener('data', listeners._r_data);
socket.removeListener('data', listeners._data); out.incoming.socket.removeListener('data', listeners._data);
socket.removeListener('close', listeners._close); out.incoming.socket.removeListener('close', listeners._close);
} }
// Hook disconnections // Hook disconnections
reverseProxy.on('end', listeners._r_close = function() { reverseProxy.on('end', listeners._r_close = function() {
socket.end(); out.incoming.socket.end();
detach(); detach();
}); });
@ -592,27 +598,47 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
outgoing = { outgoing = {
host: options.host, host: options.host,
port: options.port, port: options.port,
agent: agent,
method: 'GET', method: 'GET',
path: req.url, path: req.url,
headers: req.headers headers: req.headers,
}; };
// Make the outgoing WebSocket request // Make the outgoing WebSocket request
var request = http.request(outgoing, function () { }); var request = agent.appendMessage(outgoing);
// Not disconnect on update //
agent.on('upgrade', function(request, remoteSocket, head) { // Here we set the incoming `req`, `socket` and `head` data to the outgoing
// Prepare socket // request so that we can reuse this data later on in the closure scope
_socket(remoteSocket, true); // available to the `upgrade` event. This bookkeeping is not tracked anywhere
// in nodejs core and is **very** specific to proxying WebSockets.
//
request.agent = agent;
request.incoming = {
request: req,
socket: socket,
head: head
};
// Emit event //
onUpgrade(remoteSocket); // If the agent for this particular `host` and `port` combination
}); // is not already listening for the `upgrade` event, then do so once.
// This will force us not to disconnect.
//
// In addition, it's important to note the closure scope here. Since
// there is no mapping of the
//
if (!agent._events || agent._events['upgrade'].length === 0) {
agent.on('upgrade', function (out, remoteSocket, head) {
// Prepare socket
_socket(remoteSocket, true);
// Emit event
onUpgrade(remoteSocket._httpMessage, remoteSocket);
});
}
var handshake;
if (typeof request.socket !== 'undefined') { if (typeof request.socket !== 'undefined') {
request.socket.on('data', handshake = function(data) { request.socket.on('data', function handshake (data) {
// Handshaking // Handshaking
// Ok, kind of harmfull part of code // Ok, kind of harmfull part of code