Node updated. Some todos.

This commit is contained in:
Norm Rasmussen
2024-09-23 20:52:09 -04:00
parent 8bfaca8375
commit f25622067f
2041 changed files with 124145 additions and 110445 deletions

View File

@ -27,7 +27,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Agent = void 0;
const net = __importStar(require("net"));
const http = __importStar(require("http"));
const https_1 = require("https");
__exportStar(require("./helpers"), exports);
const INTERNAL = Symbol('AgentBaseInternalState');
class Agent extends http.Agent {
@ -64,14 +66,72 @@ class Agent extends http.Agent {
.some((l) => l.indexOf('(https.js:') !== -1 ||
l.indexOf('node:https:') !== -1);
}
// In order to support async signatures in `connect()` and Node's native
// connection pooling in `http.Agent`, the array of sockets for each origin
// has to be updated synchronously. This is so the length of the array is
// accurate when `addRequest()` is next called. We achieve this by creating a
// fake socket and adding it to `sockets[origin]` and incrementing
// `totalSocketCount`.
incrementSockets(name) {
// If `maxSockets` and `maxTotalSockets` are both Infinity then there is no
// need to create a fake socket because Node.js native connection pooling
// will never be invoked.
if (this.maxSockets === Infinity && this.maxTotalSockets === Infinity) {
return null;
}
// All instances of `sockets` are expected TypeScript errors. The
// alternative is to add it as a private property of this class but that
// will break TypeScript subclassing.
if (!this.sockets[name]) {
// @ts-expect-error `sockets` is readonly in `@types/node`
this.sockets[name] = [];
}
const fakeSocket = new net.Socket({ writable: false });
this.sockets[name].push(fakeSocket);
// @ts-expect-error `totalSocketCount` isn't defined in `@types/node`
this.totalSocketCount++;
return fakeSocket;
}
decrementSockets(name, socket) {
if (!this.sockets[name] || socket === null) {
return;
}
const sockets = this.sockets[name];
const index = sockets.indexOf(socket);
if (index !== -1) {
sockets.splice(index, 1);
// @ts-expect-error `totalSocketCount` isn't defined in `@types/node`
this.totalSocketCount--;
if (sockets.length === 0) {
// @ts-expect-error `sockets` is readonly in `@types/node`
delete this.sockets[name];
}
}
}
// In order to properly update the socket pool, we need to call `getName()` on
// the core `https.Agent` if it is a secureEndpoint.
getName(options) {
const secureEndpoint = typeof options.secureEndpoint === 'boolean'
? options.secureEndpoint
: this.isSecureEndpoint(options);
if (secureEndpoint) {
// @ts-expect-error `getName()` isn't defined in `@types/node`
return https_1.Agent.prototype.getName.call(this, options);
}
// @ts-expect-error `getName()` isn't defined in `@types/node`
return super.getName(options);
}
createSocket(req, options, cb) {
const connectOpts = {
...options,
secureEndpoint: this.isSecureEndpoint(options),
};
const name = this.getName(connectOpts);
const fakeSocket = this.incrementSockets(name);
Promise.resolve()
.then(() => this.connect(req, connectOpts))
.then((socket) => {
this.decrementSockets(name, fakeSocket);
if (socket instanceof http.Agent) {
// @ts-expect-error `addRequest()` isn't defined in `@types/node`
return socket.addRequest(req, connectOpts);
@ -79,7 +139,10 @@ class Agent extends http.Agent {
this[INTERNAL].currentSocket = socket;
// @ts-expect-error `createSocket()` isn't defined in `@types/node`
super.createSocket(req, options, cb);
}, cb);
}, (err) => {
this.decrementSockets(name, fakeSocket);
cb(err);
});
}
createConnection() {
const socket = this[INTERNAL].currentSocket;