|
28 | 28 | ];
|
29 | 29 |
|
30 | 30 | function rewriteURL(url) {
|
31 |
| - const oldUrl = url; |
32 | 31 | if (!url) return url;
|
33 |
| - let isStr = typeof url.startsWith === "function"; |
34 |
| - if (!isStr) return url; |
| 32 | + |
| 33 | + // fetch url might be string, url, or request object |
| 34 | + // handle all three by downcasting to string |
| 35 | + const isStr = typeof url === "string"; |
| 36 | + if (!isStr) { |
| 37 | + x = String(url); |
| 38 | + if (x == "[object Request]") { |
| 39 | + url = url.url; |
| 40 | + } else { |
| 41 | + url = String(url); |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + const oldUrl = url; |
35 | 46 |
|
36 | 47 | // don't rewrite special URIs
|
37 | 48 | if (blacklistedSchemes.includes(url)) return url;
|
|
44 | 55 | }
|
45 | 56 |
|
46 | 57 | // don't double rewrite
|
47 |
| - if (url.startsWith(proxyOrigin)) return url; |
| 58 | + if (url.startsWith(`${proxyOrigin}/http://`)) return url; |
| 59 | + if (url.startsWith(`${proxyOrigin}/https://`)) return url; |
48 | 60 | if (url.startsWith(`/${proxyOrigin}`)) return url;
|
49 | 61 | if (url.startsWith(`/${origin}`)) return url;
|
50 | 62 | if (url.startsWith(`/http://`)) return url;
|
|
59 | 71 | url = `/${origin}/${encodeURIComponent(url.substring(2))}`;
|
60 | 72 | } else if (url.startsWith("/")) {
|
61 | 73 | url = `/${origin}/${encodeURIComponent(url.substring(1))}`;
|
| 74 | + } else if ( |
| 75 | + url.startsWith(proxyOrigin) && !url.startsWith(`${proxyOrigin}/http`) |
| 76 | + ) { |
| 77 | + // edge case where client js uses current url host to write an absolute path |
| 78 | + url = "".replace(proxyOrigin, `${proxyOrigin}/${origin}`); |
62 | 79 | } else if (url.startsWith(origin)) {
|
63 | 80 | url = `/${encodeURIComponent(url)}`;
|
64 | 81 | } else if (url.startsWith("http://") || url.startsWith("https://")) {
|
|
68 | 85 | return url;
|
69 | 86 | }
|
70 | 87 |
|
71 |
| - // sometimes anti-bot protections like cloudflare or akamai bot manager check if JS is hooked |
| 88 | + /* |
| 89 | + // sometimes anti-bot protections like cloudflare or akamai bot manager check if JS is hooked |
| 90 | + function hideMonkeyPatch(objectOrName, method, originalToString) { |
| 91 | + let obj; |
| 92 | + let isGlobalFunction = false; |
| 93 | + |
| 94 | + if (typeof objectOrName === "string") { |
| 95 | + obj = globalThis[objectOrName]; |
| 96 | + isGlobalFunction = (typeof obj === "function") && |
| 97 | + (method === objectOrName); |
| 98 | + } else { |
| 99 | + obj = objectOrName; |
| 100 | + } |
| 101 | + |
| 102 | + if (isGlobalFunction) { |
| 103 | + const originalFunction = obj; |
| 104 | + globalThis[objectOrName] = function(...args) { |
| 105 | + return originalFunction.apply(this, args); |
| 106 | + }; |
| 107 | + globalThis[objectOrName].toString = () => originalToString; |
| 108 | + } else if (obj && typeof obj[method] === "function") { |
| 109 | + const originalMethod = obj[method]; |
| 110 | + obj[method] = function(...args) { |
| 111 | + return originalMethod.apply(this, args); |
| 112 | + }; |
| 113 | + obj[method].toString = () => originalToString; |
| 114 | + } else { |
| 115 | + console.warn( |
| 116 | + `proxychain: cannot hide monkey patch: ${method} is not a function on the provided object.`, |
| 117 | + ); |
| 118 | + } |
| 119 | + } |
| 120 | + */ |
72 | 121 | function hideMonkeyPatch(objectOrName, method, originalToString) {
|
73 |
| - let obj; |
74 |
| - let isGlobalFunction = false; |
75 |
| - |
76 |
| - if (typeof objectOrName === "string") { |
77 |
| - obj = globalThis[objectOrName]; |
78 |
| - isGlobalFunction = (typeof obj === "function") && |
79 |
| - (method === objectOrName); |
80 |
| - } else { |
81 |
| - obj = objectOrName; |
82 |
| - } |
83 |
| - |
84 |
| - if (isGlobalFunction) { |
85 |
| - const originalFunction = obj; |
86 |
| - globalThis[objectOrName] = function(...args) { |
87 |
| - return originalFunction.apply(this, args); |
88 |
| - }; |
89 |
| - globalThis[objectOrName].toString = () => originalToString; |
90 |
| - } else if (obj && typeof obj[method] === "function") { |
91 |
| - const originalMethod = obj[method]; |
92 |
| - obj[method] = function(...args) { |
93 |
| - return originalMethod.apply(this, args); |
94 |
| - }; |
95 |
| - obj[method].toString = () => originalToString; |
96 |
| - } else { |
97 |
| - console.warn( |
98 |
| - `proxychain: cannot hide monkey patch: ${method} is not a function on the provided object.`, |
99 |
| - ); |
100 |
| - } |
| 122 | + return; |
101 | 123 | }
|
102 | 124 |
|
103 | 125 | // monkey patch fetch
|
|
0 commit comments