/
proxy.js
95 lines (89 loc) · 3.22 KB
/
proxy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
const got = require("got");
const CookieHandler = require("../lib/cookies");
const {setHeaders, setAgent} = require("../lib/options");
const type = require("../util/types");
// Responsible for applying proxy
const requestHandler = async (request, proxy, overrides = {}) => {
// Reject non http(s) URI schemes
if (!request.url().startsWith("http") && !request.url().startsWith("https")) {
request.continue(); return;
}
const cookieHandler = new CookieHandler(request);
// Request options for GOT accounting for overrides
const options = {
cookieJar: await cookieHandler.getCookies(),
method: overrides.method || request.method(),
body: overrides.postData || request.postData(),
headers: overrides.headers || setHeaders(request),
agent: setAgent(proxy),
responseType: "buffer",
maxRedirects: 15,
throwHttpErrors: false,
ignoreInvalidCookies: true,
followRedirect: false
};
try {
const response = await got(overrides.url || request.url(), options);
// Set cookies manually because "set-cookie" doesn't set all cookies (?)
// Perhaps related to https://github.com/puppeteer/puppeteer/issues/5364
const setCookieHeader = response.headers["set-cookie"];
if (setCookieHeader) {
await cookieHandler.setCookies(setCookieHeader);
response.headers["set-cookie"] = undefined;
}
await request.respond({
status: response.statusCode,
headers: response.headers,
body: response.body
});
} catch (error) {
await request.abort();
}
};
// For reassigning proxy of page
const removeRequestListener = (page, listenerName) => {
const eventName = "request";
const listeners = page.eventsMap.get(eventName);
if (listeners) {
const i = listeners.findIndex((listener) => {
return listener.name === listenerName
});
listeners.splice(i, 1);
if (!listeners.length) {
page.eventsMap.delete(eventName);
}
}
};
const useProxyPer = {
// Call this if request object passed
HTTPRequest: async (request, data) => {
let proxy, overrides;
// Separate proxy and overrides
if (type(data) === "object") {
if (Object.keys(data).length !== 0) {
proxy = data.proxy;
delete data.proxy;
overrides = data;
}
} else {proxy = data}
// Skip request if proxy omitted
if (proxy) {await requestHandler(request, proxy, overrides)}
else {request.continue(overrides)}
},
// Call this if page object passed
CDPPage: async (page, proxy) => {
await page.setRequestInterception(true);
const listener = "$ppp_requestListener";
removeRequestListener(page, listener);
const f = {[listener]: async (request) => {
await requestHandler(request, proxy);
}};
if (proxy) {page.on("request", f[listener])}
else {await page.setRequestInterception(false)}
}
}
// Main function
const useProxy = async (target, data) => {
useProxyPer[target.constructor.name](target, data);
};
module.exports = useProxy;