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
+
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4