source: trip-planner-front/node_modules/make-fetch-happen/lib/agent.js@ 8d391a1

Last change on this file since 8d391a1 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.2 KB
Line 
1'use strict'
2const LRU = require('lru-cache')
3const url = require('url')
4const isLambda = require('is-lambda')
5
6const AGENT_CACHE = new LRU({ max: 50 })
7const HttpAgent = require('agentkeepalive')
8const HttpsAgent = HttpAgent.HttpsAgent
9
10module.exports = getAgent
11
12const getAgentTimeout = timeout =>
13 typeof timeout !== 'number' || !timeout ? 0 : timeout + 1
14
15const getMaxSockets = maxSockets => maxSockets || 15
16
17function getAgent (uri, opts) {
18 const parsedUri = new url.URL(typeof uri === 'string' ? uri : uri.url)
19 const isHttps = parsedUri.protocol === 'https:'
20 const pxuri = getProxyUri(parsedUri.href, opts)
21
22 // If opts.timeout is zero, set the agentTimeout to zero as well. A timeout
23 // of zero disables the timeout behavior (OS limits still apply). Else, if
24 // opts.timeout is a non-zero value, set it to timeout + 1, to ensure that
25 // the node-fetch-npm timeout will always fire first, giving us more
26 // consistent errors.
27 const agentTimeout = getAgentTimeout(opts.timeout)
28 const agentMaxSockets = getMaxSockets(opts.maxSockets)
29
30 const key = [
31 `https:${isHttps}`,
32 pxuri
33 ? `proxy:${pxuri.protocol}//${pxuri.host}:${pxuri.port}`
34 : '>no-proxy<',
35 `local-address:${opts.localAddress || '>no-local-address<'}`,
36 `strict-ssl:${isHttps ? opts.rejectUnauthorized : '>no-strict-ssl<'}`,
37 `ca:${(isHttps && opts.ca) || '>no-ca<'}`,
38 `cert:${(isHttps && opts.cert) || '>no-cert<'}`,
39 `key:${(isHttps && opts.key) || '>no-key<'}`,
40 `timeout:${agentTimeout}`,
41 `maxSockets:${agentMaxSockets}`,
42 ].join(':')
43
44 if (opts.agent != null) { // `agent: false` has special behavior!
45 return opts.agent
46 }
47
48 // keep alive in AWS lambda makes no sense
49 const lambdaAgent = !isLambda ? null
50 : isHttps ? require('https').globalAgent
51 : require('http').globalAgent
52
53 if (isLambda && !pxuri)
54 return lambdaAgent
55
56 if (AGENT_CACHE.peek(key))
57 return AGENT_CACHE.get(key)
58
59 if (pxuri) {
60 const pxopts = isLambda ? {
61 ...opts,
62 agent: lambdaAgent,
63 } : opts
64 const proxy = getProxy(pxuri, pxopts, isHttps)
65 AGENT_CACHE.set(key, proxy)
66 return proxy
67 }
68
69 const agent = isHttps ? new HttpsAgent({
70 maxSockets: agentMaxSockets,
71 ca: opts.ca,
72 cert: opts.cert,
73 key: opts.key,
74 localAddress: opts.localAddress,
75 rejectUnauthorized: opts.rejectUnauthorized,
76 timeout: agentTimeout,
77 }) : new HttpAgent({
78 maxSockets: agentMaxSockets,
79 localAddress: opts.localAddress,
80 timeout: agentTimeout,
81 })
82 AGENT_CACHE.set(key, agent)
83 return agent
84}
85
86function checkNoProxy (uri, opts) {
87 const host = new url.URL(uri).hostname.split('.').reverse()
88 let noproxy = (opts.noProxy || getProcessEnv('no_proxy'))
89 if (typeof noproxy === 'string')
90 noproxy = noproxy.split(/\s*,\s*/g)
91
92 return noproxy && noproxy.some(no => {
93 const noParts = no.split('.').filter(x => x).reverse()
94 if (!noParts.length)
95 return false
96 for (let i = 0; i < noParts.length; i++) {
97 if (host[i] !== noParts[i])
98 return false
99 }
100 return true
101 })
102}
103
104module.exports.getProcessEnv = getProcessEnv
105
106function getProcessEnv (env) {
107 if (!env)
108 return
109
110 let value
111
112 if (Array.isArray(env)) {
113 for (const e of env) {
114 value = process.env[e] ||
115 process.env[e.toUpperCase()] ||
116 process.env[e.toLowerCase()]
117 if (typeof value !== 'undefined')
118 break
119 }
120 }
121
122 if (typeof env === 'string') {
123 value = process.env[env] ||
124 process.env[env.toUpperCase()] ||
125 process.env[env.toLowerCase()]
126 }
127
128 return value
129}
130
131module.exports.getProxyUri = getProxyUri
132function getProxyUri (uri, opts) {
133 const protocol = new url.URL(uri).protocol
134
135 const proxy = opts.proxy ||
136 (
137 protocol === 'https:' &&
138 getProcessEnv('https_proxy')
139 ) ||
140 (
141 protocol === 'http:' &&
142 getProcessEnv(['https_proxy', 'http_proxy', 'proxy'])
143 )
144 if (!proxy)
145 return null
146
147 const parsedProxy = (typeof proxy === 'string') ? new url.URL(proxy) : proxy
148
149 return !checkNoProxy(uri, opts) && parsedProxy
150}
151
152const getAuth = u =>
153 u.username && u.password ? decodeURIComponent(`${u.username}:${u.password}`)
154 : u.username ? decodeURIComponent(u.username)
155 : null
156
157const getPath = u => u.pathname + u.search + u.hash
158
159const HttpProxyAgent = require('http-proxy-agent')
160const HttpsProxyAgent = require('https-proxy-agent')
161const SocksProxyAgent = require('socks-proxy-agent')
162module.exports.getProxy = getProxy
163function getProxy (proxyUrl, opts, isHttps) {
164 const popts = {
165 host: proxyUrl.hostname,
166 port: proxyUrl.port,
167 protocol: proxyUrl.protocol,
168 path: getPath(proxyUrl),
169 auth: getAuth(proxyUrl),
170 ca: opts.ca,
171 cert: opts.cert,
172 key: opts.key,
173 timeout: getAgentTimeout(opts.timeout),
174 localAddress: opts.localAddress,
175 maxSockets: getMaxSockets(opts.maxSockets),
176 rejectUnauthorized: opts.rejectUnauthorized,
177 }
178
179 if (proxyUrl.protocol === 'http:' || proxyUrl.protocol === 'https:') {
180 if (!isHttps)
181 return new HttpProxyAgent(popts)
182 else
183 return new HttpsProxyAgent(popts)
184 } else if (proxyUrl.protocol.startsWith('socks'))
185 return new SocksProxyAgent(popts)
186 else {
187 throw Object.assign(
188 new Error(`unsupported proxy protocol: '${proxyUrl.protocol}'`),
189 {
190 url: proxyUrl.href,
191 }
192 )
193 }
194}
Note: See TracBrowser for help on using the repository browser.