agent-base
Advanced tools
Comparing version 5.1.1 to 6.0.0
/// <reference types="node" /> | ||
import net from 'net'; | ||
import http from 'http'; | ||
import https from 'https'; | ||
import { Duplex } from 'stream'; | ||
import { EventEmitter } from 'events'; | ||
declare function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent; | ||
declare namespace createAgent { | ||
var prototype: Agent; | ||
} | ||
declare function createAgent(callback: createAgent.AgentCallback, opts?: createAgent.AgentOptions): createAgent.Agent; | ||
declare namespace createAgent { | ||
var prototype: Agent; | ||
} | ||
declare namespace createAgent { | ||
type ClientRequest = http.ClientRequest & { | ||
interface ClientRequest extends http.ClientRequest { | ||
_last?: boolean; | ||
_hadError?: boolean; | ||
method: string; | ||
}; | ||
type AgentCallbackReturn = net.Socket | createAgent.Agent | http.Agent; | ||
} | ||
interface AgentRequestOptions { | ||
host?: string; | ||
path?: string; | ||
port: number; | ||
} | ||
interface HttpRequestOptions extends AgentRequestOptions, Omit<http.RequestOptions, keyof AgentRequestOptions> { | ||
secureEndpoint: false; | ||
} | ||
interface HttpsRequestOptions extends AgentRequestOptions, Omit<https.RequestOptions, keyof AgentRequestOptions> { | ||
secureEndpoint: true; | ||
} | ||
type RequestOptions = HttpRequestOptions | HttpsRequestOptions; | ||
type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent; | ||
type AgentCallbackReturn = Duplex | AgentLike; | ||
type AgentCallbackCallback = (err: Error | null | undefined, socket: createAgent.AgentCallbackReturn) => void; | ||
type AgentCallbackPromise = (req: createAgent.ClientRequest, opts: createAgent.RequestOptions) => createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>; | ||
type AgentCallback = typeof Agent.prototype.callback; | ||
type AgentOptions = http.AgentOptions & {}; | ||
type RequestOptions = http.RequestOptions & { | ||
port: number; | ||
secureEndpoint: boolean; | ||
type AgentOptions = { | ||
timeout?: number; | ||
}; | ||
@@ -37,7 +44,10 @@ /** | ||
timeout: number | null; | ||
options?: createAgent.AgentOptions; | ||
maxFreeSockets: number; | ||
maxSockets: number; | ||
sockets: net.Socket[]; | ||
requests: http.ClientRequest[]; | ||
sockets: { | ||
[key: string]: net.Socket[]; | ||
}; | ||
requests: { | ||
[key: string]: http.IncomingMessage[]; | ||
}; | ||
private promisifiedCallback?; | ||
@@ -44,0 +54,0 @@ private explicitDefaultPort?; |
@@ -6,9 +6,8 @@ "use strict"; | ||
const events_1 = require("events"); | ||
const debug_1 = __importDefault(require("debug")); | ||
const promisify_1 = __importDefault(require("./promisify")); | ||
function isAgentBase(v) { | ||
const debug = debug_1.default('agent-base'); | ||
function isAgent(v) { | ||
return Boolean(v) && typeof v.addRequest === 'function'; | ||
} | ||
function isHttpAgent(v) { | ||
return Boolean(v) && typeof v.addRequest === 'function'; | ||
} | ||
function isSecureEndpoint() { | ||
@@ -34,4 +33,2 @@ const { stack } = new Error(); | ||
super(); | ||
// The callback gets promisified lazily | ||
this.promisifiedCallback = undefined; | ||
let opts = _opts; | ||
@@ -44,3 +41,3 @@ if (typeof callback === 'function') { | ||
} | ||
// timeout for the socket to be returned from the callback | ||
// Timeout for the socket to be returned from the callback | ||
this.timeout = null; | ||
@@ -50,7 +47,8 @@ if (opts && typeof opts.timeout === 'number') { | ||
} | ||
this.options = opts || {}; | ||
// These aren't actually used by `agent-base`, but are required | ||
// for the TypeScript definition files in `@types/node` :/ | ||
this.maxFreeSockets = 1; | ||
this.maxSockets = 1; | ||
this.sockets = []; | ||
this.requests = []; | ||
this.sockets = {}; | ||
this.requests = {}; | ||
} | ||
@@ -61,5 +59,3 @@ get defaultPort() { | ||
} | ||
else { | ||
return isSecureEndpoint() ? 443 : 80; | ||
} | ||
return isSecureEndpoint() ? 443 : 80; | ||
} | ||
@@ -73,5 +69,3 @@ set defaultPort(v) { | ||
} | ||
else { | ||
return isSecureEndpoint() ? 'https:' : 'http:'; | ||
} | ||
return isSecureEndpoint() ? 'https:' : 'http:'; | ||
} | ||
@@ -91,19 +85,20 @@ set protocol(v) { | ||
addRequest(req, _opts) { | ||
const ownOpts = Object.assign({}, _opts); | ||
if (typeof ownOpts.secureEndpoint !== 'boolean') { | ||
ownOpts.secureEndpoint = isSecureEndpoint(); | ||
const opts = Object.assign({}, _opts); | ||
if (typeof opts.secureEndpoint !== 'boolean') { | ||
opts.secureEndpoint = isSecureEndpoint(); | ||
} | ||
// Set default `host` for HTTP to localhost | ||
if (ownOpts.host == null) { | ||
ownOpts.host = 'localhost'; | ||
if (opts.host == null) { | ||
opts.host = 'localhost'; | ||
} | ||
// Set default `port` for HTTP if none was explicitly specified | ||
if (ownOpts.port == null) { | ||
ownOpts.port = ownOpts.secureEndpoint ? 443 : 80; | ||
if (opts.port == null) { | ||
opts.port = opts.secureEndpoint ? 443 : 80; | ||
} | ||
const opts = Object.assign(Object.assign({}, this.options), ownOpts); | ||
if (opts.protocol == null) { | ||
opts.protocol = opts.secureEndpoint ? 'https:' : 'http:'; | ||
} | ||
if (opts.host && opts.path) { | ||
// If both a `host` and `path` are specified then it's most likely the | ||
// result of a `url.parse()` call... we need to remove the `path` portion so | ||
// that `net.connect()` doesn't attempt to open that as a unix socket file. | ||
// If both a `host` and `path` are specified then it's most | ||
// likely the result of a `url.parse()` call... we need to | ||
// remove the `path` portion so that `net.connect()` doesn't | ||
// attempt to open that as a unix socket file. | ||
delete opts.path; | ||
@@ -120,8 +115,6 @@ } | ||
req.shouldKeepAlive = false; | ||
// Create the `stream.Duplex` instance | ||
let timedOut = false; | ||
let timeout = null; | ||
const timeoutMs = this.timeout; | ||
const freeSocket = this.freeSocket; | ||
function onerror(err) { | ||
let timeoutId = null; | ||
const timeoutMs = opts.timeout || this.timeout; | ||
const onerror = (err) => { | ||
if (req._hadError) | ||
@@ -133,5 +126,5 @@ return; | ||
req._hadError = true; | ||
} | ||
function ontimeout() { | ||
timeout = null; | ||
}; | ||
const ontimeout = () => { | ||
timeoutId = null; | ||
timedOut = true; | ||
@@ -141,27 +134,24 @@ const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`); | ||
onerror(err); | ||
} | ||
function callbackError(err) { | ||
}; | ||
const callbackError = (err) => { | ||
if (timedOut) | ||
return; | ||
if (timeout !== null) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
if (timeoutId !== null) { | ||
clearTimeout(timeoutId); | ||
timeoutId = null; | ||
} | ||
onerror(err); | ||
} | ||
function onsocket(socket) { | ||
let sock; | ||
function onfree() { | ||
freeSocket(sock, opts); | ||
} | ||
}; | ||
const onsocket = (socket) => { | ||
if (timedOut) | ||
return; | ||
if (timeout != null) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
if (timeoutId != null) { | ||
clearTimeout(timeoutId); | ||
timeoutId = null; | ||
} | ||
if (isAgentBase(socket) || isHttpAgent(socket)) { | ||
if (isAgent(socket)) { | ||
// `socket` is actually an `http.Agent` instance, so | ||
// relinquish responsibility for this `req` to the Agent | ||
// from here on | ||
debug('Callback returned another Agent instance %o', socket.constructor.name); | ||
socket.addRequest(req, opts); | ||
@@ -171,5 +161,6 @@ return; | ||
if (socket) { | ||
sock = socket; | ||
sock.on('free', onfree); | ||
req.onSocket(sock); | ||
socket.once('free', () => { | ||
this.freeSocket(socket, opts); | ||
}); | ||
req.onSocket(socket); | ||
return; | ||
@@ -179,3 +170,3 @@ } | ||
onerror(err); | ||
} | ||
}; | ||
if (typeof this.callback !== 'function') { | ||
@@ -187,3 +178,3 @@ onerror(new Error('`callback` is not defined')); | ||
if (this.callback.length >= 3) { | ||
// Legacy callback function - convert to a Promise | ||
debug('Converting legacy callback function to promise'); | ||
this.promisifiedCallback = promisify_1.default(this.callback); | ||
@@ -196,3 +187,3 @@ } | ||
if (typeof timeoutMs === 'number' && timeoutMs > 0) { | ||
timeout = setTimeout(ontimeout, timeoutMs); | ||
timeoutId = setTimeout(ontimeout, timeoutMs); | ||
} | ||
@@ -203,2 +194,3 @@ if ('port' in opts && typeof opts.port !== 'number') { | ||
try { | ||
debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`); | ||
Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError); | ||
@@ -211,12 +203,14 @@ } | ||
freeSocket(socket, opts) { | ||
// TODO reuse sockets | ||
debug('Freeing socket %o %o', socket.constructor.name, opts); | ||
socket.destroy(); | ||
} | ||
destroy() { } | ||
destroy() { | ||
debug('Destroying agent %o', this.constructor.name); | ||
} | ||
} | ||
createAgent.Agent = Agent; | ||
// So that `instanceof` works correctly | ||
createAgent.prototype = createAgent.Agent.prototype; | ||
})(createAgent || (createAgent = {})); | ||
// So that `instanceof` works correctly | ||
createAgent.prototype = createAgent.Agent.prototype; | ||
module.exports = createAgent; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "agent-base", | ||
"version": "5.1.1", | ||
"version": "6.0.0", | ||
"description": "Turn a function into an `http.Agent` instance", | ||
@@ -34,5 +34,9 @@ "main": "dist/src/index", | ||
}, | ||
"dependencies": { | ||
"debug": "4" | ||
}, | ||
"devDependencies": { | ||
"@types/debug": "4", | ||
"@types/mocha": "^5.2.7", | ||
"@types/node": "^10.5.3", | ||
"@types/node": "^12.12.17", | ||
"@types/ws": "^6.0.3", | ||
@@ -39,0 +43,0 @@ "@typescript-eslint/eslint-plugin": "1.6.0", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24416
293
1
19
+ Addeddebug@4
+ Addeddebug@4.3.7(transitive)
+ Addedms@2.1.3(transitive)