From e8c77b13eedcf5d2b8d5d918d83fd46fa34cfbc0 Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Wed, 21 Aug 2019 15:12:48 +0200 Subject: [PATCH] http: fix event listener leak --- lib/_http_client.js | 2 ++ test/parallel/test-http-agent-keepalive.js | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/_http_client.js b/lib/_http_client.js index 67e14fae20ad42..04d5a3f56ee5a2 100644 --- a/lib/_http_client.js +++ b/lib/_http_client.js @@ -506,6 +506,7 @@ function socketOnData(d) { !statusIsInformational(parser.incoming.statusCode)) { socket.removeListener('data', socketOnData); socket.removeListener('end', socketOnEnd); + socket.removeListener('drain', ondrain); freeParser(parser, req, socket); } } @@ -613,6 +614,7 @@ function responseKeepAlive(res, req) { } socket.removeListener('close', socketCloseListener); socket.removeListener('error', socketErrorListener); + socket.removeListener('drain', ondrain); socket.once('error', freeSocketErrorListener); // There are cases where _handle === null. Avoid those. Passing null to // nextTick() will call getDefaultTriggerAsyncId() to retrieve the id. diff --git a/test/parallel/test-http-agent-keepalive.js b/test/parallel/test-http-agent-keepalive.js index 5902c5867968cf..71c4fbd72cbac6 100644 --- a/test/parallel/test-http-agent-keepalive.js +++ b/test/parallel/test-http-agent-keepalive.js @@ -52,7 +52,7 @@ function get(path, callback) { port: server.address().port, agent: agent, path: path - }, callback); + }, callback).on('socket', checkListeners); } function checkDataAndSockets(body) { @@ -134,3 +134,12 @@ server.listen(0, common.mustCall(() => { })); })); })); + +// Check for listener leaks when reusing sockets. +function checkListeners(socket) { + assert.strictEqual(socket.listenerCount('data'), 1); + assert.strictEqual(socket.listenerCount('drain'), 1); + assert.strictEqual(socket.listenerCount('error'), 1); + // Sockets have onReadableStreamEnd. + assert.strictEqual(socket.listenerCount('end'), 2); +}