@gby/got-scraping 4.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +164 -0
- package/dist/index.d.ts +284 -0
- package/dist/index.js +1117 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1117 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
4
|
+
var __publicField = (obj, key, value) => {
|
|
5
|
+
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
6
|
+
return value;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
// src/index.ts
|
|
10
|
+
import http3 from "node:http";
|
|
11
|
+
import https2 from "node:https";
|
|
12
|
+
import { got as originalGot, Options as Options8 } from "got";
|
|
13
|
+
import { HeaderGenerator as HeaderGenerator2 } from "header-generator";
|
|
14
|
+
|
|
15
|
+
// src/agent/transform-headers-agent.ts
|
|
16
|
+
import { HeaderGenerator } from "header-generator";
|
|
17
|
+
import { OutgoingMessage } from "node:http";
|
|
18
|
+
|
|
19
|
+
// src/agent/wrapped-agent.ts
|
|
20
|
+
import "node:http";
|
|
21
|
+
var _WrappedAgent = class _WrappedAgent {
|
|
22
|
+
constructor(agent) {
|
|
23
|
+
__publicField(this, "agent");
|
|
24
|
+
this.agent = agent;
|
|
25
|
+
}
|
|
26
|
+
addRequest(request, options) {
|
|
27
|
+
this.agent.addRequest(request, options);
|
|
28
|
+
}
|
|
29
|
+
get keepAlive() {
|
|
30
|
+
return this.agent.keepAlive;
|
|
31
|
+
}
|
|
32
|
+
get maxSockets() {
|
|
33
|
+
return this.agent.maxSockets;
|
|
34
|
+
}
|
|
35
|
+
get options() {
|
|
36
|
+
return this.agent.options;
|
|
37
|
+
}
|
|
38
|
+
get defaultPort() {
|
|
39
|
+
return this.agent.defaultPort;
|
|
40
|
+
}
|
|
41
|
+
get protocol() {
|
|
42
|
+
return this.agent.protocol;
|
|
43
|
+
}
|
|
44
|
+
destroy() {
|
|
45
|
+
this.agent.destroy();
|
|
46
|
+
}
|
|
47
|
+
// Let's implement `HttpAgent` so we don't have to
|
|
48
|
+
// type `WrappedAgent as unknown as HttpAgent`
|
|
49
|
+
get maxFreeSockets() {
|
|
50
|
+
return this.agent.maxFreeSockets;
|
|
51
|
+
}
|
|
52
|
+
get maxTotalSockets() {
|
|
53
|
+
return this.agent.maxTotalSockets;
|
|
54
|
+
}
|
|
55
|
+
get freeSockets() {
|
|
56
|
+
return this.agent.freeSockets;
|
|
57
|
+
}
|
|
58
|
+
get sockets() {
|
|
59
|
+
return this.agent.sockets;
|
|
60
|
+
}
|
|
61
|
+
get requests() {
|
|
62
|
+
return this.agent.requests;
|
|
63
|
+
}
|
|
64
|
+
on(eventName, listener) {
|
|
65
|
+
this.agent.on(eventName, listener);
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
once(eventName, listener) {
|
|
69
|
+
this.agent.once(eventName, listener);
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
off(eventName, listener) {
|
|
73
|
+
this.agent.off(eventName, listener);
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
addListener(eventName, listener) {
|
|
77
|
+
this.agent.addListener(eventName, listener);
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
removeListener(eventName, listener) {
|
|
81
|
+
this.agent.removeListener(eventName, listener);
|
|
82
|
+
return this;
|
|
83
|
+
}
|
|
84
|
+
removeAllListeners(eventName) {
|
|
85
|
+
this.agent.removeAllListeners(eventName);
|
|
86
|
+
return this;
|
|
87
|
+
}
|
|
88
|
+
setMaxListeners(n) {
|
|
89
|
+
this.agent.setMaxListeners(n);
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
getMaxListeners() {
|
|
93
|
+
return this.agent.getMaxListeners();
|
|
94
|
+
}
|
|
95
|
+
listeners(eventName) {
|
|
96
|
+
return this.agent.listeners(eventName);
|
|
97
|
+
}
|
|
98
|
+
rawListeners(eventName) {
|
|
99
|
+
return this.agent.rawListeners(eventName);
|
|
100
|
+
}
|
|
101
|
+
emit(eventName, ...args) {
|
|
102
|
+
return this.agent.emit(eventName, ...args);
|
|
103
|
+
}
|
|
104
|
+
eventNames() {
|
|
105
|
+
return this.agent.eventNames();
|
|
106
|
+
}
|
|
107
|
+
listenerCount(eventName) {
|
|
108
|
+
return this.agent.listenerCount(eventName);
|
|
109
|
+
}
|
|
110
|
+
prependListener(eventName, listener) {
|
|
111
|
+
this.agent.prependListener(eventName, listener);
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
prependOnceListener(eventName, listener) {
|
|
115
|
+
this.agent.prependOnceListener(eventName, listener);
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
createConnection(options, callback) {
|
|
119
|
+
return this.agent.createConnection(options, callback);
|
|
120
|
+
}
|
|
121
|
+
keepSocketAlive(socket) {
|
|
122
|
+
this.agent.keepSocketAlive(socket);
|
|
123
|
+
}
|
|
124
|
+
reuseSocket(socket, request) {
|
|
125
|
+
this.agent.reuseSocket(socket, request);
|
|
126
|
+
}
|
|
127
|
+
getName(options) {
|
|
128
|
+
return this.agent.getName(options);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
__name(_WrappedAgent, "WrappedAgent");
|
|
132
|
+
var WrappedAgent = _WrappedAgent;
|
|
133
|
+
|
|
134
|
+
// src/agent/transform-headers-agent.ts
|
|
135
|
+
var { _storeHeader } = OutgoingMessage.prototype;
|
|
136
|
+
var generator = new HeaderGenerator();
|
|
137
|
+
var _TransformHeadersAgent = class _TransformHeadersAgent extends WrappedAgent {
|
|
138
|
+
// Rewritten from https://github.com/nodejs/node/blob/533cafcf7e3ab72e98a2478bc69aedfdf06d3a5e/lib/_http_outgoing.js#L442-L479
|
|
139
|
+
/**
|
|
140
|
+
* Transforms the request via header normalization.
|
|
141
|
+
*/
|
|
142
|
+
transformRequest(request, { sortHeaders }) {
|
|
143
|
+
const headers = {};
|
|
144
|
+
const hasConnection = request.hasHeader("connection");
|
|
145
|
+
const hasContentLength = request.hasHeader("content-length");
|
|
146
|
+
const hasTransferEncoding = request.hasHeader("transfer-encoding");
|
|
147
|
+
const hasTrailer = request.hasHeader("trailer");
|
|
148
|
+
const keys = request.getHeaderNames();
|
|
149
|
+
for (const key of keys) {
|
|
150
|
+
if (key.toLowerCase().startsWith("x-")) {
|
|
151
|
+
headers[key] = request.getHeader(key);
|
|
152
|
+
} else {
|
|
153
|
+
headers[this.toPascalCase(key)] = request.getHeader(key);
|
|
154
|
+
}
|
|
155
|
+
if (sortHeaders) {
|
|
156
|
+
request.removeHeader(key);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
const typedRequest = request;
|
|
160
|
+
if (!hasConnection) {
|
|
161
|
+
const shouldSendKeepAlive = request.shouldKeepAlive && (hasContentLength || request.useChunkedEncodingByDefault || typedRequest.agent);
|
|
162
|
+
if (shouldSendKeepAlive) {
|
|
163
|
+
headers.Connection = "keep-alive";
|
|
164
|
+
} else {
|
|
165
|
+
headers.Connection = "close";
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!hasContentLength && !hasTransferEncoding) {
|
|
169
|
+
if (!hasTrailer && !typedRequest._removedContLen && typeof typedRequest._contentLength === "number") {
|
|
170
|
+
headers["Content-Length"] = typedRequest._contentLength;
|
|
171
|
+
} else if (!typedRequest._removedTE) {
|
|
172
|
+
headers["Transfer-Encoding"] = "chunked";
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const transformedHeaders = sortHeaders ? generator.orderHeaders(headers) : headers;
|
|
176
|
+
for (const [key, value] of Object.entries(transformedHeaders)) {
|
|
177
|
+
request.setHeader(key, value);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
addRequest(request, options) {
|
|
181
|
+
const typedRequest = request;
|
|
182
|
+
typedRequest._storeHeader = (...args) => {
|
|
183
|
+
this.transformRequest(request, { sortHeaders: true });
|
|
184
|
+
return _storeHeader.call(request, ...args);
|
|
185
|
+
};
|
|
186
|
+
options.secureEndpoint = options.protocol === "https:";
|
|
187
|
+
return super.addRequest(request, options);
|
|
188
|
+
}
|
|
189
|
+
toPascalCase(header) {
|
|
190
|
+
return header.split("-").map((part) => {
|
|
191
|
+
return part[0].toUpperCase() + part.slice(1).toLowerCase();
|
|
192
|
+
}).join("-");
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
__name(_TransformHeadersAgent, "TransformHeadersAgent");
|
|
196
|
+
var TransformHeadersAgent = _TransformHeadersAgent;
|
|
197
|
+
|
|
198
|
+
// src/hooks/browser-headers.ts
|
|
199
|
+
import "got";
|
|
200
|
+
import http22 from "http2-wrapper";
|
|
201
|
+
import "node:url";
|
|
202
|
+
|
|
203
|
+
// src/resolve-protocol.ts
|
|
204
|
+
import { isIPv6 as isIPv62 } from "node:net";
|
|
205
|
+
import tls2 from "node:tls";
|
|
206
|
+
import { URL as URL3 } from "node:url";
|
|
207
|
+
import "got";
|
|
208
|
+
import { auto as auto2 } from "http2-wrapper";
|
|
209
|
+
import QuickLRU from "quick-lru";
|
|
210
|
+
|
|
211
|
+
// src/hooks/proxy.ts
|
|
212
|
+
import "got";
|
|
213
|
+
import http2, { auto } from "http2-wrapper";
|
|
214
|
+
import { URL as URL2 } from "node:url";
|
|
215
|
+
|
|
216
|
+
// src/agent/h1-proxy-agent.ts
|
|
217
|
+
import http from "node:http";
|
|
218
|
+
import https from "node:https";
|
|
219
|
+
import { isIPv6 } from "node:net";
|
|
220
|
+
import tls from "node:tls";
|
|
221
|
+
import { URL } from "node:url";
|
|
222
|
+
|
|
223
|
+
// src/auth.ts
|
|
224
|
+
function buildBasicAuthHeader(url) {
|
|
225
|
+
if (!url.username && !url.password) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
const username = decodeURIComponent(url.username ?? "");
|
|
229
|
+
const password = decodeURIComponent(url.password ?? "");
|
|
230
|
+
const basic = Buffer.from(`${username}:${password}`).toString("base64");
|
|
231
|
+
return `Basic ${basic}`;
|
|
232
|
+
}
|
|
233
|
+
__name(buildBasicAuthHeader, "buildBasicAuthHeader");
|
|
234
|
+
|
|
235
|
+
// src/agent/h1-proxy-agent.ts
|
|
236
|
+
var initialize = /* @__PURE__ */ __name((self, options) => {
|
|
237
|
+
self.proxy = typeof options.proxy === "string" ? new URL(options.proxy) : options.proxy;
|
|
238
|
+
}, "initialize");
|
|
239
|
+
var getPort = /* @__PURE__ */ __name((url) => {
|
|
240
|
+
if (url.port !== "") {
|
|
241
|
+
return Number(url.port);
|
|
242
|
+
}
|
|
243
|
+
if (url.protocol === "http:") {
|
|
244
|
+
return 80;
|
|
245
|
+
}
|
|
246
|
+
if (url.protocol === "https:") {
|
|
247
|
+
return 443;
|
|
248
|
+
}
|
|
249
|
+
throw new Error(`Unexpected protocol: ${url.protocol}`);
|
|
250
|
+
}, "getPort");
|
|
251
|
+
var _HttpRegularProxyAgent = class _HttpRegularProxyAgent extends http.Agent {
|
|
252
|
+
constructor(options) {
|
|
253
|
+
super(options);
|
|
254
|
+
__publicField(this, "proxy");
|
|
255
|
+
initialize(this, options);
|
|
256
|
+
}
|
|
257
|
+
addRequest(request, options) {
|
|
258
|
+
if (options.socketPath) {
|
|
259
|
+
super.addRequest(request, options);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
let hostport = `${options.host}:${options.port}`;
|
|
263
|
+
if (isIPv6(options.host)) {
|
|
264
|
+
hostport = `[${options.host}]:${options.port}`;
|
|
265
|
+
}
|
|
266
|
+
const url = new URL(`${request.protocol}//${hostport}${request.path}`);
|
|
267
|
+
options = {
|
|
268
|
+
...options,
|
|
269
|
+
host: this.proxy.hostname,
|
|
270
|
+
port: getPort(this.proxy)
|
|
271
|
+
};
|
|
272
|
+
request.path = url.href;
|
|
273
|
+
const basic = buildBasicAuthHeader(this.proxy);
|
|
274
|
+
if (basic) {
|
|
275
|
+
request.setHeader("proxy-authorization", basic);
|
|
276
|
+
}
|
|
277
|
+
super.addRequest(request, options);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
__name(_HttpRegularProxyAgent, "HttpRegularProxyAgent");
|
|
281
|
+
var HttpRegularProxyAgent = _HttpRegularProxyAgent;
|
|
282
|
+
var _HttpProxyAgent = class _HttpProxyAgent extends http.Agent {
|
|
283
|
+
constructor(options) {
|
|
284
|
+
super(options);
|
|
285
|
+
__publicField(this, "proxy");
|
|
286
|
+
initialize(this, options);
|
|
287
|
+
}
|
|
288
|
+
// @ts-expect-error New @types/node patch has narrower types than the originally exported got-scraping interface
|
|
289
|
+
createConnection(options, callback) {
|
|
290
|
+
if (options.path) {
|
|
291
|
+
super.createConnection(options, callback);
|
|
292
|
+
return;
|
|
293
|
+
}
|
|
294
|
+
const fn = this.proxy.protocol === "https:" ? https.request : http.request;
|
|
295
|
+
let hostport = `${options.host}:${options.port}`;
|
|
296
|
+
if (isIPv6(options.host)) {
|
|
297
|
+
hostport = `[${options.host}]:${options.port}`;
|
|
298
|
+
}
|
|
299
|
+
const headers = {
|
|
300
|
+
host: hostport
|
|
301
|
+
};
|
|
302
|
+
const basic = buildBasicAuthHeader(this.proxy);
|
|
303
|
+
if (basic) {
|
|
304
|
+
headers["proxy-authorization"] = basic;
|
|
305
|
+
headers.authorization = basic;
|
|
306
|
+
}
|
|
307
|
+
const connectRequest = fn(this.proxy, {
|
|
308
|
+
method: "CONNECT",
|
|
309
|
+
headers,
|
|
310
|
+
path: hostport,
|
|
311
|
+
agent: false,
|
|
312
|
+
rejectUnauthorized: false
|
|
313
|
+
});
|
|
314
|
+
connectRequest.once("connect", (response, socket, head) => {
|
|
315
|
+
if (head.length > 0 || response.statusCode !== 200) {
|
|
316
|
+
socket.destroy();
|
|
317
|
+
const error = new Error(`The proxy responded with ${response.statusCode} ${response.statusMessage}: ${head.toString()}`);
|
|
318
|
+
callback(error);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
if (options.protocol === "https:") {
|
|
322
|
+
callback(void 0, tls.connect({
|
|
323
|
+
...options,
|
|
324
|
+
socket
|
|
325
|
+
}));
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
callback(void 0, socket);
|
|
329
|
+
});
|
|
330
|
+
connectRequest.once("error", (error) => {
|
|
331
|
+
callback(error);
|
|
332
|
+
});
|
|
333
|
+
connectRequest.end();
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
__name(_HttpProxyAgent, "HttpProxyAgent");
|
|
337
|
+
var HttpProxyAgent = _HttpProxyAgent;
|
|
338
|
+
var _HttpsProxyAgent = class _HttpsProxyAgent extends https.Agent {
|
|
339
|
+
constructor(options) {
|
|
340
|
+
super(options);
|
|
341
|
+
__publicField(this, "proxy");
|
|
342
|
+
initialize(this, options);
|
|
343
|
+
}
|
|
344
|
+
// @ts-expect-error New @types/node patch has narrower types than the originally exported got-scraping interface
|
|
345
|
+
createConnection(options, callback) {
|
|
346
|
+
HttpProxyAgent.prototype.createConnection.call(this, options, callback);
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
__name(_HttpsProxyAgent, "HttpsProxyAgent");
|
|
350
|
+
var HttpsProxyAgent = _HttpsProxyAgent;
|
|
351
|
+
|
|
352
|
+
// src/hooks/proxy.ts
|
|
353
|
+
var {
|
|
354
|
+
HttpOverHttp2,
|
|
355
|
+
HttpsOverHttp2,
|
|
356
|
+
Http2OverHttp2,
|
|
357
|
+
Http2OverHttps,
|
|
358
|
+
Http2OverHttp
|
|
359
|
+
} = http2.proxies;
|
|
360
|
+
async function proxyHook(options) {
|
|
361
|
+
const { context: { proxyUrl } } = options;
|
|
362
|
+
if (proxyUrl) {
|
|
363
|
+
const parsedProxy = new URL2(proxyUrl);
|
|
364
|
+
validateProxyProtocol(parsedProxy.protocol);
|
|
365
|
+
options.agent = await getAgents(parsedProxy, options.https.rejectUnauthorized);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
__name(proxyHook, "proxyHook");
|
|
369
|
+
var _ProxyError = class _ProxyError extends Error {
|
|
370
|
+
};
|
|
371
|
+
__name(_ProxyError, "ProxyError");
|
|
372
|
+
var ProxyError = _ProxyError;
|
|
373
|
+
function validateProxyProtocol(protocol) {
|
|
374
|
+
const isSupported = protocol === "http:" || protocol === "https:";
|
|
375
|
+
if (!isSupported) {
|
|
376
|
+
throw new ProxyError(`Proxy URL protocol "${protocol}" is not supported. Please use HTTP or HTTPS.`);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
__name(validateProxyProtocol, "validateProxyProtocol");
|
|
380
|
+
async function getAgents(parsedProxyUrl, rejectUnauthorized) {
|
|
381
|
+
const headers = {};
|
|
382
|
+
const basic = buildBasicAuthHeader(parsedProxyUrl);
|
|
383
|
+
if (basic) {
|
|
384
|
+
headers.authorization = basic;
|
|
385
|
+
headers["proxy-authorization"] = basic;
|
|
386
|
+
}
|
|
387
|
+
const wrapperOptions = {
|
|
388
|
+
proxyOptions: {
|
|
389
|
+
url: parsedProxyUrl,
|
|
390
|
+
headers,
|
|
391
|
+
// Based on the got https.rejectUnauthorized option
|
|
392
|
+
rejectUnauthorized
|
|
393
|
+
},
|
|
394
|
+
// The sockets won't be reused, no need to keep them
|
|
395
|
+
maxFreeSockets: 0,
|
|
396
|
+
maxEmptySessions: 0
|
|
397
|
+
};
|
|
398
|
+
const nativeOptions = {
|
|
399
|
+
proxy: parsedProxyUrl,
|
|
400
|
+
// The sockets won't be reused, no need to keep them
|
|
401
|
+
maxFreeSockets: 0
|
|
402
|
+
};
|
|
403
|
+
let agent;
|
|
404
|
+
if (parsedProxyUrl.protocol === "https:") {
|
|
405
|
+
let alpnProtocol = "http/1.1";
|
|
406
|
+
try {
|
|
407
|
+
const result = await auto.resolveProtocol({
|
|
408
|
+
host: parsedProxyUrl.hostname,
|
|
409
|
+
port: parsedProxyUrl.port,
|
|
410
|
+
rejectUnauthorized,
|
|
411
|
+
ALPNProtocols: ["h2", "http/1.1"],
|
|
412
|
+
servername: parsedProxyUrl.hostname
|
|
413
|
+
});
|
|
414
|
+
alpnProtocol = result.alpnProtocol;
|
|
415
|
+
} catch {
|
|
416
|
+
}
|
|
417
|
+
const proxyIsHttp2 = alpnProtocol === "h2";
|
|
418
|
+
if (proxyIsHttp2) {
|
|
419
|
+
agent = {
|
|
420
|
+
http: new TransformHeadersAgent(new HttpOverHttp2(wrapperOptions)),
|
|
421
|
+
https: new TransformHeadersAgent(new HttpsOverHttp2(wrapperOptions)),
|
|
422
|
+
http2: new Http2OverHttp2(wrapperOptions)
|
|
423
|
+
};
|
|
424
|
+
} else {
|
|
425
|
+
agent = {
|
|
426
|
+
// @ts-expect-error New @types/node patch has narrower types than the originally exported got-scraping interface
|
|
427
|
+
http: new TransformHeadersAgent(new HttpProxyAgent(nativeOptions)),
|
|
428
|
+
// @ts-expect-error New @types/node patch has narrower types than the originally exported got-scraping interface
|
|
429
|
+
https: new TransformHeadersAgent(new HttpsProxyAgent(nativeOptions)),
|
|
430
|
+
http2: new Http2OverHttps(wrapperOptions)
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
} else {
|
|
434
|
+
agent = {
|
|
435
|
+
http: new TransformHeadersAgent(new HttpRegularProxyAgent(nativeOptions)),
|
|
436
|
+
// @ts-expect-error New @types/node patch has narrower types than the originally exported got-scraping interface
|
|
437
|
+
https: new TransformHeadersAgent(new HttpsProxyAgent(nativeOptions)),
|
|
438
|
+
http2: new Http2OverHttp(wrapperOptions)
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
return agent;
|
|
442
|
+
}
|
|
443
|
+
__name(getAgents, "getAgents");
|
|
444
|
+
|
|
445
|
+
// src/resolve-protocol.ts
|
|
446
|
+
var connect = /* @__PURE__ */ __name(async (proxyUrl, options, callback) => new Promise((resolve, reject) => {
|
|
447
|
+
let host = `${options.host}:${options.port}`;
|
|
448
|
+
if (isIPv62(options.host)) {
|
|
449
|
+
host = `[${options.host}]:${options.port}`;
|
|
450
|
+
}
|
|
451
|
+
void (async () => {
|
|
452
|
+
try {
|
|
453
|
+
const headers = {
|
|
454
|
+
host
|
|
455
|
+
};
|
|
456
|
+
const url = new URL3(proxyUrl);
|
|
457
|
+
const basic = buildBasicAuthHeader(url);
|
|
458
|
+
if (basic) {
|
|
459
|
+
headers.authorization = basic;
|
|
460
|
+
headers["proxy-authorization"] = basic;
|
|
461
|
+
}
|
|
462
|
+
const request = await auto2(url, {
|
|
463
|
+
method: "CONNECT",
|
|
464
|
+
headers,
|
|
465
|
+
path: host,
|
|
466
|
+
// TODO: this property doesn't exist according to the types
|
|
467
|
+
pathname: host,
|
|
468
|
+
rejectUnauthorized: false
|
|
469
|
+
});
|
|
470
|
+
request.end();
|
|
471
|
+
request.once("error", reject);
|
|
472
|
+
request.once("connect", (response, socket, head) => {
|
|
473
|
+
if (response.statusCode !== 200 || head.length > 0) {
|
|
474
|
+
reject(new ProxyError(`Proxy responded with ${response.statusCode} ${response.statusMessage}: ${head.length} bytes.
|
|
475
|
+
|
|
476
|
+
Below is the first 100 bytes of the proxy response body:
|
|
477
|
+
${head.toString("utf8", 0, 100)}`, { cause: head.toString("utf8") }));
|
|
478
|
+
socket.destroy();
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
const tlsSocket = tls2.connect({
|
|
482
|
+
...options,
|
|
483
|
+
socket
|
|
484
|
+
}, callback);
|
|
485
|
+
resolve(tlsSocket);
|
|
486
|
+
});
|
|
487
|
+
} catch (error) {
|
|
488
|
+
reject(error);
|
|
489
|
+
}
|
|
490
|
+
})();
|
|
491
|
+
}), "connect");
|
|
492
|
+
var createCaches = /* @__PURE__ */ __name(() => ({
|
|
493
|
+
protocolCache: new QuickLRU({ maxSize: 1e3 }),
|
|
494
|
+
resolveAlpnQueue: /* @__PURE__ */ new Map()
|
|
495
|
+
}), "createCaches");
|
|
496
|
+
var defaults = createCaches();
|
|
497
|
+
var createResolveProtocol = /* @__PURE__ */ __name((proxyUrl, sessionData, timeout) => {
|
|
498
|
+
let { protocolCache, resolveAlpnQueue } = defaults;
|
|
499
|
+
if (sessionData) {
|
|
500
|
+
if (!sessionData.protocolCache || !sessionData.resolveAlpnQueue) {
|
|
501
|
+
Object.assign(sessionData, createCaches());
|
|
502
|
+
}
|
|
503
|
+
protocolCache = sessionData.protocolCache;
|
|
504
|
+
resolveAlpnQueue = sessionData.resolveAlpnQueue;
|
|
505
|
+
}
|
|
506
|
+
const connectWithProxy = /* @__PURE__ */ __name(async (pOptions, pCallback) => {
|
|
507
|
+
return connect(proxyUrl, pOptions, pCallback);
|
|
508
|
+
}, "connectWithProxy");
|
|
509
|
+
const resolveProtocol = auto2.createResolveProtocol(
|
|
510
|
+
protocolCache,
|
|
511
|
+
resolveAlpnQueue,
|
|
512
|
+
connectWithProxy
|
|
513
|
+
);
|
|
514
|
+
return async (...args) => resolveProtocol({
|
|
515
|
+
...args[0],
|
|
516
|
+
timeout
|
|
517
|
+
});
|
|
518
|
+
}, "createResolveProtocol");
|
|
519
|
+
|
|
520
|
+
// src/hooks/browser-headers.ts
|
|
521
|
+
function mergeHeaders(original, overrides) {
|
|
522
|
+
const fixedHeaders = /* @__PURE__ */ new Map();
|
|
523
|
+
for (const entry of Object.entries(original)) {
|
|
524
|
+
fixedHeaders.set(entry[0].toLowerCase(), entry);
|
|
525
|
+
}
|
|
526
|
+
for (const entry of Object.entries(overrides)) {
|
|
527
|
+
fixedHeaders.set(entry[0].toLowerCase(), entry);
|
|
528
|
+
}
|
|
529
|
+
return Object.fromEntries(fixedHeaders.values());
|
|
530
|
+
}
|
|
531
|
+
__name(mergeHeaders, "mergeHeaders");
|
|
532
|
+
var getResolveProtocolFunction = /* @__PURE__ */ __name((options, proxyUrl, sessionData) => {
|
|
533
|
+
const { resolveProtocol } = options;
|
|
534
|
+
if (resolveProtocol) {
|
|
535
|
+
return resolveProtocol;
|
|
536
|
+
}
|
|
537
|
+
if (proxyUrl) {
|
|
538
|
+
return createResolveProtocol(proxyUrl, sessionData, Math.min(options?.timeout?.connect ?? 6e4, options?.timeout?.request ?? 6e4));
|
|
539
|
+
}
|
|
540
|
+
return (...args) => http22.auto.resolveProtocol({
|
|
541
|
+
...args[0],
|
|
542
|
+
timeout: Math.min(options?.timeout?.connect ?? 6e4, options?.timeout?.request ?? 6e4)
|
|
543
|
+
});
|
|
544
|
+
}, "getResolveProtocolFunction");
|
|
545
|
+
async function browserHeadersHook(options) {
|
|
546
|
+
const { context } = options;
|
|
547
|
+
const {
|
|
548
|
+
headerGeneratorOptions,
|
|
549
|
+
useHeaderGenerator,
|
|
550
|
+
headerGenerator,
|
|
551
|
+
proxyUrl
|
|
552
|
+
} = context;
|
|
553
|
+
const sessionData = context.sessionData;
|
|
554
|
+
if (!useHeaderGenerator || !headerGenerator)
|
|
555
|
+
return;
|
|
556
|
+
const createHeadersPair = /* @__PURE__ */ __name(() => ({
|
|
557
|
+
1: headerGenerator.getHeaders({
|
|
558
|
+
httpVersion: "1",
|
|
559
|
+
...headerGeneratorOptions
|
|
560
|
+
}),
|
|
561
|
+
2: headerGenerator.getHeaders({
|
|
562
|
+
httpVersion: "2",
|
|
563
|
+
...headerGeneratorOptions
|
|
564
|
+
})
|
|
565
|
+
}), "createHeadersPair");
|
|
566
|
+
const url = options.url;
|
|
567
|
+
const resolveProtocol = getResolveProtocolFunction(options, proxyUrl, sessionData);
|
|
568
|
+
let alpnProtocol;
|
|
569
|
+
if (url.protocol === "https:") {
|
|
570
|
+
alpnProtocol = (await resolveProtocol({
|
|
571
|
+
host: url.hostname,
|
|
572
|
+
port: url.port || 443,
|
|
573
|
+
rejectUnauthorized: false,
|
|
574
|
+
ALPNProtocols: ["h2", "http/1.1"],
|
|
575
|
+
servername: url.hostname
|
|
576
|
+
})).alpnProtocol;
|
|
577
|
+
}
|
|
578
|
+
const httpVersion = alpnProtocol === "h2" ? "2" : "1";
|
|
579
|
+
let generatedHeaders;
|
|
580
|
+
if (sessionData) {
|
|
581
|
+
if (!sessionData.headers) {
|
|
582
|
+
sessionData.headers = createHeadersPair();
|
|
583
|
+
}
|
|
584
|
+
generatedHeaders = sessionData.headers[httpVersion];
|
|
585
|
+
} else {
|
|
586
|
+
generatedHeaders = headerGenerator.getHeaders({
|
|
587
|
+
httpVersion,
|
|
588
|
+
...headerGeneratorOptions
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
if (!options.decompress) {
|
|
592
|
+
for (const key of Object.keys(generatedHeaders)) {
|
|
593
|
+
if (key.toLowerCase() === "accept-encoding") {
|
|
594
|
+
delete generatedHeaders[key];
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
options.headers = mergeHeaders(generatedHeaders, options.headers);
|
|
599
|
+
}
|
|
600
|
+
__name(browserHeadersHook, "browserHeadersHook");
|
|
601
|
+
|
|
602
|
+
// src/hooks/custom-options.ts
|
|
603
|
+
import "got";
|
|
604
|
+
function customOptionsHook(raw, options) {
|
|
605
|
+
const typedRaw = raw;
|
|
606
|
+
const names = [
|
|
607
|
+
"proxyUrl",
|
|
608
|
+
"headerGeneratorOptions",
|
|
609
|
+
"useHeaderGenerator",
|
|
610
|
+
"insecureHTTPParser",
|
|
611
|
+
"sessionToken"
|
|
612
|
+
];
|
|
613
|
+
for (const name of names) {
|
|
614
|
+
if (name in raw) {
|
|
615
|
+
options.context[name] = typedRaw[name];
|
|
616
|
+
delete typedRaw[name];
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
__name(customOptionsHook, "customOptionsHook");
|
|
621
|
+
|
|
622
|
+
// src/hooks/fix-decompress.ts
|
|
623
|
+
import zlib from "node:zlib";
|
|
624
|
+
import "node:http";
|
|
625
|
+
import { PassThrough } from "node:stream";
|
|
626
|
+
import mimicResponse from "mimic-response";
|
|
627
|
+
var onResponse = /* @__PURE__ */ __name((response, propagate) => {
|
|
628
|
+
const encoding = response.headers["content-encoding"]?.toLowerCase();
|
|
629
|
+
const zlibOptions = {
|
|
630
|
+
flush: zlib.constants.Z_SYNC_FLUSH,
|
|
631
|
+
finishFlush: zlib.constants.Z_SYNC_FLUSH
|
|
632
|
+
};
|
|
633
|
+
const useDecompressor = /* @__PURE__ */ __name((decompressor) => {
|
|
634
|
+
delete response.headers["content-encoding"];
|
|
635
|
+
const result = new PassThrough({
|
|
636
|
+
autoDestroy: false,
|
|
637
|
+
destroy(error, callback) {
|
|
638
|
+
response.destroy();
|
|
639
|
+
callback(error);
|
|
640
|
+
}
|
|
641
|
+
});
|
|
642
|
+
decompressor.once("error", (error) => {
|
|
643
|
+
result.destroy(error);
|
|
644
|
+
});
|
|
645
|
+
response.pipe(decompressor).pipe(result);
|
|
646
|
+
propagate(mimicResponse(response, result));
|
|
647
|
+
}, "useDecompressor");
|
|
648
|
+
if (encoding === "gzip" || encoding === "x-gzip") {
|
|
649
|
+
useDecompressor(zlib.createGunzip(zlibOptions));
|
|
650
|
+
} else if (encoding === "deflate" || encoding === "x-deflate") {
|
|
651
|
+
let read = false;
|
|
652
|
+
response.once("data", (chunk) => {
|
|
653
|
+
read = true;
|
|
654
|
+
response.unshift(chunk);
|
|
655
|
+
const decompressor = (chunk[0] & 15) === 8 ? zlib.createInflate() : zlib.createInflateRaw();
|
|
656
|
+
useDecompressor(decompressor);
|
|
657
|
+
});
|
|
658
|
+
response.once("end", () => {
|
|
659
|
+
if (!read) {
|
|
660
|
+
propagate(response);
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
} else if (encoding === "br") {
|
|
664
|
+
let read = false;
|
|
665
|
+
response.once("data", (chunk) => {
|
|
666
|
+
read = true;
|
|
667
|
+
response.unshift(chunk);
|
|
668
|
+
const decompressor = zlib.createBrotliDecompress();
|
|
669
|
+
useDecompressor(decompressor);
|
|
670
|
+
});
|
|
671
|
+
response.once("end", () => {
|
|
672
|
+
if (!read) {
|
|
673
|
+
propagate(response);
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
} else {
|
|
677
|
+
propagate(response);
|
|
678
|
+
}
|
|
679
|
+
}, "onResponse");
|
|
680
|
+
var fixDecompress = /* @__PURE__ */ __name((options, next) => {
|
|
681
|
+
const result = next(options);
|
|
682
|
+
result.on("request", (request) => {
|
|
683
|
+
const emit = request.emit.bind(request);
|
|
684
|
+
request.emit = (event, ...args) => {
|
|
685
|
+
if (event === "response" && options.decompress) {
|
|
686
|
+
const response = args[0];
|
|
687
|
+
const emitted = request.listenerCount("response") !== 0;
|
|
688
|
+
onResponse(response, (fixedResponse) => {
|
|
689
|
+
emit("response", fixedResponse);
|
|
690
|
+
});
|
|
691
|
+
return emitted;
|
|
692
|
+
}
|
|
693
|
+
return emit(event, ...args);
|
|
694
|
+
};
|
|
695
|
+
});
|
|
696
|
+
return result;
|
|
697
|
+
}, "fixDecompress");
|
|
698
|
+
|
|
699
|
+
// src/hooks/http2.ts
|
|
700
|
+
import "node:url";
|
|
701
|
+
import "got";
|
|
702
|
+
import { auto as auto3 } from "http2-wrapper";
|
|
703
|
+
function http2Hook(options) {
|
|
704
|
+
const { proxyUrl, sessionData } = options.context;
|
|
705
|
+
if (options.http2 && options.url.protocol !== "http:") {
|
|
706
|
+
options.request = (url, requestOptions, callback) => {
|
|
707
|
+
const typedRequestOptions = requestOptions;
|
|
708
|
+
if (proxyUrl) {
|
|
709
|
+
typedRequestOptions.resolveProtocol = createResolveProtocol(
|
|
710
|
+
proxyUrl,
|
|
711
|
+
sessionData,
|
|
712
|
+
Math.min(options?.timeout?.connect ?? 6e4, options?.timeout?.request ?? 6e4)
|
|
713
|
+
);
|
|
714
|
+
}
|
|
715
|
+
return auto3(url, typedRequestOptions, callback);
|
|
716
|
+
};
|
|
717
|
+
} else {
|
|
718
|
+
options.request = void 0;
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
__name(http2Hook, "http2Hook");
|
|
722
|
+
|
|
723
|
+
// src/hooks/insecure-parser.ts
|
|
724
|
+
import "got";
|
|
725
|
+
function insecureParserHook(options) {
|
|
726
|
+
if (options.context.insecureHTTPParser !== void 0) {
|
|
727
|
+
options._unixOptions = {
|
|
728
|
+
// @ts-expect-error Private use
|
|
729
|
+
...options._unixOptions,
|
|
730
|
+
insecureHTTPParser: options.context.insecureHTTPParser
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
__name(insecureParserHook, "insecureParserHook");
|
|
735
|
+
|
|
736
|
+
// src/hooks/options-validation.ts
|
|
737
|
+
import ow from "ow";
|
|
738
|
+
var validationSchema = {
|
|
739
|
+
proxyUrl: ow.optional.string.url,
|
|
740
|
+
useHeaderGenerator: ow.optional.boolean,
|
|
741
|
+
headerGeneratorOptions: ow.optional.object,
|
|
742
|
+
insecureHTTPParser: ow.optional.boolean,
|
|
743
|
+
sessionToken: ow.optional.object
|
|
744
|
+
};
|
|
745
|
+
function optionsValidationHandler(options) {
|
|
746
|
+
ow(options, ow.object.partialShape(validationSchema));
|
|
747
|
+
}
|
|
748
|
+
__name(optionsValidationHandler, "optionsValidationHandler");
|
|
749
|
+
|
|
750
|
+
// src/hooks/referer.ts
|
|
751
|
+
import { URL as URL6 } from "node:url";
|
|
752
|
+
var refererHook = /* @__PURE__ */ __name((options, response) => {
|
|
753
|
+
const url = options.url;
|
|
754
|
+
const resUrl = new URL6(response.url);
|
|
755
|
+
const policy = response.headers["referer-policy"] || "strict-origin-when-cross-origin";
|
|
756
|
+
if (policy === "no-referrer") {
|
|
757
|
+
delete options.headers.referer;
|
|
758
|
+
} else if (policy === "no-referrer-when-downgrade") {
|
|
759
|
+
if (resUrl.protocol === "https:" && url.protocol === "http:") {
|
|
760
|
+
delete options.headers.referer;
|
|
761
|
+
} else {
|
|
762
|
+
options.headers.referer = `${resUrl.origin}${resUrl.pathname}${resUrl.search}`;
|
|
763
|
+
}
|
|
764
|
+
} else if (policy === "origin") {
|
|
765
|
+
options.headers.referer = resUrl.origin;
|
|
766
|
+
} else if (policy === "origin-when-cross-origin") {
|
|
767
|
+
if (url.origin === resUrl.origin) {
|
|
768
|
+
options.headers.referer = `${resUrl.origin}${resUrl.pathname}${resUrl.search}`;
|
|
769
|
+
} else {
|
|
770
|
+
options.headers.referer = resUrl.origin;
|
|
771
|
+
}
|
|
772
|
+
} else if (policy === "same-origin") {
|
|
773
|
+
if (url.origin === resUrl.origin) {
|
|
774
|
+
options.headers.referer = `${resUrl.origin}${resUrl.pathname}${resUrl.search}`;
|
|
775
|
+
} else {
|
|
776
|
+
delete options.headers.referer;
|
|
777
|
+
}
|
|
778
|
+
} else if (policy === "strict-origin") {
|
|
779
|
+
if (resUrl.protocol === "https:" && url.protocol === "http:") {
|
|
780
|
+
delete options.headers.referer;
|
|
781
|
+
} else {
|
|
782
|
+
options.headers.referer = resUrl.origin;
|
|
783
|
+
}
|
|
784
|
+
} else if (policy === "strict-origin-when-cross-origin") {
|
|
785
|
+
if (url.origin === resUrl.origin) {
|
|
786
|
+
options.headers.referer = `${resUrl.origin}${resUrl.pathname}${resUrl.search}`;
|
|
787
|
+
} else if (resUrl.protocol === "https:" && url.protocol === "http:") {
|
|
788
|
+
delete options.headers.referer;
|
|
789
|
+
} else {
|
|
790
|
+
options.headers.referer = resUrl.origin;
|
|
791
|
+
}
|
|
792
|
+
} else if (policy === "unsafe-url") {
|
|
793
|
+
options.headers.referer = `${resUrl.origin}${resUrl.pathname}${resUrl.search}`;
|
|
794
|
+
}
|
|
795
|
+
}, "refererHook");
|
|
796
|
+
|
|
797
|
+
// src/hooks/storage.ts
|
|
798
|
+
import "got";
|
|
799
|
+
var _Storage = class _Storage {
|
|
800
|
+
constructor() {
|
|
801
|
+
__publicField(this, "storage");
|
|
802
|
+
this.storage = /* @__PURE__ */ new WeakMap();
|
|
803
|
+
}
|
|
804
|
+
get(token) {
|
|
805
|
+
if (!token) {
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (!this.storage.has(token)) {
|
|
809
|
+
this.storage.set(token, {});
|
|
810
|
+
}
|
|
811
|
+
return this.storage.get(token);
|
|
812
|
+
}
|
|
813
|
+
};
|
|
814
|
+
__name(_Storage, "Storage");
|
|
815
|
+
var Storage = _Storage;
|
|
816
|
+
var storage = new Storage();
|
|
817
|
+
var sessionDataHook = /* @__PURE__ */ __name((options) => {
|
|
818
|
+
options.context.sessionData = storage.get(options.context.sessionToken);
|
|
819
|
+
}, "sessionDataHook");
|
|
820
|
+
|
|
821
|
+
// src/hooks/tls.ts
|
|
822
|
+
import "got";
|
|
823
|
+
var supportsFirefoxFully = Number(process.versions.node.split(".")[0]) >= 17;
|
|
824
|
+
var SSL_OP_TLSEXT_PADDING = 1 << 4;
|
|
825
|
+
var SSL_OP_NO_ENCRYPT_THEN_MAC = 1 << 19;
|
|
826
|
+
var ecdhCurve = {
|
|
827
|
+
firefox: (supportsFirefoxFully ? [
|
|
828
|
+
"X25519",
|
|
829
|
+
"prime256v1",
|
|
830
|
+
"secp384r1",
|
|
831
|
+
"secp521r1",
|
|
832
|
+
"ffdhe2048",
|
|
833
|
+
"ffdhe3072"
|
|
834
|
+
] : [
|
|
835
|
+
"X25519",
|
|
836
|
+
"prime256v1",
|
|
837
|
+
"secp384r1",
|
|
838
|
+
"secp521r1"
|
|
839
|
+
]).join(":"),
|
|
840
|
+
chrome: [
|
|
841
|
+
"X25519",
|
|
842
|
+
"prime256v1",
|
|
843
|
+
"secp384r1"
|
|
844
|
+
].join(":"),
|
|
845
|
+
safari: [
|
|
846
|
+
"X25519",
|
|
847
|
+
"prime256v1",
|
|
848
|
+
"secp384r1",
|
|
849
|
+
"secp521r1"
|
|
850
|
+
].join(":")
|
|
851
|
+
};
|
|
852
|
+
var sigalgs = {
|
|
853
|
+
firefox: [
|
|
854
|
+
"ecdsa_secp256r1_sha256",
|
|
855
|
+
"ecdsa_secp384r1_sha384",
|
|
856
|
+
"ecdsa_secp521r1_sha512",
|
|
857
|
+
"rsa_pss_rsae_sha256",
|
|
858
|
+
"rsa_pss_rsae_sha384",
|
|
859
|
+
"rsa_pss_rsae_sha512",
|
|
860
|
+
"rsa_pkcs1_sha256",
|
|
861
|
+
"rsa_pkcs1_sha384",
|
|
862
|
+
"rsa_pkcs1_sha512",
|
|
863
|
+
"ECDSA+SHA1",
|
|
864
|
+
"rsa_pkcs1_sha1"
|
|
865
|
+
].join(":"),
|
|
866
|
+
chrome: [
|
|
867
|
+
"ecdsa_secp256r1_sha256",
|
|
868
|
+
"rsa_pss_rsae_sha256",
|
|
869
|
+
"rsa_pkcs1_sha256",
|
|
870
|
+
"ecdsa_secp384r1_sha384",
|
|
871
|
+
"rsa_pss_rsae_sha384",
|
|
872
|
+
"rsa_pkcs1_sha384",
|
|
873
|
+
"rsa_pss_rsae_sha512",
|
|
874
|
+
"rsa_pkcs1_sha512"
|
|
875
|
+
].join(":"),
|
|
876
|
+
safari: [
|
|
877
|
+
"ecdsa_secp256r1_sha256",
|
|
878
|
+
"rsa_pss_rsae_sha256",
|
|
879
|
+
"rsa_pkcs1_sha256",
|
|
880
|
+
"ecdsa_secp384r1_sha384",
|
|
881
|
+
"ECDSA+SHA1",
|
|
882
|
+
"rsa_pss_rsae_sha384",
|
|
883
|
+
"rsa_pkcs1_sha384",
|
|
884
|
+
"rsa_pss_rsae_sha512",
|
|
885
|
+
"rsa_pkcs1_sha512",
|
|
886
|
+
"RSA+SHA1"
|
|
887
|
+
].join(":")
|
|
888
|
+
};
|
|
889
|
+
var knownCiphers = {
|
|
890
|
+
chrome: [
|
|
891
|
+
// Chrome v92
|
|
892
|
+
"TLS_AES_128_GCM_SHA256",
|
|
893
|
+
"TLS_AES_256_GCM_SHA384",
|
|
894
|
+
"TLS_CHACHA20_POLY1305_SHA256",
|
|
895
|
+
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
|
896
|
+
"ECDHE-RSA-AES128-GCM-SHA256",
|
|
897
|
+
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
|
898
|
+
"ECDHE-RSA-AES256-GCM-SHA384",
|
|
899
|
+
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
900
|
+
"ECDHE-RSA-CHACHA20-POLY1305",
|
|
901
|
+
// Legacy:
|
|
902
|
+
"ECDHE-RSA-AES128-SHA",
|
|
903
|
+
"ECDHE-RSA-AES256-SHA",
|
|
904
|
+
"AES128-GCM-SHA256",
|
|
905
|
+
"AES256-GCM-SHA384",
|
|
906
|
+
"AES128-SHA",
|
|
907
|
+
"AES256-SHA"
|
|
908
|
+
].join(":"),
|
|
909
|
+
firefox: [
|
|
910
|
+
// Firefox v91
|
|
911
|
+
"TLS_AES_128_GCM_SHA256",
|
|
912
|
+
"TLS_CHACHA20_POLY1305_SHA256",
|
|
913
|
+
"TLS_AES_256_GCM_SHA384",
|
|
914
|
+
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
|
915
|
+
"ECDHE-RSA-AES128-GCM-SHA256",
|
|
916
|
+
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
917
|
+
"ECDHE-RSA-CHACHA20-POLY1305",
|
|
918
|
+
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
|
919
|
+
"ECDHE-RSA-AES256-GCM-SHA384",
|
|
920
|
+
// Legacy:
|
|
921
|
+
"ECDHE-ECDSA-AES256-SHA",
|
|
922
|
+
"ECDHE-ECDSA-AES128-SHA",
|
|
923
|
+
"ECDHE-RSA-AES128-SHA",
|
|
924
|
+
"ECDHE-RSA-AES256-SHA",
|
|
925
|
+
"AES128-GCM-SHA256",
|
|
926
|
+
"AES256-GCM-SHA384",
|
|
927
|
+
"AES128-SHA",
|
|
928
|
+
"AES256-SHA",
|
|
929
|
+
"DES-CBC3-SHA"
|
|
930
|
+
].join(":"),
|
|
931
|
+
safari: [
|
|
932
|
+
// Safari v14
|
|
933
|
+
"TLS_AES_128_GCM_SHA256",
|
|
934
|
+
"TLS_AES_256_GCM_SHA384",
|
|
935
|
+
"TLS_CHACHA20_POLY1305_SHA256",
|
|
936
|
+
"ECDHE-ECDSA-AES256-GCM-SHA384",
|
|
937
|
+
"ECDHE-ECDSA-AES128-GCM-SHA256",
|
|
938
|
+
"ECDHE-ECDSA-CHACHA20-POLY1305",
|
|
939
|
+
"ECDHE-RSA-AES256-GCM-SHA384",
|
|
940
|
+
"ECDHE-RSA-AES128-GCM-SHA256",
|
|
941
|
+
"ECDHE-RSA-CHACHA20-POLY1305",
|
|
942
|
+
// Legacy:
|
|
943
|
+
"ECDHE-ECDSA-AES256-SHA384",
|
|
944
|
+
"ECDHE-ECDSA-AES128-SHA256",
|
|
945
|
+
"ECDHE-ECDSA-AES256-SHA",
|
|
946
|
+
"ECDHE-ECDSA-AES128-SHA",
|
|
947
|
+
"ECDHE-RSA-AES256-SHA384",
|
|
948
|
+
"ECDHE-RSA-AES128-SHA256",
|
|
949
|
+
"ECDHE-RSA-AES256-SHA",
|
|
950
|
+
"ECDHE-RSA-AES128-SHA",
|
|
951
|
+
"AES256-GCM-SHA384",
|
|
952
|
+
"AES128-GCM-SHA256",
|
|
953
|
+
"AES256-SHA256",
|
|
954
|
+
"AES128-SHA256",
|
|
955
|
+
"AES256-SHA",
|
|
956
|
+
"AES128-SHA",
|
|
957
|
+
"ECDHE-ECDSA-DES-CBC3-SHA",
|
|
958
|
+
"ECDHE-RSA-DES-CBC3-SHA",
|
|
959
|
+
"DES-CBC3-SHA"
|
|
960
|
+
].join(":")
|
|
961
|
+
};
|
|
962
|
+
var minVersion = {
|
|
963
|
+
firefox: "TLSv1.2",
|
|
964
|
+
chrome: "TLSv1",
|
|
965
|
+
safari: "TLSv1.2"
|
|
966
|
+
};
|
|
967
|
+
var maxVersion = {
|
|
968
|
+
firefox: "TLSv1.3",
|
|
969
|
+
chrome: "TLSv1.3",
|
|
970
|
+
safari: "TLSv1.3"
|
|
971
|
+
};
|
|
972
|
+
var secureOptions = {
|
|
973
|
+
firefox: SSL_OP_TLSEXT_PADDING | SSL_OP_NO_ENCRYPT_THEN_MAC,
|
|
974
|
+
chrome: SSL_OP_TLSEXT_PADDING | SSL_OP_NO_ENCRYPT_THEN_MAC,
|
|
975
|
+
safari: SSL_OP_TLSEXT_PADDING | SSL_OP_NO_ENCRYPT_THEN_MAC
|
|
976
|
+
};
|
|
977
|
+
var requestOCSP = {
|
|
978
|
+
firefox: true,
|
|
979
|
+
chrome: true,
|
|
980
|
+
safari: true
|
|
981
|
+
};
|
|
982
|
+
var getUserAgent = /* @__PURE__ */ __name((headers) => {
|
|
983
|
+
for (const [header, value] of Object.entries(headers)) {
|
|
984
|
+
if (header.toLowerCase() === "user-agent") {
|
|
985
|
+
return value;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
return void 0;
|
|
989
|
+
}, "getUserAgent");
|
|
990
|
+
var getBrowser = /* @__PURE__ */ __name((userAgent) => {
|
|
991
|
+
if (!userAgent) {
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
let browser;
|
|
995
|
+
if (userAgent.includes("Firefox")) {
|
|
996
|
+
browser = "firefox";
|
|
997
|
+
} else if (userAgent.includes("Chrome")) {
|
|
998
|
+
browser = "chrome";
|
|
999
|
+
} else {
|
|
1000
|
+
browser = "safari";
|
|
1001
|
+
}
|
|
1002
|
+
return browser;
|
|
1003
|
+
}, "getBrowser");
|
|
1004
|
+
function tlsHook(options) {
|
|
1005
|
+
const { https: https3 } = options;
|
|
1006
|
+
if (https3.ciphers || https3.signatureAlgorithms || https3.minVersion || https3.maxVersion) {
|
|
1007
|
+
return;
|
|
1008
|
+
}
|
|
1009
|
+
const browser = getBrowser(getUserAgent(options.headers)) ?? "firefox";
|
|
1010
|
+
https3.ciphers = knownCiphers[browser];
|
|
1011
|
+
https3.signatureAlgorithms = sigalgs[browser];
|
|
1012
|
+
https3.ecdhCurve = ecdhCurve[browser];
|
|
1013
|
+
https3.minVersion = minVersion[browser];
|
|
1014
|
+
https3.maxVersion = maxVersion[browser];
|
|
1015
|
+
options._unixOptions = {
|
|
1016
|
+
// @ts-expect-error Private use
|
|
1017
|
+
...options._unixOptions,
|
|
1018
|
+
secureOptions: secureOptions[browser],
|
|
1019
|
+
requestOCSP: requestOCSP[browser]
|
|
1020
|
+
};
|
|
1021
|
+
}
|
|
1022
|
+
__name(tlsHook, "tlsHook");
|
|
1023
|
+
|
|
1024
|
+
// src/index.ts
|
|
1025
|
+
export * from "got";
|
|
1026
|
+
var handlers = [
|
|
1027
|
+
fixDecompress
|
|
1028
|
+
];
|
|
1029
|
+
var beforeRequest = [
|
|
1030
|
+
insecureParserHook,
|
|
1031
|
+
sessionDataHook,
|
|
1032
|
+
http2Hook,
|
|
1033
|
+
proxyHook,
|
|
1034
|
+
browserHeadersHook,
|
|
1035
|
+
tlsHook
|
|
1036
|
+
];
|
|
1037
|
+
var init = [
|
|
1038
|
+
optionsValidationHandler,
|
|
1039
|
+
customOptionsHook
|
|
1040
|
+
];
|
|
1041
|
+
var beforeRedirect = [
|
|
1042
|
+
refererHook
|
|
1043
|
+
];
|
|
1044
|
+
function createGotScrapingOptions() {
|
|
1045
|
+
return {
|
|
1046
|
+
handlers,
|
|
1047
|
+
mutableDefaults: true,
|
|
1048
|
+
// Most of the new browsers use HTTP/2
|
|
1049
|
+
http2: true,
|
|
1050
|
+
https: {
|
|
1051
|
+
// In contrast to browsers, we don't usually do login operations.
|
|
1052
|
+
// We want the content.
|
|
1053
|
+
rejectUnauthorized: false
|
|
1054
|
+
},
|
|
1055
|
+
// Don't fail on 404
|
|
1056
|
+
throwHttpErrors: false,
|
|
1057
|
+
timeout: { request: 6e4 },
|
|
1058
|
+
retry: { limit: 0 },
|
|
1059
|
+
headers: {
|
|
1060
|
+
"user-agent": void 0
|
|
1061
|
+
},
|
|
1062
|
+
context: {
|
|
1063
|
+
headerGenerator: new HeaderGenerator2(),
|
|
1064
|
+
useHeaderGenerator: true,
|
|
1065
|
+
insecureHTTPParser: true
|
|
1066
|
+
},
|
|
1067
|
+
agent: {
|
|
1068
|
+
http: new TransformHeadersAgent(http3.globalAgent),
|
|
1069
|
+
https: new TransformHeadersAgent(https2.globalAgent)
|
|
1070
|
+
},
|
|
1071
|
+
hooks: {
|
|
1072
|
+
init,
|
|
1073
|
+
beforeRequest,
|
|
1074
|
+
beforeRedirect
|
|
1075
|
+
}
|
|
1076
|
+
};
|
|
1077
|
+
}
|
|
1078
|
+
__name(createGotScrapingOptions, "createGotScrapingOptions");
|
|
1079
|
+
var gotScraping = originalGot.extend(createGotScrapingOptions());
|
|
1080
|
+
var setupDecodeURI = /* @__PURE__ */ __name(() => {
|
|
1081
|
+
const { set } = Object.getOwnPropertyDescriptor(Options8.prototype, "url");
|
|
1082
|
+
Object.defineProperty(Options8.prototype, "url", {
|
|
1083
|
+
set(value) {
|
|
1084
|
+
const originalDecodeURI = global.decodeURI;
|
|
1085
|
+
global.decodeURI = (str) => str;
|
|
1086
|
+
try {
|
|
1087
|
+
return set.call(this, value);
|
|
1088
|
+
} finally {
|
|
1089
|
+
global.decodeURI = originalDecodeURI;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
}, "setupDecodeURI");
|
|
1094
|
+
setupDecodeURI();
|
|
1095
|
+
var hooks = {
|
|
1096
|
+
init,
|
|
1097
|
+
beforeRequest,
|
|
1098
|
+
beforeRedirect,
|
|
1099
|
+
fixDecompress,
|
|
1100
|
+
insecureParserHook,
|
|
1101
|
+
sessionDataHook,
|
|
1102
|
+
http2Hook,
|
|
1103
|
+
proxyHook,
|
|
1104
|
+
browserHeadersHook,
|
|
1105
|
+
tlsHook,
|
|
1106
|
+
optionsValidationHandler,
|
|
1107
|
+
customOptionsHook,
|
|
1108
|
+
refererHook
|
|
1109
|
+
};
|
|
1110
|
+
export {
|
|
1111
|
+
TransformHeadersAgent,
|
|
1112
|
+
createGotScrapingOptions,
|
|
1113
|
+
getAgents,
|
|
1114
|
+
gotScraping,
|
|
1115
|
+
hooks
|
|
1116
|
+
};
|
|
1117
|
+
//# sourceMappingURL=index.js.map
|