From d602c7a2ed80c978f94bd63f76b54d0843bea6cf Mon Sep 17 00:00:00 2001 From: James Ide Date: Fri, 20 Jul 2018 17:25:02 -0700 Subject: [PATCH] http2: release request()'s "connect" event listener after it runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `Http2Session#request()` method internally listens to the "connect" event if the session has not yet established a connection so that the actual request can be sent after the connection has been established. This commit removes the event listener after it runs and carries out the request and is no longer needed. In practice this shouldn't affect the behavior of the session object since the "connect" event fires only once anyway, but removing the listener releases its references. The rest of this class subscribes to the "connect" event with `once` instead of `on` as well. Tested by adding a new test that ensures `Http2Session#request()` is called before the connection is established, indicated by a "connect" listener that is run. The test also ensures all "connect" listeners are removed after the connection is established. Backport-PR-URL: https://github.com/nodejs/node/pull/22850 PR-URL: https://github.com/nodejs/node/pull/21916 Reviewed-By: Michaƫl Zasso Reviewed-By: Trivikram Kamat Reviewed-By: Anna Henningsen Reviewed-By: Anatoli Papirovski Reviewed-By: Colin Ihrig Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- lib/internal/http2/core.js | 2 +- ...t-http2-request-remove-connect-listener.js | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-http2-request-remove-connect-listener.js diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 9beb8833a297fb..e496c3a87fd3ee 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -1384,7 +1384,7 @@ class ClientHttp2Session extends Http2Session { const onConnect = requestOnConnect.bind(stream, headersList, options); if (this.connecting) { - this.on('connect', onConnect); + this.once('connect', onConnect); } else { onConnect(); } diff --git a/test/parallel/test-http2-request-remove-connect-listener.js b/test/parallel/test-http2-request-remove-connect-listener.js new file mode 100644 index 00000000000000..61de140c225144 --- /dev/null +++ b/test/parallel/test-http2-request-remove-connect-listener.js @@ -0,0 +1,28 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); + + +const server = http2.createServer(); +server.on('stream', common.mustCall((stream) => { + stream.respond(); + stream.end(); +})); + +server.listen(0, common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + client.once('connect', common.mustCall()); + + req.on('response', common.mustCall(() => { + assert.strictEqual(client.listenerCount('connect'), 0); + })); + req.on('close', common.mustCall(() => { + server.close(); + client.close(); + })); +}));