-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
https: fix memory leak with https.request() #8647
Conversation
43ac439
to
0891876
Compare
options.servername = options.host; | ||
const hostHeader = req.getHeader('host'); | ||
if (hostHeader) { | ||
options.servername = hostHeader.replace(/:.*$/, ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer just using hostHeader.slice()
and hostHeader.indexOf()
, but if others are not comfortable with that, at the very least the regex should be /:[\s\S]*$/
to match any character (including newlines).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left the hostHeader
cleanup intentionally unmodified to match the original feature implemented PR #1110
I did not want to fix two unrelated issues in single PR dedicated to memory leak.
ca: options.ca, | ||
agent: agent | ||
}, common.mustCall((res) => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove the extra blank lines at lines 37, 44, 48, 54, and 56.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra blank lines removed
0891876
to
b6b452c
Compare
LGTM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
LGTM |
FreeBSD CI failed due to force pushed commit New CI run: https://ci.nodejs.org/job/node-test-pull-request/4108/ |
I'm going to add lts-agenda label because this leak affects current LTS release too. |
CI before landing: https://ci.nodejs.org/job/node-test-pull-request/4127/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
// To verify that no leaks occur, check that no entries | ||
// exist in agent.sockets pool after both request and socket | ||
// has been closed. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this line should also be removed? #8647 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Removed extra line.
If calling `https.request()` with `options.headers.host` defined and `options.servername` undefined, `https.Agent.createSocket` mutates connection `options` after `https.Agent.addRequest` has created empty socket pool array with mismatching connection name. This results in two socket pool arrays being created and only the last one gets eventually deleted by `removeSocket` - causing a memory leak. This commit fixes the leak by making sure that `addRequest` does the same modifications to `options` object as the `createSocket`. `createSocket` is intentionally left unmodified to prevent userland regressions. Test case included. Fixes: nodejs#6687
b6b452c
to
4d68ae2
Compare
Trying CI again due to the AIX error: https://ci.nodejs.org/job/node-test-pull-request/4179/ |
If CI is green, I'll land this. |
I'll start landing this:
|
If calling `https.request()` with `options.headers.host` defined and `options.servername` undefined, `https.Agent.createSocket` mutates connection `options` after `https.Agent.addRequest` has created empty socket pool array with mismatching connection name. This results in two socket pool arrays being created and only the last one gets eventually deleted by `removeSocket` - causing a memory leak. This commit fixes the leak by making sure that `addRequest` does the same modifications to `options` object as the `createSocket`. `createSocket` is intentionally left unmodified to prevent userland regressions. Test case included. PR-URL: nodejs#8647 Fixes: nodejs#6687 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Jackson Tian <[email protected]> Reviewed-By: James M Snell <[email protected]>
landed in db5a879 |
@imyller I'm removing the agenda label for right now as there does not appear to be anything controversial about this change. After it has lived in a release for at least two weeks we can backport |
If calling `https.request()` with `options.headers.host` defined and `options.servername` undefined, `https.Agent.createSocket` mutates connection `options` after `https.Agent.addRequest` has created empty socket pool array with mismatching connection name. This results in two socket pool arrays being created and only the last one gets eventually deleted by `removeSocket` - causing a memory leak. This commit fixes the leak by making sure that `addRequest` does the same modifications to `options` object as the `createSocket`. `createSocket` is intentionally left unmodified to prevent userland regressions. Test case included. PR-URL: #8647 Fixes: #6687 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Jackson Tian <[email protected]> Reviewed-By: James M Snell <[email protected]>
If calling `https.request()` with `options.headers.host` defined and `options.servername` undefined, `https.Agent.createSocket` mutates connection `options` after `https.Agent.addRequest` has created empty socket pool array with mismatching connection name. This results in two socket pool arrays being created and only the last one gets eventually deleted by `removeSocket` - causing a memory leak. This commit fixes the leak by making sure that `addRequest` does the same modifications to `options` object as the `createSocket`. `createSocket` is intentionally left unmodified to prevent userland regressions. Test case included. PR-URL: #8647 Fixes: #6687 Reviewed-By: Fedor Indutny <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Jackson Tian <[email protected]> Reviewed-By: James M Snell <[email protected]>
Checklist
make -j4 test
(UNIX), orvcbuild test nosign
(Windows) passesAffected core subsystem(s)
https
Description of change
If calling
https.request()
withoptions.headers.host
defined andoptions.servername
undefined,https.Agent.createSocket
mutates connectionoptions
afterhttps.Agent.addRequest
has created empty socket pool array with mismatching connection name.This results in two socket pool arrays being created and only the last one gets eventually deleted by
removeSocket
- effectively causing a memory leak.This commit fixes the leak by making sure that
addRequest
does the same modifications tooptions
object as thecreateSocket
.createSocket
is intentionally left unmodified to prevent userland regressions.Test case included.
Fixes: #6687
/cc @nodejs/http @nodejs/crypto