aboutsummaryrefslogtreecommitdiffstats
path: root/vanilla/node_modules/undici/lib/core/connect.js
diff options
context:
space:
mode:
authorAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
committerAdam Mathes <adam@adammathes.com>2026-02-13 21:34:48 -0800
commit76cb9c2a39d477a64824a985ade40507e3bbade1 (patch)
tree41e997aa9c6f538d3a136af61dae9424db2005a9 /vanilla/node_modules/undici/lib/core/connect.js
parent819a39a21ac992b1393244a4c283bbb125208c69 (diff)
downloadneko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.gz
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.tar.bz2
neko-76cb9c2a39d477a64824a985ade40507e3bbade1.zip
feat(vanilla): add testing infrastructure and tests (NK-wjnczv)
Diffstat (limited to 'vanilla/node_modules/undici/lib/core/connect.js')
-rw-r--r--vanilla/node_modules/undici/lib/core/connect.js137
1 files changed, 137 insertions, 0 deletions
diff --git a/vanilla/node_modules/undici/lib/core/connect.js b/vanilla/node_modules/undici/lib/core/connect.js
new file mode 100644
index 0000000..a49af91
--- /dev/null
+++ b/vanilla/node_modules/undici/lib/core/connect.js
@@ -0,0 +1,137 @@
+'use strict'
+
+const net = require('node:net')
+const assert = require('node:assert')
+const util = require('./util')
+const { InvalidArgumentError } = require('./errors')
+
+let tls // include tls conditionally since it is not always available
+
+// TODO: session re-use does not wait for the first
+// connection to resolve the session and might therefore
+// resolve the same servername multiple times even when
+// re-use is enabled.
+
+const SessionCache = class WeakSessionCache {
+ constructor (maxCachedSessions) {
+ this._maxCachedSessions = maxCachedSessions
+ this._sessionCache = new Map()
+ this._sessionRegistry = new FinalizationRegistry((key) => {
+ if (this._sessionCache.size < this._maxCachedSessions) {
+ return
+ }
+
+ const ref = this._sessionCache.get(key)
+ if (ref !== undefined && ref.deref() === undefined) {
+ this._sessionCache.delete(key)
+ }
+ })
+ }
+
+ get (sessionKey) {
+ const ref = this._sessionCache.get(sessionKey)
+ return ref ? ref.deref() : null
+ }
+
+ set (sessionKey, session) {
+ if (this._maxCachedSessions === 0) {
+ return
+ }
+
+ this._sessionCache.set(sessionKey, new WeakRef(session))
+ this._sessionRegistry.register(session, sessionKey)
+ }
+}
+
+function buildConnector ({ allowH2, useH2c, maxCachedSessions, socketPath, timeout, session: customSession, ...opts }) {
+ if (maxCachedSessions != null && (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0)) {
+ throw new InvalidArgumentError('maxCachedSessions must be a positive integer or zero')
+ }
+
+ const options = { path: socketPath, ...opts }
+ const sessionCache = new SessionCache(maxCachedSessions == null ? 100 : maxCachedSessions)
+ timeout = timeout == null ? 10e3 : timeout
+ allowH2 = allowH2 != null ? allowH2 : false
+ return function connect ({ hostname, host, protocol, port, servername, localAddress, httpSocket }, callback) {
+ let socket
+ if (protocol === 'https:') {
+ if (!tls) {
+ tls = require('node:tls')
+ }
+ servername = servername || options.servername || util.getServerName(host) || null
+
+ const sessionKey = servername || hostname
+ assert(sessionKey)
+
+ const session = customSession || sessionCache.get(sessionKey) || null
+
+ port = port || 443
+
+ socket = tls.connect({
+ highWaterMark: 16384, // TLS in node can't have bigger HWM anyway...
+ ...options,
+ servername,
+ session,
+ localAddress,
+ ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'],
+ socket: httpSocket, // upgrade socket connection
+ port,
+ host: hostname
+ })
+
+ socket
+ .on('session', function (session) {
+ // TODO (fix): Can a session become invalid once established? Don't think so?
+ sessionCache.set(sessionKey, session)
+ })
+ } else {
+ assert(!httpSocket, 'httpSocket can only be sent on TLS update')
+
+ port = port || 80
+
+ socket = net.connect({
+ highWaterMark: 64 * 1024, // Same as nodejs fs streams.
+ ...options,
+ localAddress,
+ port,
+ host: hostname
+ })
+ if (useH2c === true) {
+ socket.alpnProtocol = 'h2'
+ }
+ }
+
+ // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket
+ if (options.keepAlive == null || options.keepAlive) {
+ const keepAliveInitialDelay = options.keepAliveInitialDelay === undefined ? 60e3 : options.keepAliveInitialDelay
+ socket.setKeepAlive(true, keepAliveInitialDelay)
+ }
+
+ const clearConnectTimeout = util.setupConnectTimeout(new WeakRef(socket), { timeout, hostname, port })
+
+ socket
+ .setNoDelay(true)
+ .once(protocol === 'https:' ? 'secureConnect' : 'connect', function () {
+ queueMicrotask(clearConnectTimeout)
+
+ if (callback) {
+ const cb = callback
+ callback = null
+ cb(null, this)
+ }
+ })
+ .on('error', function (err) {
+ queueMicrotask(clearConnectTimeout)
+
+ if (callback) {
+ const cb = callback
+ callback = null
+ cb(err)
+ }
+ })
+
+ return socket
+ }
+}
+
+module.exports = buildConnector