Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
File Manager
/
byp
/
izo
/
con7ext_sym404
/
rintoar.txt
/
usr
/
lib
/
node_modules
/
npm
/
node_modules
/
@npmcli
/
agent
/
lib
:
agents.js
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
'use strict' const http = require('http') const https = require('https') const net = require('net') const tls = require('tls') const { once } = require('events') const { createTimeout, abortRace, urlify, appendPort, cacheAgent } = require('./util') const { normalizeOptions, cacheOptions } = require('./options') const { getProxy, getProxyType, proxyCache } = require('./proxy.js') const Errors = require('./errors.js') const createAgent = (base, name) => { const SECURE = base === https const SOCKET_TYPE = SECURE ? tls : net const agent = class extends base.Agent { #options #timeouts #proxy #socket constructor (_options) { const { timeouts, proxy, noProxy, ...options } = normalizeOptions(_options) super(options) this.#options = options this.#timeouts = timeouts this.#proxy = proxy ? { proxies: getProxyType(proxy), proxy: urlify(proxy), noProxy } : null } get proxy () { return this.#proxy ? { url: this.#proxy.proxy } : {} } #getProxy (options) { const proxy = this.#proxy ? getProxy(appendPort(`${options.protocol}//${options.host}`, options.port), this.#proxy) : null if (!proxy) { return } return cacheAgent({ key: cacheOptions({ ...options, ...this.#options, secure: SECURE, timeouts: this.#timeouts, proxy, }), cache: proxyCache, secure: SECURE, proxies: this.#proxy.proxies, }, proxy, this.#options) } #setKeepAlive (socket) { socket.setKeepAlive(this.keepAlive, this.keepAliveMsecs) socket.setNoDelay(this.keepAlive) } #setIdleTimeout (socket, options) { if (this.#timeouts.idle) { socket.setTimeout(this.#timeouts.idle, () => { socket.destroy(new Errors.IdleTimeoutError(options)) }) } } async #proxyConnect (proxy, request, options) { // socks-proxy-agent accepts a dns lookup function options.lookup ??= this.#options.lookup // all the proxy agents use this secureEndpoint option to determine // if the proxy should connect over tls or not. we can set it based // on if the HttpAgent or HttpsAgent is used. options.secureEndpoint = SECURE const socket = await abortRace([ (ac) => createTimeout(this.#timeouts.connection, ac).catch(() => { throw new Errors.ConnectionTimeoutError(options) }), (ac) => proxy.connect(request, options).then((s) => { this.#setKeepAlive(s) const connectEvent = SECURE ? 'secureConnect' : 'connect' const connectingEvent = SECURE ? 'secureConnecting' : 'connecting' if (!s[connectingEvent]) { return s } return abortRace([ () => once(s, 'error', ac).then((err) => { throw err }), () => once(s, connectEvent, ac).then(() => s), ], ac) }), ]) this.#setIdleTimeout(socket, options) return socket } async connect (request, options) { const proxy = this.#getProxy(options) if (proxy) { return this.#proxyConnect(proxy, request, options) } const socket = SOCKET_TYPE.connect(options) this.#setKeepAlive(socket) await abortRace([ (s) => createTimeout(this.#timeouts.connection, s).catch(() => { throw new Errors.ConnectionTimeoutError(options) }), (s) => once(socket, 'error', s).then((err) => { throw err }), (s) => once(socket, 'connect', s), ]) this.#setIdleTimeout(socket, options) return socket } addRequest (request, options) { const proxy = this.#getProxy(options) // it would be better to call proxy.addRequest here but this causes the // http-proxy-agent to call its super.addRequest which causes the request // to be added to the agent twice. since we only support 3 agents // currently (see the required agents in proxy.js) we have manually // checked that the only public methods we need to call are called in the // next block. this could change in the future and presumably we would get // failing tests until we have properly called the necessary methods on // each of our proxy agents if (proxy?.setRequestProps) { proxy.setRequestProps(request, options) } request.setHeader('connection', this.keepAlive ? 'keep-alive' : 'close') const responseTimeout = createTimeout(this.#timeouts.response) if (responseTimeout) { request.once('finish', () => { responseTimeout.start(() => { request.destroy(new Errors.ResponseTimeoutError(request, this.proxy?.url)) }) }) request.once('response', () => { responseTimeout.clear() }) } const transferTimeout = createTimeout(this.#timeouts.transfer) if (transferTimeout) { request.once('response', (res) => { transferTimeout.start(() => { res.destroy(new Errors.TransferTimeoutError(request, this.proxy?.url)) }) res.once('close', () => { transferTimeout.clear() }) }) } return super.addRequest(request, options) } createSocket (req, options, cb) { return Promise.resolve() .then(() => this.connect(req, options)) .then((socket) => { this.#socket = socket return super.createSocket(req, options, cb) }, cb) } createConnection () { return this.#socket } } Object.defineProperty(agent, 'name', { value: name }) return agent } module.exports = { HttpAgent: createAgent(http, 'HttpAgent'), HttpsAgent: createAgent(https, 'HttpsAgent'), }