[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 = {};
// We're now connected to the server, so lets change server socket
reverseProxy.on('data', listeners._r_data = function(data) {
// Pass data to client
if (socket.writable) {
if (out.incoming.socket.writable) {
try {
socket.write(data);
out.incoming.socket.write(data);
}
catch (e) {
socket.end();
out.incoming.socket.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
try {
reverseProxy.write(data);
@ -562,13 +568,13 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
function detach() {
reverseProxy.removeListener('close', listeners._r_close);
reverseProxy.removeListener('data', listeners._r_data);
socket.removeListener('data', listeners._data);
socket.removeListener('close', listeners._close);
out.incoming.socket.removeListener('data', listeners._data);
out.incoming.socket.removeListener('close', listeners._close);
}
// Hook disconnections
reverseProxy.on('end', listeners._r_close = function() {
socket.end();
out.incoming.socket.end();
detach();
});
@ -592,27 +598,47 @@ HttpProxy.prototype.proxyWebSocketRequest = function (req, socket, head, options
outgoing = {
host: options.host,
port: options.port,
agent: agent,
method: 'GET',
path: req.url,
headers: req.headers
headers: req.headers,
};
// 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) {
// Prepare socket
_socket(remoteSocket, true);
//
// Here we set the incoming `req`, `socket` and `head` data to the outgoing
// request so that we can reuse this data later on in the closure scope
// 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') {
request.socket.on('data', handshake = function(data) {
request.socket.on('data', function handshake (data) {
// Handshaking
// Ok, kind of harmfull part of code