aripbae commited on
Commit
ff235bf
·
verified ·
1 Parent(s): a07bbe3

Create index.js

Browse files
Files changed (1) hide show
  1. index.js +146 -0
index.js ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const {addExtra} = require('puppeteer-extra');
2
+ const StealthPlugin = require('puppeteer-extra-plugin-stealth');
3
+ const rebrowserPuppeteer = require('rebrowser-puppeteer');
4
+
5
+ const puppeteer = addExtra(rebrowserPuppeteer);
6
+ puppeteer.use(StealthPlugin());
7
+ const Koa = require('koa');
8
+ const bodyParser = require('koa-bodyparser');
9
+ const app = new Koa();
10
+ app.use(bodyParser());
11
+ const jsesc = require('jsesc');
12
+
13
+ const requestHeadersToRemove = [
14
+ "host", "user-agent", "accept-encoding", "content-length",
15
+ "forwarded", "x-forwarded-proto", "x-forwarded-for", "x-cloud-trace-context"
16
+ ];
17
+ const responseHeadersToRemove = ["Accept-Ranges", "Content-Length", "Keep-Alive", "Connection", "content-encoding", "set-cookie"];
18
+
19
+ (async () => {
20
+ let options = {
21
+ headless: "new",
22
+ args: [
23
+ '--no-sandbox',
24
+ '--disable-setuid-sandbox',
25
+ '--disable-blink-features=AutomationControlled'
26
+ ],
27
+ ignoreDefaultArgs: [
28
+ '--enable-automation',
29
+ '--disable-popup-blocking'
30
+ ]
31
+ };
32
+ if (process.env.PUPPETEER_SKIP_CHROMIUM_DOWNLOAD)
33
+ options.executablePath = '/usr/bin/chromium-browser';
34
+ if (process.env.PUPPETEER_HEADFUL)
35
+ options.headless = false;
36
+ if (process.env.PUPPETEER_USERDATADIR)
37
+ options.userDataDir = process.env.PUPPETEER_USERDATADIR;
38
+ if (process.env.PUPPETEER_PROXY)
39
+ options.args.push(`--proxy-server=${process.env.PUPPETEER_PROXY}`);
40
+ const browser = await puppeteer.launch(options);
41
+ app.use(async ctx => {
42
+ if (ctx.query.url) {
43
+ const url = decodeURIComponent(ctx.url.replace("/?url=", ""));
44
+ if (process.env.DEBUG) {
45
+ console.log(`[DEBUG] URL: ${url}`);
46
+ }
47
+ let responseBody;
48
+ let responseData;
49
+ let responseHeaders;
50
+ const page = await browser.newPage();
51
+
52
+ await page.removeAllListeners('request');
53
+ await page.setRequestInterception(true);
54
+ let requestHeaders = ctx.headers;
55
+ requestHeadersToRemove.forEach(header => {
56
+ delete requestHeaders[header];
57
+ });
58
+ page.on('request', (request) => {
59
+ requestHeaders = Object.assign({}, request.headers(), requestHeaders);
60
+ if (process.env.DEBUG) {
61
+ console.log(`[DEBUG] requested headers: \n${JSON.stringify(requestHeaders)}`);
62
+ }
63
+ if (ctx.method == "POST") {
64
+ request.continue({
65
+ headers: requestHeaders,
66
+ 'method': 'POST',
67
+ 'postData': ctx.request.rawBody
68
+ });
69
+ } else {
70
+ request.continue({ headers: requestHeaders });
71
+ }
72
+ });
73
+
74
+ const client = await page.target().createCDPSession();
75
+ await client.send('Network.setRequestInterception', {
76
+ patterns: [{
77
+ urlPattern: '*',
78
+ resourceType: 'Document',
79
+ interceptionStage: 'HeadersReceived'
80
+ }],
81
+ });
82
+
83
+ await client.on('Network.requestIntercepted', async e => {
84
+ let obj = { interceptionId: e.interceptionId };
85
+ if (e.isDownload) {
86
+ await client.send('Network.getResponseBodyForInterception', {
87
+ interceptionId: e.interceptionId
88
+ }).then((result) => {
89
+ if (result.base64Encoded) {
90
+ responseData = Buffer.from(result.body, 'base64');
91
+ }
92
+ });
93
+ obj['errorReason'] = 'BlockedByClient';
94
+ responseHeaders = e.responseHeaders;
95
+ }
96
+ await client.send('Network.continueInterceptedRequest', obj);
97
+ if (e.isDownload)
98
+ await page.close();
99
+ });
100
+ try {
101
+ let response;
102
+ let tryCount = 0;
103
+ response = await page.goto(url, { timeout: 30000, waitUntil: 'domcontentloaded' });
104
+ ctx.status = response.status();
105
+ responseBody = await response.text();
106
+ responseData = await response.buffer();
107
+ while (responseBody.includes(process.env.CHALLENGE_MATCH || "challenge-platform") && tryCount <= 10) {
108
+ newResponse = await page.waitForNavigation({ timeout: 30000, waitUntil: 'domcontentloaded' });
109
+ if (newResponse) response = newResponse;
110
+ responseBody = await response.text();
111
+ responseData = await response.buffer();
112
+ tryCount++;
113
+ }
114
+ responseHeaders = await response.headers();
115
+ const cookies = await page.cookies();
116
+ if (cookies)
117
+ cookies.forEach(cookie => {
118
+ const { name, value, secure, expires, domain, ...options } = cookie;
119
+ ctx.cookies.set(cookie.name, cookie.value, options);
120
+ });
121
+ } catch (error) {
122
+ if (!error.toString().includes("ERR_BLOCKED_BY_CLIENT")) {
123
+ ctx.status = 500;
124
+ ctx.body = error;
125
+ }
126
+ }
127
+
128
+ await page.close();
129
+ if (responseHeaders) {
130
+ responseHeadersToRemove.forEach(header => delete responseHeaders[header]);
131
+ Object.keys(responseHeaders).forEach(header => ctx.set(header, jsesc(responseHeaders[header])));
132
+ }
133
+ if (process.env.DEBUG) {
134
+ console.log(`[DEBUG] response headers: \n${JSON.stringify(responseHeaders)}`);
135
+ }
136
+ if (process.env.DEBUG_BODY) {
137
+ console.log(`[DEBUG] body: \n${responseData}`);
138
+ }
139
+ ctx.body = responseData;
140
+ }
141
+ else {
142
+ ctx.body = "Please specify the URL in the 'url' query string.";
143
+ }
144
+ });
145
+ app.listen(process.env.PORT || 3000, process.env.ADDRESS || "::");
146
+ })();