http: fix parser memory leak on double response #60187
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Fixes a memory leak in the HTTP client when a server sends two complete HTTP responses in a single TCP chunk. The HTTP parser object is never freed in this scenario, leading to unbounded memory growth.
Root Cause Analysis
When a server sends malformed double responses:
First response processing (lib/_http_client.js:520-530):
req.res = parser.incoming
(the first response object)parserOnIncomingClient()
which emits 'response' eventSecond response detection (lib/_http_client.js:691-695):
parser.incoming
object for second responseif (req.res)
checkParser cleanup failure (lib/_http_client.js:571-575):
socketOnData()
checks:parser.incoming
now points to the incomplete second responseparser.incoming.complete
is false foreverThe Fix
Immediately free the parser when double response is detected, before destroying the socket:
This ensures the parser is properly released even though it's in an invalid state with an incomplete second response.
Evidence of Memory Leak
The included test case demonstrates the leak:
Without the fix:
With the fix:
Test Plan
The test creates a TCP server that sends two complete HTTP responses in a single write:
Runs 1000 iterations with forced GC every 100 iterations, then verifies memory growth is < 10 MB.
Checklist
test/parallel/test-http-client-double-response-leak.js
--expose-gc
flag for memory verificationFixes: #60025