diff --git a/lib/http.js b/lib/http.js index 912e3da17091..6be71a3c6bfe 100644 --- a/lib/http.js +++ b/lib/http.js @@ -896,6 +896,10 @@ function Agent(options) { var name = host + ':' + port; if (self.requests[name] && self.requests[name].length) { self.requests[name].shift().onSocket(socket); + if (self.requests[name].length === 0) { + // don't leak + delete this.requests[name]; + } } else { // If there are no pending requests just destroy the // socket and it will get removed from the pool. This @@ -963,11 +967,11 @@ Agent.prototype.removeSocket = function(s, name, host, port) { var index = this.sockets[name].indexOf(s); if (index !== -1) { this.sockets[name].splice(index, 1); + if (this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name]; + } } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name]; - delete this.requests[name]; } if (this.requests[name] && this.requests[name].length) { // If we have pending requests and a socket gets closed a new one diff --git a/test/simple/test-http-client-agent.js b/test/simple/test-http-client-agent.js index edf064a25ce6..f7112e3bfe46 100644 --- a/test/simple/test-http-client-agent.js +++ b/test/simple/test-http-client-agent.js @@ -52,9 +52,12 @@ function request(i) { var socket = req.socket; socket.on('close', function() { ++count; - assert.equal(http.globalAgent.sockets[name].length, max - count); - assert.equal(http.globalAgent.sockets[name].indexOf(socket), -1); - if (count === max) { + if (count < max) { + assert.equal(http.globalAgent.sockets[name].length, max - count); + assert.equal(http.globalAgent.sockets[name].indexOf(socket), -1); + } else { + assert(!http.globalAgent.sockets.hasOwnProperty(name)); + assert(!http.globalAgent.requests.hasOwnProperty(name)); server.close(); } }); diff --git a/test/simple/test-http-keep-alive.js b/test/simple/test-http-keep-alive.js index 061747d3692a..aa03639debc3 100644 --- a/test/simple/test-http-keep-alive.js +++ b/test/simple/test-http-keep-alive.js @@ -22,10 +22,8 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var util = require('util'); var body = 'hello world\n'; -var headers = {'connection': 'keep-alive'}; var server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Length': body.length}); @@ -34,23 +32,37 @@ var server = http.createServer(function(req, res) { }); var connectCount = 0; +var name = 'localhost:' + common.PORT; +var agent = new http.Agent({maxSockets: 1}); +var headers = {'connection': 'keep-alive'}; server.listen(common.PORT, function() { - var agent = new http.Agent({maxSockets: 1}); - var request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { + assert.equal(agent.sockets[name].length, 1); + assert.equal(agent.requests[name].length, 2); }); - request.end(); - request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { + assert.equal(agent.sockets[name].length, 1); + assert.equal(agent.requests[name].length, 1); }); - request.end(); - request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function(response) { + + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { response.on('end', function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + assert.equal(agent.sockets[name].length, 1); + assert(!agent.requests.hasOwnProperty(name)); server.close(); }); }); - request.end(); +}); + +process.on('exit', function() { + assert(!agent.sockets.hasOwnProperty(name)); + assert(!agent.requests.hasOwnProperty(name)); }); diff --git a/test/simple/test-http-upgrade-agent.js b/test/simple/test-http-upgrade-agent.js index f59633318cbf..a87d5e864c4f 100644 --- a/test/simple/test-http-upgrade-agent.js +++ b/test/simple/test-http-upgrade-agent.js @@ -59,6 +59,7 @@ srv.listen(common.PORT, '127.0.0.1', function() { 'upgrade': 'websocket' } }; + var name = options.host + ':' + options.port; var req = http.request(options); req.end(); @@ -73,11 +74,11 @@ srv.listen(common.PORT, '127.0.0.1', function() { 'connection': 'upgrade', 'upgrade': 'websocket' }; assert.deepEqual(expectedHeaders, res.headers); - assert.equal(http.globalAgent.sockets[options.host + ':' + options.port].length, 1); + assert.equal(http.globalAgent.sockets[name].length, 1); process.nextTick(function() { // Make sure this request got removed from the pool. - assert.equal(http.globalAgent.sockets[options.host + ':' + options.port].length, 0); + assert(!http.globalAgent.sockets.hasOwnProperty(name)); socket.end(); srv.close();