Skip to content

Commit 5d0d859

Browse files
committed
1 parent f916d33 commit 5d0d859

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+5696
-23
lines changed

node_modules/.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
!/@isaacs/string-locale-compare
1919
!/@npmcli/
2020
/@npmcli/*
21+
!/@npmcli/agent
2122
!/@npmcli/disparity-colors
2223
!/@npmcli/fs
2324
!/@npmcli/git
@@ -193,12 +194,22 @@
193194
!/npm-packlist
194195
!/npm-pick-manifest
195196
!/npm-profile
197+
!/npm-profile/node_modules/
198+
/npm-profile/node_modules/*
199+
!/npm-profile/node_modules/npm-registry-fetch
196200
!/npm-registry-fetch
201+
!/npm-registry-fetch/node_modules/
202+
/npm-registry-fetch/node_modules/*
203+
!/npm-registry-fetch/node_modules/make-fetch-happen
204+
!/npm-registry-fetch/node_modules/minipass
197205
!/npm-user-validate
198206
!/npmlog
199207
!/once
200208
!/p-map
201209
!/pacote
210+
!/pacote/node_modules/
211+
/pacote/node_modules/*
212+
!/pacote/node_modules/npm-registry-fetch
202213
!/parse-conflict-json
203214
!/path-is-absolute
204215
!/path-key

node_modules/@npmcli/agent/lib/dns.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
'use strict'
2+
3+
const LRUCache = require('lru-cache')
4+
const dns = require('dns')
5+
6+
const defaultOptions = exports.defaultOptions = {
7+
family: undefined,
8+
hints: dns.ADDRCONFIG,
9+
all: false,
10+
verbatim: undefined,
11+
}
12+
13+
const lookupCache = exports.lookupCache = new LRUCache({ max: 50 })
14+
15+
// this is a factory so that each request can have its own opts (i.e. ttl)
16+
// while still sharing the cache across all requests
17+
exports.getLookup = (dnsOptions) => {
18+
return (hostname, options, callback) => {
19+
if (typeof options === 'function') {
20+
callback = options
21+
options = null
22+
} else if (typeof options === 'number') {
23+
options = { family: options }
24+
}
25+
26+
options = { ...defaultOptions, ...options }
27+
28+
const key = JSON.stringify({
29+
hostname,
30+
family: options.family,
31+
hints: options.hints,
32+
all: options.all,
33+
verbatim: options.verbatim,
34+
})
35+
36+
if (lookupCache.has(key)) {
37+
const [address, family] = lookupCache.get(key)
38+
process.nextTick(callback, null, address, family)
39+
return
40+
}
41+
42+
dnsOptions.lookup(hostname, options, (err, address, family) => {
43+
if (err) {
44+
return callback(err)
45+
}
46+
47+
lookupCache.set(key, [address, family], { ttl: dnsOptions.ttl })
48+
return callback(null, address, family)
49+
})
50+
}
51+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
'use strict'
2+
3+
class InvalidProxyProtocolError extends Error {
4+
constructor (url) {
5+
super(`Invalid protocol \`${url.protocol}\` connecting to proxy \`${url.host}\``)
6+
this.code = 'EINVALIDPROXY'
7+
this.proxy = url
8+
}
9+
}
10+
11+
class InvalidProxyResponseError extends Error {
12+
constructor (url, status) {
13+
super(`Invalid status code \`${status}\` connecting to proxy \`${url.host}\``)
14+
this.code = 'EINVALIDRESPONSE'
15+
this.proxy = url
16+
this.status = status
17+
}
18+
}
19+
20+
class ConnectionTimeoutError extends Error {
21+
constructor (host) {
22+
super(`Timeout connecting to host \`${host}\``)
23+
this.code = 'ECONNECTIONTIMEOUT'
24+
this.host = host
25+
}
26+
}
27+
28+
class IdleTimeoutError extends Error {
29+
constructor (host) {
30+
super(`Idle timeout reached for host \`${host}\``)
31+
this.code = 'EIDLETIMEOUT'
32+
this.host = host
33+
}
34+
}
35+
36+
class ResponseTimeoutError extends Error {
37+
constructor (proxy, request) {
38+
let msg = 'Response timeout '
39+
if (proxy.url) {
40+
msg += `from proxy \`${proxy.url.host}\` `
41+
}
42+
msg += `connecting to host \`${request.host}\``
43+
super(msg)
44+
this.code = 'ERESPONSETIMEOUT'
45+
this.proxy = proxy.url
46+
this.request = request
47+
}
48+
}
49+
50+
class TransferTimeoutError extends Error {
51+
constructor (proxy, request) {
52+
let msg = 'Transfer timeout '
53+
if (proxy.url) {
54+
msg += `from proxy \`${proxy.url.host}\` `
55+
}
56+
msg += `for \`${request.host}\``
57+
super(msg)
58+
this.code = 'ETRANSFERTIMEOUT'
59+
this.proxy = proxy.url
60+
this.request = request
61+
}
62+
}
63+
64+
module.exports = {
65+
InvalidProxyProtocolError,
66+
InvalidProxyResponseError,
67+
ConnectionTimeoutError,
68+
IdleTimeoutError,
69+
ResponseTimeoutError,
70+
TransferTimeoutError,
71+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict'
2+
3+
const http = require('http')
4+
5+
const { getLookup } = require('./dns.js')
6+
const { normalizeOptions } = require('./util.js')
7+
const createProxy = require('./proxy/index.js')
8+
9+
class HttpAgent extends http.Agent {
10+
constructor (_options = {}) {
11+
const options = normalizeOptions(_options)
12+
super(options)
13+
this.proxy = createProxy({
14+
agent: this,
15+
lookup: getLookup(options.dns),
16+
proxy: options.proxy,
17+
secure: false,
18+
})
19+
}
20+
21+
createConnection (_options, callback) {
22+
const options = normalizeOptions(_options)
23+
return this.proxy.createConnection(options, callback)
24+
}
25+
26+
addRequest (request, _options) {
27+
const options = normalizeOptions(_options)
28+
super.addRequest(request, _options)
29+
return this.proxy.addRequest(request, options)
30+
}
31+
}
32+
33+
module.exports = HttpAgent
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
'use strict'
2+
3+
const https = require('https')
4+
5+
const { getLookup } = require('./dns.js')
6+
const { normalizeOptions } = require('./util.js')
7+
const createProxy = require('./proxy/index.js')
8+
9+
class HttpsAgent extends https.Agent {
10+
constructor (_options) {
11+
const options = normalizeOptions(_options)
12+
super(options)
13+
this.proxy = createProxy({
14+
agent: this,
15+
lookup: getLookup(options.dns),
16+
proxy: options.proxy,
17+
secure: true,
18+
})
19+
}
20+
21+
createConnection (_options, callback) {
22+
const options = normalizeOptions(_options)
23+
return this.proxy.createConnection(options, callback)
24+
}
25+
26+
addRequest (request, _options) {
27+
const options = normalizeOptions(_options)
28+
super.addRequest(request, options)
29+
return this.proxy.addRequest(request, options)
30+
}
31+
}
32+
33+
module.exports = HttpsAgent
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
'use strict'
2+
3+
const { normalizeOptions } = require('./util.js')
4+
const HttpAgent = require('./http.js')
5+
const HttpsAgent = require('./https.js')
6+
7+
const AgentCache = new Map()
8+
9+
const proxyEnv = {}
10+
for (const [key, value] of Object.entries(process.env)) {
11+
const lowerKey = key.toLowerCase()
12+
if (['https_proxy', 'http_proxy', 'proxy', 'no_proxy'].includes(lowerKey)) {
13+
proxyEnv[lowerKey] = value
14+
}
15+
}
16+
17+
const getAgent = (url, options) => {
18+
url = new URL(url)
19+
options = normalizeOptions(options)
20+
21+
// false has meaning so this can't be a simple truthiness check
22+
if (options.agent != null) {
23+
return options.agent
24+
}
25+
26+
const isHttps = url.protocol === 'https:'
27+
28+
let proxy = options.proxy
29+
if (!proxy) {
30+
proxy = isHttps
31+
? proxyEnv.https_proxy
32+
: (proxyEnv.https_proxy || proxyEnv.http_proxy || proxyEnv.proxy)
33+
}
34+
35+
if (proxy) {
36+
proxy = new URL(proxy)
37+
let noProxy = options.noProxy || proxyEnv.no_proxy
38+
if (typeof noProxy === 'string') {
39+
noProxy = noProxy.split(',').map((p) => p.trim())
40+
}
41+
42+
if (noProxy) {
43+
const hostSegments = url.hostname.split('.').reverse()
44+
const matches = noProxy.some((no) => {
45+
const noSegments = no.split('.').filter(Boolean).reverse()
46+
if (!noSegments.length) {
47+
return false
48+
}
49+
50+
for (let i = 0; i < noSegments.length; ++i) {
51+
if (hostSegments[i] !== noSegments[i]) {
52+
return false
53+
}
54+
}
55+
56+
return true
57+
})
58+
59+
if (matches) {
60+
proxy = ''
61+
}
62+
}
63+
}
64+
65+
const timeouts = [
66+
options.timeouts.connection || 0,
67+
options.timeouts.idle || 0,
68+
options.timeouts.response || 0,
69+
options.timeouts.transfer || 0,
70+
].join('.')
71+
72+
const maxSockets = options.maxSockets || 15
73+
74+
let proxyDescriptor = 'proxy:'
75+
if (!proxy) {
76+
proxyDescriptor += 'null'
77+
} else {
78+
proxyDescriptor += `${proxy.protocol}//`
79+
let auth = ''
80+
81+
if (proxy.username) {
82+
auth += proxy.username
83+
}
84+
85+
if (proxy.password) {
86+
auth += `:${proxy.password}`
87+
}
88+
89+
if (auth) {
90+
proxyDescriptor += `${auth}@`
91+
}
92+
93+
proxyDescriptor += proxy.host
94+
}
95+
96+
const key = [
97+
`https:${isHttps}`,
98+
proxyDescriptor,
99+
`local-address:${options.localAddress || 'null'}`,
100+
`strict-ssl:${isHttps ? options.rejectUnauthorized : 'false'}`,
101+
`ca:${isHttps && options.ca || 'null'}`,
102+
`cert:${isHttps && options.cert || 'null'}`,
103+
`key:${isHttps && options.key || 'null'}`,
104+
`timeouts:${timeouts}`,
105+
`maxSockets:${maxSockets}`,
106+
].join(':')
107+
108+
if (AgentCache.has(key)) {
109+
return AgentCache.get(key)
110+
}
111+
112+
const agentOptions = {
113+
ca: options.ca,
114+
cert: options.cert,
115+
key: options.key,
116+
rejectUnauthorized: options.rejectUnauthorized,
117+
maxSockets,
118+
timeouts: options.timeouts,
119+
localAddress: options.localAddress,
120+
proxy,
121+
}
122+
123+
const agent = isHttps
124+
? new HttpsAgent(agentOptions)
125+
: new HttpAgent(agentOptions)
126+
127+
AgentCache.set(key, agent)
128+
return agent
129+
}
130+
131+
module.exports = {
132+
getAgent,
133+
HttpAgent,
134+
HttpsAgent,
135+
}

0 commit comments

Comments
 (0)