From 6ab28486c3042bb1fec7f7714910def37c3a81ac Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Sat, 24 Aug 2019 20:42:11 +0200 Subject: http: reset parser.incoming when server request is finished This resolves a memory leak for keep-alive connections and does not regress in the way that 779a05d5d1bfe2eeb05386f did by waiting for the incoming request to be finished before releasing the `parser.incoming` object. Refs: https://github.com/nodejs/node/pull/28646 Refs: https://github.com/nodejs/node/pull/29263 Fixes: https://github.com/nodejs/node/issues/9668 PR-URL: https://github.com/nodejs/node/pull/29297 Reviewed-By: Luigi Pinca Reviewed-By: Matteo Collina --- lib/_http_server.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib/_http_server.js') diff --git a/lib/_http_server.js b/lib/_http_server.js index 862b7c970b..6dc29c855e 100644 --- a/lib/_http_server.js +++ b/lib/_http_server.js @@ -611,6 +611,19 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) { } } +function clearIncoming(req) { + req = req || this; + const parser = req.socket && req.socket.parser; + // Reset the .incoming property so that the request object can be gc'ed. + if (parser && parser.incoming === req) { + if (req.readableEnded) { + parser.incoming = null; + } else { + req.on('end', clearIncoming); + } + } +} + function resOnFinish(req, res, socket, state, server) { // Usually the first incoming element should be our request. it may // be that in the case abortIncoming() was called that the incoming @@ -618,6 +631,7 @@ function resOnFinish(req, res, socket, state, server) { assert(state.incoming.length === 0 || state.incoming[0] === req); state.incoming.shift(); + clearIncoming(req); // If the user never called req.read(), and didn't pipe() or // .resume() or .on('data'), then we call req._dump() so that the -- cgit v1.2.3