There is no way to disable SNI extension when sending a request to HTTPS
server. Setting `options.servername` to a falsy value would make Node.js
core override it with either hostname or ip address.
This change introduces a way to disable SNI completely if this is
required for user's application. Setting `options.servername` to ``
in `https.request` would disable overrides and thus disable the
extension.
PR-URL: https://github.com/nodejs/node/pull/27316
Reviewed-By: Steven R Loomis <srloomis@us.ibm.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: Anatoli Papirovski <apapirovski@mac.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Rich Trott <rtrott@gmail.com>
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This adds missing async_hooks destroy calls for sockets (in
_http_agent.js) and HTTP parsers. We need to emit a destroy in
AsyncWrap#AsyncReset before assigning a new async_id when the instance
has already been in use and is being recycled, because in that case, we
have already emitted an init for the "old" async_id.
This also removes a duplicated init call for HTTP parser: Each time a
new parser was created, AsyncReset was being called via the C++ Parser
class constructor (super constructor AsyncWrap) and also via
Parser::Reinitialize.
PR-URL: https://github.com/nodejs/node/pull/23272
Fixes: https://github.com/nodejs/node/issues/19859
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Instead of exposing internals of async_hooks & async_wrap throughout
the code base, create necessary helper methods within the internal
async_hooks that allows easy usage by Node.js internals. This stops
every single internal user of async_hooks from importing a ton of
functions, constants and internal Aliased Buffers from C++ async_wrap.
Adds functions initHooksExist, afterHooksExist, and destroyHooksExist
to determine whether the related emit methods need to be triggered.
Adds clearDefaultTriggerAsyncId and clearAsyncIdStack on the JS side
as an alternative to always calling C++.
Moves async_id_symbol and trigger_async_id_symbol to internal
async_hooks as they are never used in C++.
Renames newUid to newAsyncId for added clarity of its purpose.
Adjusts usage throughout the codebase, as well as in a couple of tests.
PR-URL: https://github.com/nodejs/node/pull/18720
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Makes `Connection: keep-alive` behave correctly when making client
connections to UNIX domain sockets.
Prior to this, connections would never be re-used, but the keep-alive
would cause the connections to stick around until they time out. This
would lead to an eventual EMFILE error due to all the connections
staying open. This was due to http.Agent not properly supporting UNIX
domain sockets.
PR-URL: https://github.com/nodejs/node/pull/13214
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Reviewed-By: James M Snell <jasnell@gmail.com>
Introduce two overridable `Agent` methods:
* `keepSocketAlive(socket)`
* `reuseSocket(socket, req)`
These methods can be overridden by particular `Agent` class child to
make keep-alive behavior customizable.
Motivation: destroy persisted sockets after some configurable timeout.
It is very non-trivial to do it with available primitives. Such program
will most likely need to poke with undocumented events and methods of
`Agent`. With introduced API such behavior is easy to implement.
PR-URL: https://github.com/nodejs/node/pull/13005
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Keepalive sockets that are returned to the agent's freesocket pool were
previously capturing a reference to the ClientRequest that initiated the
request.
This commit eliminates that by moving the installation of the socket
listeners to a different function.
PR-URL: https://github.com/nodejs/node/pull/10134
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
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: https://github.com/nodejs/node/pull/8647
Fixes: https://github.com/nodejs/node/issues/6687
Reviewed-By: Fedor Indutny <fedor.indutny@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: Jackson Tian <shvyo1987@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
SSL sockets leak whenever keep alive is enabled, ca option is set in
the global agent, and requests are sent without the ca property.
In the following case at Agent.prototype.createSocket a socket will
be created with a hashtag name that includes data from the global
agents’ ca property.
On subsequent requests at Agent.prototype.addRequest we do not find
the free socket, because the hashtag name generated there does not
take into account the global agents’ ca property, thus creating a new
socket and leaving the first socket to timeout. closes: #5699
PR-URL: https://github.com/nodejs/node/pull/5713
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
This commit adds support for async createConnection()
implementations and is still backwards compatible with
synchronous createConnection() implementations.
This commit also makes the http client more friendly with
generic stream objects produced by createConnection() by
checking stream.writable instead of stream.destroyed as the
latter is currently a net.Socket-ism and not set by the core
stream implementations.
PR-URL: https://github.com/nodejs/node/pull/4638
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
socket.destroy() triggers a 'close' event from the socket which triggers
the onClose handler of HTTPAgent which calls self.removeSocket(). So by
calling self.removeSocket() prior to socket.destroy() we end up with two
calls to self.removeSocket().
If there are pending requests, removeSocket ends up creating a new socket.
So if there are pending requests, each time a request completes, we tear
down one socket and create two more. So the total number of sockets grows
exponentially and without regard for any maxSockets settings. This was
noticed in https://github.com/nodejs/node/issues/4050. Let's get rid of
the extra calls to removeSocket so we only call it once per completed
request.
PR-URL: https://github.com/nodejs/node/pull/4172
Reviewed-By: Brian White <mscdex@mscdex.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Refactor out the if/else statement checking for option.host.
Add whitespace to make concatenation chunks more readable and
consistent with the https version of Agent.getName().
PR-URL: https://github.com/nodejs/node/pull/2825
Reviewed-By: Julian Duque <julianduquej@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
This commit fixes agent.getName(), which returned an extra colon
according to the docs, and adds tests (it was previously not unit
tested).
PR-URL: https://github.com/nodejs/io.js/pull/1617
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
The copyright and license notice is already in the LICENSE file. There
is no justifiable reason to also require that it be included in every
file, since the individual files are not individually distributed except
as part of the entire package.
Between `ClientRequest` and `Agent`. The circular require was doing
weird things at load time, like making the `globalAgent` property
be `undefined` from within the context of the "_http_client"
module.
Removing the circular dependency completely fixes this.
This commit effectively removes the undocumented `Agent#request()`
and `Agent#get()` functions.