Skip to content

Commit 66f64eb

Browse files
committed
1 parent 1f85f94 commit 66f64eb

File tree

193 files changed

+3951
-17532
lines changed

Some content is hidden

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

193 files changed

+3951
-17532
lines changed

node_modules/.gitignore

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,6 @@
6060
!/@sigstore/core
6161
!/@sigstore/protobuf-specs
6262
!/@sigstore/sign
63-
!/@sigstore/sign/node_modules/
64-
/@sigstore/sign/node_modules/*
65-
!/@sigstore/sign/node_modules/make-fetch-happen
66-
!/@sigstore/sign/node_modules/negotiator
6763
!/@sigstore/tuf
6864
!/@sigstore/verify
6965
!/@tufjs/
@@ -143,13 +139,11 @@
143139
!/make-fetch-happen
144140
!/make-fetch-happen/node_modules/
145141
/make-fetch-happen/node_modules/*
146-
!/make-fetch-happen/node_modules/cacache
147-
!/make-fetch-happen/node_modules/chownr
148-
!/make-fetch-happen/node_modules/minizlib
149-
!/make-fetch-happen/node_modules/mkdirp
142+
!/make-fetch-happen/node_modules/@npmcli/
143+
/make-fetch-happen/node_modules/@npmcli/*
144+
!/make-fetch-happen/node_modules/@npmcli/agent
145+
!/make-fetch-happen/node_modules/lru-cache
150146
!/make-fetch-happen/node_modules/negotiator
151-
!/make-fetch-happen/node_modules/tar
152-
!/make-fetch-happen/node_modules/yallist
153147
!/minimatch
154148
!/minipass-collect
155149
!/minipass-fetch
@@ -179,9 +173,12 @@
179173
!/node-gyp
180174
!/node-gyp/node_modules/
181175
/node-gyp/node_modules/*
176+
!/node-gyp/node_modules/cacache
182177
!/node-gyp/node_modules/chownr
178+
!/node-gyp/node_modules/make-fetch-happen
183179
!/node-gyp/node_modules/minizlib
184180
!/node-gyp/node_modules/mkdirp
181+
!/node-gyp/node_modules/negotiator
185182
!/node-gyp/node_modules/tar
186183
!/node-gyp/node_modules/yallist
187184
!/nopt
@@ -203,9 +200,7 @@
203200
/npm-registry-fetch/node_modules/*
204201
!/npm-registry-fetch/node_modules/hosted-git-info
205202
!/npm-registry-fetch/node_modules/lru-cache
206-
!/npm-registry-fetch/node_modules/make-fetch-happen
207203
!/npm-registry-fetch/node_modules/minizlib
208-
!/npm-registry-fetch/node_modules/negotiator
209204
!/npm-registry-fetch/node_modules/npm-package-arg
210205
!/npm-user-validate
211206
!/p-map
@@ -216,27 +211,13 @@
216211
!/pacote/node_modules/@npmcli/
217212
/pacote/node_modules/@npmcli/*
218213
!/pacote/node_modules/@npmcli/git
219-
!/pacote/node_modules/@npmcli/run-script
220-
!/pacote/node_modules/@sigstore/
221-
/pacote/node_modules/@sigstore/*
222-
!/pacote/node_modules/@sigstore/bundle
223-
!/pacote/node_modules/@sigstore/core
224-
!/pacote/node_modules/@sigstore/protobuf-specs
225-
!/pacote/node_modules/@sigstore/sign
226-
!/pacote/node_modules/@sigstore/tuf
227-
!/pacote/node_modules/@sigstore/verify
228-
!/pacote/node_modules/@tufjs/
229-
/pacote/node_modules/@tufjs/*
230-
!/pacote/node_modules/@tufjs/models
231214
!/pacote/node_modules/chownr
232215
!/pacote/node_modules/hosted-git-info
233216
!/pacote/node_modules/lru-cache
234217
!/pacote/node_modules/minizlib
235218
!/pacote/node_modules/mkdirp
236219
!/pacote/node_modules/npm-package-arg
237220
!/pacote/node_modules/npm-pick-manifest
238-
!/pacote/node_modules/npm-registry-fetch
239-
!/pacote/node_modules/sigstore
240221
!/pacote/node_modules/tar
241222
!/pacote/node_modules/yallist
242223
!/parse-conflict-json
@@ -298,8 +279,6 @@
298279
!/tuf-js/node_modules/@tufjs/
299280
/tuf-js/node_modules/@tufjs/*
300281
!/tuf-js/node_modules/@tufjs/models
301-
!/tuf-js/node_modules/make-fetch-happen
302-
!/tuf-js/node_modules/negotiator
303282
!/unique-filename
304283
!/unique-slug
305284
!/util-deprecate
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
'use strict'
2+
3+
const net = require('net')
4+
const tls = require('tls')
5+
const { once } = require('events')
6+
const timers = require('timers/promises')
7+
const { normalizeOptions, cacheOptions } = require('./options')
8+
const { getProxy, getProxyAgent, proxyCache } = require('./proxy.js')
9+
const Errors = require('./errors.js')
10+
const { Agent: AgentBase } = require('agent-base')
11+
12+
module.exports = class Agent extends AgentBase {
13+
#options
14+
#timeouts
15+
#proxy
16+
#noProxy
17+
#ProxyAgent
18+
19+
constructor (options = {}) {
20+
const { timeouts, proxy, noProxy, ...normalizedOptions } = normalizeOptions(options)
21+
22+
super(normalizedOptions)
23+
24+
this.#options = normalizedOptions
25+
this.#timeouts = timeouts
26+
27+
if (proxy) {
28+
this.#proxy = new URL(proxy)
29+
this.#noProxy = noProxy
30+
this.#ProxyAgent = getProxyAgent(proxy)
31+
}
32+
}
33+
34+
get proxy () {
35+
return this.#proxy ? { url: this.#proxy } : {}
36+
}
37+
38+
#getProxy (options) {
39+
if (!this.#proxy) {
40+
return
41+
}
42+
43+
const proxy = getProxy(`${options.protocol}//${options.host}:${options.port}`, {
44+
proxy: this.#proxy,
45+
noProxy: this.#noProxy,
46+
})
47+
48+
if (!proxy) {
49+
return
50+
}
51+
52+
const cacheKey = cacheOptions({
53+
...options,
54+
...this.#options,
55+
timeouts: this.#timeouts,
56+
proxy,
57+
})
58+
59+
if (proxyCache.has(cacheKey)) {
60+
return proxyCache.get(cacheKey)
61+
}
62+
63+
let ProxyAgent = this.#ProxyAgent
64+
if (Array.isArray(ProxyAgent)) {
65+
ProxyAgent = this.isSecureEndpoint(options) ? ProxyAgent[1] : ProxyAgent[0]
66+
}
67+
68+
const proxyAgent = new ProxyAgent(proxy, {
69+
...this.#options,
70+
socketOptions: { family: this.#options.family },
71+
})
72+
proxyCache.set(cacheKey, proxyAgent)
73+
74+
return proxyAgent
75+
}
76+
77+
// takes an array of promises and races them against the connection timeout
78+
// which will throw the necessary error if it is hit. This will return the
79+
// result of the promise race.
80+
async #timeoutConnection ({ promises, options, timeout }, ac = new AbortController()) {
81+
if (timeout) {
82+
const connectionTimeout = timers.setTimeout(timeout, null, { signal: ac.signal })
83+
.then(() => {
84+
throw new Errors.ConnectionTimeoutError(`${options.host}:${options.port}`)
85+
}).catch((err) => {
86+
if (err.name === 'AbortError') {
87+
return
88+
}
89+
throw err
90+
})
91+
promises.push(connectionTimeout)
92+
}
93+
94+
let result
95+
try {
96+
result = await Promise.race(promises)
97+
ac.abort()
98+
} catch (err) {
99+
ac.abort()
100+
throw err
101+
}
102+
return result
103+
}
104+
105+
async connect (request, options) {
106+
// if the connection does not have its own lookup function
107+
// set, then use the one from our options
108+
options.lookup ??= this.#options.lookup
109+
110+
let socket
111+
let timeout = this.#timeouts.connection
112+
const isSecureEndpoint = this.isSecureEndpoint(options)
113+
114+
const proxy = this.#getProxy(options)
115+
if (proxy) {
116+
// some of the proxies will wait for the socket to fully connect before
117+
// returning so we have to await this while also racing it against the
118+
// connection timeout.
119+
const start = Date.now()
120+
socket = await this.#timeoutConnection({
121+
options,
122+
timeout,
123+
promises: [proxy.connect(request, options)],
124+
})
125+
// see how much time proxy.connect took and subtract it from
126+
// the timeout
127+
if (timeout) {
128+
timeout = timeout - (Date.now() - start)
129+
}
130+
} else {
131+
socket = (isSecureEndpoint ? tls : net).connect(options)
132+
}
133+
134+
socket.setKeepAlive(this.keepAlive, this.keepAliveMsecs)
135+
socket.setNoDelay(this.keepAlive)
136+
137+
const abortController = new AbortController()
138+
const { signal } = abortController
139+
140+
const connectPromise = socket[isSecureEndpoint ? 'secureConnecting' : 'connecting']
141+
? once(socket, isSecureEndpoint ? 'secureConnect' : 'connect', { signal })
142+
: Promise.resolve()
143+
144+
await this.#timeoutConnection({
145+
options,
146+
timeout,
147+
promises: [
148+
connectPromise,
149+
once(socket, 'error', { signal }).then((err) => {
150+
throw err[0]
151+
}),
152+
],
153+
}, abortController)
154+
155+
if (this.#timeouts.idle) {
156+
socket.setTimeout(this.#timeouts.idle, () => {
157+
socket.destroy(new Errors.IdleTimeoutError(`${options.host}:${options.port}`))
158+
})
159+
}
160+
161+
return socket
162+
}
163+
164+
addRequest (request, options) {
165+
const proxy = this.#getProxy(options)
166+
// it would be better to call proxy.addRequest here but this causes the
167+
// http-proxy-agent to call its super.addRequest which causes the request
168+
// to be added to the agent twice. since we only support 3 agents
169+
// currently (see the required agents in proxy.js) we have manually
170+
// checked that the only public methods we need to call are called in the
171+
// next block. this could change in the future and presumably we would get
172+
// failing tests until we have properly called the necessary methods on
173+
// each of our proxy agents
174+
if (proxy?.setRequestProps) {
175+
proxy.setRequestProps(request, options)
176+
}
177+
178+
request.setHeader('connection', this.keepAlive ? 'keep-alive' : 'close')
179+
180+
if (this.#timeouts.response) {
181+
let responseTimeout
182+
request.once('finish', () => {
183+
setTimeout(() => {
184+
request.destroy(new Errors.ResponseTimeoutError(request, this.#proxy))
185+
}, this.#timeouts.response)
186+
})
187+
request.once('response', () => {
188+
clearTimeout(responseTimeout)
189+
})
190+
}
191+
192+
if (this.#timeouts.transfer) {
193+
let transferTimeout
194+
request.once('response', (res) => {
195+
setTimeout(() => {
196+
res.destroy(new Errors.TransferTimeoutError(request, this.#proxy))
197+
}, this.#timeouts.transfer)
198+
res.once('close', () => {
199+
clearTimeout(transferTimeout)
200+
})
201+
})
202+
}
203+
204+
return super.addRequest(request, options)
205+
}
206+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
'use strict'
2+
3+
const { LRUCache } = require('lru-cache')
4+
const dns = require('dns')
5+
6+
// this is a factory so that each request can have its own opts (i.e. ttl)
7+
// while still sharing the cache across all requests
8+
const cache = new LRUCache({ max: 50 })
9+
10+
const getOptions = ({
11+
family = 0,
12+
hints = dns.ADDRCONFIG,
13+
all = false,
14+
verbatim = undefined,
15+
ttl = 5 * 60 * 1000,
16+
lookup = dns.lookup,
17+
}) => ({
18+
// hints and lookup are returned since both are top level properties to (net|tls).connect
19+
hints,
20+
lookup: (hostname, ...args) => {
21+
const callback = args.pop() // callback is always last arg
22+
const lookupOptions = args[0] ?? {}
23+
24+
const options = {
25+
family,
26+
hints,
27+
all,
28+
verbatim,
29+
...(typeof lookupOptions === 'number' ? { family: lookupOptions } : lookupOptions),
30+
}
31+
32+
const key = JSON.stringify({ hostname, ...options })
33+
34+
if (cache.has(key)) {
35+
const cached = cache.get(key)
36+
return process.nextTick(callback, null, ...cached)
37+
}
38+
39+
lookup(hostname, options, (err, ...result) => {
40+
if (err) {
41+
return callback(err)
42+
}
43+
44+
cache.set(key, result, { ttl })
45+
return callback(null, ...result)
46+
})
47+
},
48+
})
49+
50+
module.exports = {
51+
cache,
52+
getOptions,
53+
}

0 commit comments

Comments
 (0)