From bcf11356b3d8a39a0d731164bee9b2acd4c10bae Mon Sep 17 00:00:00 2001 From: Antonio Kukas Date: Thu, 30 May 2019 22:59:59 +0200 Subject: [PATCH] http2: do not register unnecessary listeners PR-URL: https://github.com/nodejs/node/pull/27987 Reviewed-By: Anna Henningsen Reviewed-By: Ruben Bridgewater Reviewed-By: James M Snell --- lib/internal/http2/core.js | 12 +++++- ...-http2-client-request-listeners-warning.js | 41 +++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/parallel/test-http2-client-request-listeners-warning.js diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 0351f55afc6..8c05ff62679 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -160,6 +160,7 @@ const kLocalSettings = Symbol('local-settings'); const kOptions = Symbol('options'); const kOwner = owner_symbol; const kOrigin = Symbol('origin'); +const kPendingRequestCalls = Symbol('kPendingRequestCalls'); const kProceed = Symbol('proceed'); const kProtocol = Symbol('protocol'); const kRemoteSettings = Symbol('remote-settings'); @@ -1413,6 +1414,7 @@ class ServerHttp2Session extends Http2Session { class ClientHttp2Session extends Http2Session { constructor(options, socket) { super(NGHTTP2_SESSION_CLIENT, options, socket); + this[kPendingRequestCalls] = null; } // Submits a new HTTP2 request to the connected peer. Returns the @@ -1482,7 +1484,15 @@ class ClientHttp2Session extends Http2Session { const onConnect = requestOnConnect.bind(stream, headersList, options); if (this.connecting) { - this.once('connect', onConnect); + if (this[kPendingRequestCalls] !== null) { + this[kPendingRequestCalls].push(onConnect); + } else { + this[kPendingRequestCalls] = [onConnect]; + this.once('connect', () => { + this[kPendingRequestCalls].forEach((f) => f()); + this[kPendingRequestCalls] = null; + }); + } } else { onConnect(); } diff --git a/test/parallel/test-http2-client-request-listeners-warning.js b/test/parallel/test-http2-client-request-listeners-warning.js new file mode 100644 index 00000000000..854e9535fd7 --- /dev/null +++ b/test/parallel/test-http2-client-request-listeners-warning.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const http2 = require('http2'); +const EventEmitter = require('events'); + +// This test ensures that a MaxListenersExceededWarning isn't emitted if +// more than EventEmitter.defaultMaxListeners requests are started on a +// ClientHttp2Session before it has finished connecting. + +process.on('warning', common.mustNotCall('A warning was emitted')); + +const server = http2.createServer(); +server.on('stream', (stream) => { + stream.respond(); + stream.end(); +}); + +server.listen(common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + + function request() { + return new Promise((resolve, reject) => { + const stream = client.request(); + stream.on('error', reject); + stream.on('response', resolve); + stream.end(); + }); + } + + const requests = []; + for (let i = 0; i < EventEmitter.defaultMaxListeners + 1; i++) { + requests.push(request()); + } + + Promise.all(requests).then(common.mustCall()).finally(common.mustCall(() => { + server.close(); + client.close(); + })); +}));