Skip to content

Commit 1bc4982

Browse files
Fix resource leak by removing abort event listeners on destroy
Not sure that this fix is entirely correct because I may have missed clean up points. Also, needs a test still. Fixes sindresorhus#2160
1 parent 623229f commit 1bc4982

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

source/core/index.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
176176
private _triggerRead: boolean;
177177
declare private _jobs: Array<() => void>;
178178
private _cancelTimeouts: () => void;
179+
private readonly _removeListeners: () => void;
179180
private _nativeResponse?: IncomingMessageWithTimings;
180181
private _flushed: boolean;
181182
private _aborted: boolean;
@@ -199,6 +200,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
199200
this._unproxyEvents = noop;
200201
this._triggerRead = false;
201202
this._cancelTimeouts = noop;
203+
this._removeListeners = noop;
202204
this._jobs = [];
203205
this._flushed = false;
204206
this._requestInitialized = false;
@@ -247,13 +249,20 @@ export default class Request extends Duplex implements RequestEvents<Request> {
247249
return;
248250
}
249251

250-
if (this.options.signal?.aborted) {
251-
this.destroy(new AbortError(this));
252-
}
252+
if (this.options.signal) {
253+
if (this.options.signal.aborted) {
254+
this.destroy(new AbortError(this));
255+
}
253256

254-
this.options.signal?.addEventListener('abort', () => {
255-
this.destroy(new AbortError(this));
256-
});
257+
const abort = () => {
258+
this.destroy(new AbortError(this));
259+
};
260+
261+
this.options.signal.addEventListener('abort', abort);
262+
this._removeListeners = () => {
263+
this.options.signal.removeEventListener('abort', abort);
264+
};
265+
}
257266

258267
// Important! If you replace `body` in a handler with another stream, make sure it's readable first.
259268
// The below is run only once.
@@ -508,6 +517,7 @@ export default class Request extends Duplex implements RequestEvents<Request> {
508517
// Prevent further retries
509518
this._stopRetry();
510519
this._cancelTimeouts();
520+
this._removeListeners();
511521

512522
if (this.options) {
513523
const {body} = this.options;

0 commit comments

Comments
 (0)