fix: prevent recursion in transparent proxy
Browse files- dns-fix.js +13 -1
dns-fix.js
CHANGED
|
@@ -14,6 +14,8 @@ function isBlocked(hostname) {
|
|
| 14 |
const _origHttpRequest = http.request;
|
| 15 |
const _origHttpsRequest = https.request;
|
| 16 |
|
|
|
|
|
|
|
| 17 |
function transparentProxyRequest(protocol, origFn, ...args) {
|
| 18 |
let options = args[0];
|
| 19 |
let callback = args[1];
|
|
@@ -31,6 +33,11 @@ function transparentProxyRequest(protocol, origFn, ...args) {
|
|
| 31 |
options = { ...options };
|
| 32 |
}
|
| 33 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
if (typeof callback !== "function" && typeof args[2] === "function") {
|
| 35 |
callback = args[2];
|
| 36 |
}
|
|
@@ -57,6 +64,7 @@ function transparentProxyRequest(protocol, origFn, ...args) {
|
|
| 57 |
|
| 58 |
reqStream.on("finish", async () => {
|
| 59 |
try {
|
|
|
|
| 60 |
const fetchRes = await fetch(requestUrl, {
|
| 61 |
method: options.method || "GET",
|
| 62 |
headers: requestHeaders,
|
|
@@ -64,7 +72,7 @@ function transparentProxyRequest(protocol, origFn, ...args) {
|
|
| 64 |
redirect: "manual",
|
| 65 |
});
|
| 66 |
|
| 67 |
-
//
|
| 68 |
resStream.statusCode = fetchRes.status;
|
| 69 |
resStream.statusMessage = fetchRes.statusText;
|
| 70 |
resStream.headers = Object.fromEntries(fetchRes.headers.entries());
|
|
@@ -117,12 +125,16 @@ https.request = function (...args) {
|
|
| 117 |
|
| 118 |
// Also patch http.get and https.get as they often bypass request
|
| 119 |
http.get = function (...args) {
|
|
|
|
|
|
|
| 120 |
const req = http.request(...args);
|
| 121 |
req.end();
|
| 122 |
return req;
|
| 123 |
};
|
| 124 |
|
| 125 |
https.get = function (...args) {
|
|
|
|
|
|
|
| 126 |
const req = https.request(...args);
|
| 127 |
req.end();
|
| 128 |
return req;
|
|
|
|
| 14 |
const _origHttpRequest = http.request;
|
| 15 |
const _origHttpsRequest = https.request;
|
| 16 |
|
| 17 |
+
const IN_PROXY = Symbol("IN_PROXY");
|
| 18 |
+
|
| 19 |
function transparentProxyRequest(protocol, origFn, ...args) {
|
| 20 |
let options = args[0];
|
| 21 |
let callback = args[1];
|
|
|
|
| 33 |
options = { ...options };
|
| 34 |
}
|
| 35 |
|
| 36 |
+
// RECURSION GUARD
|
| 37 |
+
if (options[IN_PROXY]) {
|
| 38 |
+
return origFn.apply(this, args);
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
if (typeof callback !== "function" && typeof args[2] === "function") {
|
| 42 |
callback = args[2];
|
| 43 |
}
|
|
|
|
| 64 |
|
| 65 |
reqStream.on("finish", async () => {
|
| 66 |
try {
|
| 67 |
+
// Ensure fetch itself doesn't trigger our monkey-patches (if undici uses them)
|
| 68 |
const fetchRes = await fetch(requestUrl, {
|
| 69 |
method: options.method || "GET",
|
| 70 |
headers: requestHeaders,
|
|
|
|
| 72 |
redirect: "manual",
|
| 73 |
});
|
| 74 |
|
| 75 |
+
// ... existing logic ...
|
| 76 |
resStream.statusCode = fetchRes.status;
|
| 77 |
resStream.statusMessage = fetchRes.statusText;
|
| 78 |
resStream.headers = Object.fromEntries(fetchRes.headers.entries());
|
|
|
|
| 125 |
|
| 126 |
// Also patch http.get and https.get as they often bypass request
|
| 127 |
http.get = function (...args) {
|
| 128 |
+
const options = typeof args[0] === 'string' ? new URL(args[0]) : args[0];
|
| 129 |
+
if (options) options[IN_PROXY] = true;
|
| 130 |
const req = http.request(...args);
|
| 131 |
req.end();
|
| 132 |
return req;
|
| 133 |
};
|
| 134 |
|
| 135 |
https.get = function (...args) {
|
| 136 |
+
const options = typeof args[0] === 'string' ? new URL(args[0]) : args[0];
|
| 137 |
+
if (options) options[IN_PROXY] = true;
|
| 138 |
const req = https.request(...args);
|
| 139 |
req.end();
|
| 140 |
return req;
|