Path: blob/master/node_modules/agent-base/dist/src/index.js
2593 views
"use strict";1var __importDefault = (this && this.__importDefault) || function (mod) {2return (mod && mod.__esModule) ? mod : { "default": mod };3};4const events_1 = require("events");5const debug_1 = __importDefault(require("debug"));6const promisify_1 = __importDefault(require("./promisify"));7const debug = debug_1.default('agent-base');8function isAgent(v) {9return Boolean(v) && typeof v.addRequest === 'function';10}11function isSecureEndpoint() {12const { stack } = new Error();13if (typeof stack !== 'string')14return false;15return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1);16}17function createAgent(callback, opts) {18return new createAgent.Agent(callback, opts);19}20(function (createAgent) {21/**22* Base `http.Agent` implementation.23* No pooling/keep-alive is implemented by default.24*25* @param {Function} callback26* @api public27*/28class Agent extends events_1.EventEmitter {29constructor(callback, _opts) {30super();31let opts = _opts;32if (typeof callback === 'function') {33this.callback = callback;34}35else if (callback) {36opts = callback;37}38// Timeout for the socket to be returned from the callback39this.timeout = null;40if (opts && typeof opts.timeout === 'number') {41this.timeout = opts.timeout;42}43// These aren't actually used by `agent-base`, but are required44// for the TypeScript definition files in `@types/node` :/45this.maxFreeSockets = 1;46this.maxSockets = 1;47this.maxTotalSockets = Infinity;48this.sockets = {};49this.freeSockets = {};50this.requests = {};51this.options = {};52}53get defaultPort() {54if (typeof this.explicitDefaultPort === 'number') {55return this.explicitDefaultPort;56}57return isSecureEndpoint() ? 443 : 80;58}59set defaultPort(v) {60this.explicitDefaultPort = v;61}62get protocol() {63if (typeof this.explicitProtocol === 'string') {64return this.explicitProtocol;65}66return isSecureEndpoint() ? 'https:' : 'http:';67}68set protocol(v) {69this.explicitProtocol = v;70}71callback(req, opts, fn) {72throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`');73}74/**75* Called by node-core's "_http_client.js" module when creating76* a new HTTP request with this Agent instance.77*78* @api public79*/80addRequest(req, _opts) {81const opts = Object.assign({}, _opts);82if (typeof opts.secureEndpoint !== 'boolean') {83opts.secureEndpoint = isSecureEndpoint();84}85if (opts.host == null) {86opts.host = 'localhost';87}88if (opts.port == null) {89opts.port = opts.secureEndpoint ? 443 : 80;90}91if (opts.protocol == null) {92opts.protocol = opts.secureEndpoint ? 'https:' : 'http:';93}94if (opts.host && opts.path) {95// If both a `host` and `path` are specified then it's most96// likely the result of a `url.parse()` call... we need to97// remove the `path` portion so that `net.connect()` doesn't98// attempt to open that as a unix socket file.99delete opts.path;100}101delete opts.agent;102delete opts.hostname;103delete opts._defaultAgent;104delete opts.defaultPort;105delete opts.createConnection;106// Hint to use "Connection: close"107// XXX: non-documented `http` module API :(108req._last = true;109req.shouldKeepAlive = false;110let timedOut = false;111let timeoutId = null;112const timeoutMs = opts.timeout || this.timeout;113const onerror = (err) => {114if (req._hadError)115return;116req.emit('error', err);117// For Safety. Some additional errors might fire later on118// and we need to make sure we don't double-fire the error event.119req._hadError = true;120};121const ontimeout = () => {122timeoutId = null;123timedOut = true;124const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`);125err.code = 'ETIMEOUT';126onerror(err);127};128const callbackError = (err) => {129if (timedOut)130return;131if (timeoutId !== null) {132clearTimeout(timeoutId);133timeoutId = null;134}135onerror(err);136};137const onsocket = (socket) => {138if (timedOut)139return;140if (timeoutId != null) {141clearTimeout(timeoutId);142timeoutId = null;143}144if (isAgent(socket)) {145// `socket` is actually an `http.Agent` instance, so146// relinquish responsibility for this `req` to the Agent147// from here on148debug('Callback returned another Agent instance %o', socket.constructor.name);149socket.addRequest(req, opts);150return;151}152if (socket) {153socket.once('free', () => {154this.freeSocket(socket, opts);155});156req.onSocket(socket);157return;158}159const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``);160onerror(err);161};162if (typeof this.callback !== 'function') {163onerror(new Error('`callback` is not defined'));164return;165}166if (!this.promisifiedCallback) {167if (this.callback.length >= 3) {168debug('Converting legacy callback function to promise');169this.promisifiedCallback = promisify_1.default(this.callback);170}171else {172this.promisifiedCallback = this.callback;173}174}175if (typeof timeoutMs === 'number' && timeoutMs > 0) {176timeoutId = setTimeout(ontimeout, timeoutMs);177}178if ('port' in opts && typeof opts.port !== 'number') {179opts.port = Number(opts.port);180}181try {182debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`);183Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError);184}185catch (err) {186Promise.reject(err).catch(callbackError);187}188}189freeSocket(socket, opts) {190debug('Freeing socket %o %o', socket.constructor.name, opts);191socket.destroy();192}193destroy() {194debug('Destroying agent %o', this.constructor.name);195}196}197createAgent.Agent = Agent;198// So that `instanceof` works correctly199createAgent.prototype = createAgent.Agent.prototype;200})(createAgent || (createAgent = {}));201module.exports = createAgent;202//# sourceMappingURL=index.js.map203204