diff --git a/lib/node-http-proxy.js b/lib/node-http-proxy.js index f2054ac..e9a383e 100644 --- a/lib/node-http-proxy.js +++ b/lib/node-http-proxy.js @@ -32,6 +32,7 @@ exports.HttpProxy = function () { this.emitter = new(events.EventEmitter); this.events = {}; this.listeners = {}; + this.collisions = {}; }; exports.createServer = function () { @@ -83,34 +84,55 @@ exports.HttpProxy.prototype = { watch: function (req, res) { var self = this; - this.events[req] = []; + // Create a unique id for this request so + // we can reference it later. + var id = new Date().getTime().toString(); - this.listeners[req] = { + // If we get a request in the same tick, we need to + // append to the id so it stays unique. + if(typeof this.collisions[id] === 'undefined') { + this.collisions[id] = 0; + } + else { + this.collisions[id]++; + id += this.collisions[id]; + } + + req.id = id; + this.events[req.id] = []; + + this.listeners[req.id] = { onData: function () { - self.events[req].push(['data'].concat(self.toArray(arguments))); + self.events[req.id].push(['data'].concat(self.toArray(arguments))); }, onEnd: function () { - self.events[req].push(['end'].concat(self.toArray(arguments))); + self.events[req.id].push(['end'].concat(self.toArray(arguments))); } }; - req.addListener('data', this.listeners[req].onData); - req.addListener('end', this.listeners[req].onEnd); + req.addListener('data', this.listeners[req.id].onData); + req.addListener('end', this.listeners[req.id].onEnd); + }, unwatch: function (req, res) { - req.removeListener('data', this.listeners[req].onData); - req.removeListener('end', this.listeners[req].onEnd); - + req.removeListener('data', this.listeners[req.id].onData); + req.removeListener('end', this.listeners[req.id].onEnd); + // Rebroadcast any events that have been buffered - while(this.events[req].length > 0) { - var args = this.events[req].shift(); + while(this.events[req.id].length > 0) { + var args = this.events[req.id].shift(); req.emit.apply(req, args); } - + // Remove the data from the event and listeners hashes - delete this.listeners[req]; - delete this.events[req]; + delete this.listeners[req.id]; + delete this.events[req.id]; + + // If this request id is a base time, delete it + if (typeof this.collisions[req.id] !== 'undefined') { + delete this.collisions[req.id]; + } }, proxyRequest: function (port, server, req, res) { @@ -135,11 +157,12 @@ exports.HttpProxy.prototype = { res.end(); }); + // Add a listener for the reverse_proxy response event reverse_proxy.addListener('response', function (response) { // Set the response headers of the client response res.writeHead(response.statusCode, response.headers); - + // Add event handler for the proxied response in chunks response.addListener('data', function (chunk) { if(req.method !== 'HEAD') {