From 3e9191513d0f6db4421640e4b50b773dc3a02eaa Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Fri, 14 Apr 2023 17:25:25 +0200 Subject: [PATCH] fix: don't leak socket if client is destroyed while connecting (#2058) * fix: don't leak socket if client is destroyed will connecting * Update types/connector.d.ts --- lib/client.js | 12 +++++++++++- test/connect-abort.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 test/connect-abort.js diff --git a/lib/client.js b/lib/client.js index 370e89b89cf..e630212fa79 100644 --- a/lib/client.js +++ b/lib/client.js @@ -21,7 +21,8 @@ const { InformationalError, BodyTimeoutError, HTTPParserError, - ResponseExceededMaxSizeError + ResponseExceededMaxSizeError, + ClientDestroyedError } = require('./core/errors') const buildConnector = require('./core/connect') const { @@ -1083,6 +1084,11 @@ async function connect (client) { }) }) + if (client.destroyed) { + util.destroy(socket.on('error', () => {}), new ClientDestroyedError()) + return + } + if (!llhttpInstance) { llhttpInstance = await llhttpPromise llhttpPromise = null @@ -1125,6 +1131,10 @@ async function connect (client) { } client.emit('connect', client[kUrl], [client]) } catch (err) { + if (client.destroyed) { + return + } + client[kConnecting] = false if (channels.connectError.hasSubscribers) { diff --git a/test/connect-abort.js b/test/connect-abort.js new file mode 100644 index 00000000000..6eb36243866 --- /dev/null +++ b/test/connect-abort.js @@ -0,0 +1,28 @@ +'use strict' + +const { test } = require('tap') +const { Client } = require('..') +const { PassThrough } = require('stream') + +test(t => { + t.plan(2) + + const client = new Client('http://localhost:1234', { + connect: (_, cb) => { + client.destroy() + cb(null, new PassThrough({ + destroy (err, cb) { + t.same(err?.name, 'ClientDestroyedError') + cb(null) + } + })) + } + }) + + client.request({ + path: '/', + method: 'GET' + }, (err, data) => { + t.same(err?.name, 'ClientDestroyedError') + }) +})