agent-base
Advanced tools
Comparing version 7.1.0 to 7.1.1
@@ -30,3 +30,5 @@ "use strict"; | ||
exports.Agent = void 0; | ||
const net = __importStar(require("net")); | ||
const http = __importStar(require("http")); | ||
const https_1 = require("https"); | ||
__exportStar(require("./helpers"), exports); | ||
@@ -68,2 +70,57 @@ const INTERNAL = Symbol('AgentBaseInternalState'); | ||
} | ||
// 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) { | ||
@@ -74,5 +131,8 @@ const connectOpts = { | ||
}; | ||
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) { | ||
@@ -85,3 +145,6 @@ // @ts-expect-error `addRequest()` isn't defined in `@types/node` | ||
super.createSocket(req, options, cb); | ||
}, cb); | ||
}, (err) => { | ||
this.decrementSockets(name, fakeSocket); | ||
cb(err); | ||
}); | ||
} | ||
@@ -88,0 +151,0 @@ createConnection() { |
@@ -31,2 +31,5 @@ /// <reference types="node" /> | ||
isSecureEndpoint(options?: AgentConnectOpts): boolean; | ||
private incrementSockets; | ||
private decrementSockets; | ||
getName(options: AgentConnectOpts): string; | ||
createSocket(req: http.ClientRequest, options: AgentConnectOpts, cb: (err: Error | null, s?: Duplex) => void): void; | ||
@@ -33,0 +36,0 @@ createConnection(): Duplex; |
@@ -30,3 +30,5 @@ "use strict"; | ||
exports.Agent = void 0; | ||
const net = __importStar(require("net")); | ||
const http = __importStar(require("http")); | ||
const https_1 = require("https"); | ||
__exportStar(require("./helpers"), exports); | ||
@@ -68,2 +70,57 @@ const INTERNAL = Symbol('AgentBaseInternalState'); | ||
} | ||
// 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) { | ||
@@ -74,5 +131,8 @@ const connectOpts = { | ||
}; | ||
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) { | ||
@@ -85,3 +145,6 @@ // @ts-expect-error `addRequest()` isn't defined in `@types/node` | ||
super.createSocket(req, options, cb); | ||
}, cb); | ||
}, (err) => { | ||
this.decrementSockets(name, fakeSocket); | ||
cb(err); | ||
}); | ||
} | ||
@@ -88,0 +151,0 @@ createConnection() { |
{ | ||
"name": "agent-base", | ||
"version": "7.1.0", | ||
"version": "7.1.1", | ||
"description": "Turn a function into an `http.Agent` instance", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
@@ -65,28 +65,2 @@ agent-base | ||
License | ||
------- | ||
(The MIT License) | ||
Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> | ||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
'Software'), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
[http-proxy-agent]: ../http-proxy-agent | ||
@@ -93,0 +67,0 @@ [https-proxy-agent]: ../https-proxy-agent |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
31249
12
467
70
8