diff --git a/.changeset/giant-taxis-breathe.md b/.changeset/giant-taxis-breathe.md new file mode 100644 index 00000000..26afc797 --- /dev/null +++ b/.changeset/giant-taxis-breathe.md @@ -0,0 +1,5 @@ +--- +"@web-std/fetch": patch +--- + +Memory leak caused by unregistered listeners. Solution was copied from a node-fetch pr. diff --git a/packages/fetch/src/fetch.js b/packages/fetch/src/fetch.js index 307ac844..ffd38cae 100644 --- a/packages/fetch/src/fetch.js +++ b/packages/fetch/src/fetch.js @@ -346,13 +346,8 @@ function fixResponseChunkedTransferBadEnding(request, errorCallback) { } }; - socket.prependListener('close', onSocketClose); - - request.on('abort', () => { - socket.removeListener('close', onSocketClose); - }); - - socket.on('data', buf => { + /** @param {Buffer} buf */ + const onData = buf => { properLastChunkReceived = Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0; // Sometimes final 0-length chunk and end of message code are in separate packets @@ -364,7 +359,18 @@ function fixResponseChunkedTransferBadEnding(request, errorCallback) { } previousChunk = buf; - }); + }; + + socket.prependListener('close', onSocketClose); + socket.on('data', onData); + + const removeSocketListeners = () => { + socket.removeListener('close', onSocketClose); + socket.removeListener('data', onData); + } + + request.on('close', removeSocketListeners); + request.on('abort', removeSocketListeners); }); }