Spaces:
Running
Running
fix: comprehensive undici patching for telegram connectivity
Browse files- cloudflare-proxy.js +61 -61
cloudflare-proxy.js
CHANGED
|
@@ -192,6 +192,67 @@ if (PROXY_URL) {
|
|
| 192 |
|
| 193 |
const patchUndiciInstance = (exports) => {
|
| 194 |
if (!exports) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 195 |
if (exports.fetch && !exports.fetch._patched) {
|
| 196 |
exports.fetch = async function (input, init) {
|
| 197 |
return globalThis.fetch(input, init);
|
|
@@ -222,67 +283,6 @@ if (PROXY_URL) {
|
|
| 222 |
exports.request._patched = true;
|
| 223 |
if (DEBUG) log("[cloudflare-proxy] Patched undici.request");
|
| 224 |
}
|
| 225 |
-
|
| 226 |
-
if (exports.Dispatcher && exports.Dispatcher.prototype.dispatch && !exports.Dispatcher.prototype.dispatch._patched) {
|
| 227 |
-
const origDispatch = exports.Dispatcher.prototype.dispatch;
|
| 228 |
-
exports.Dispatcher.prototype.dispatch = function(options, handler) {
|
| 229 |
-
// In undici, Pool/Client instances have a .origin property.
|
| 230 |
-
// options.origin might be missing for instance-bound calls.
|
| 231 |
-
let origin = options.origin || this.origin;
|
| 232 |
-
if (origin && typeof origin !== 'string') {
|
| 233 |
-
try { origin = origin.origin || origin.toString(); } catch (e) { origin = ""; }
|
| 234 |
-
}
|
| 235 |
-
|
| 236 |
-
let hostname = "";
|
| 237 |
-
try {
|
| 238 |
-
hostname = new URL(String(origin)).hostname;
|
| 239 |
-
} catch(e) {
|
| 240 |
-
hostname = String(origin || "").split(':')[0];
|
| 241 |
-
}
|
| 242 |
-
|
| 243 |
-
if (hostname && shouldProxyHost(hostname)) {
|
| 244 |
-
if (DEBUG) log(`[cloudflare-proxy] Redirecting undici dispatch: ${hostname}${options.path || ""} -> ${proxy.hostname}`);
|
| 245 |
-
|
| 246 |
-
// Ensure we have headers to modify
|
| 247 |
-
let headers = options.headers;
|
| 248 |
-
const targetHeader = "x-target-host";
|
| 249 |
-
const secretHeader = "x-proxy-key";
|
| 250 |
-
|
| 251 |
-
if (Array.isArray(headers)) {
|
| 252 |
-
// undici internal header array format: [key, value, key, value, ...]
|
| 253 |
-
let foundTarget = false;
|
| 254 |
-
for (let i = 0; i < headers.length; i += 2) {
|
| 255 |
-
if (String(headers[i]).toLowerCase() === targetHeader) {
|
| 256 |
-
foundTarget = true;
|
| 257 |
-
break;
|
| 258 |
-
}
|
| 259 |
-
}
|
| 260 |
-
if (!foundTarget) {
|
| 261 |
-
headers.push(targetHeader, hostname);
|
| 262 |
-
if (PROXY_SHARED_SECRET) headers.push(secretHeader, PROXY_SHARED_SECRET);
|
| 263 |
-
}
|
| 264 |
-
} else {
|
| 265 |
-
// Object or Headers format
|
| 266 |
-
options.headers = headers || {};
|
| 267 |
-
if (options.headers instanceof Map || (typeof options.headers.set === 'function')) {
|
| 268 |
-
options.headers.set(targetHeader, hostname);
|
| 269 |
-
if (PROXY_SHARED_SECRET) options.headers.set(secretHeader, PROXY_SHARED_SECRET);
|
| 270 |
-
} else {
|
| 271 |
-
options.headers[targetHeader] = hostname;
|
| 272 |
-
if (PROXY_SHARED_SECRET) options.headers[secretHeader] = PROXY_SHARED_SECRET;
|
| 273 |
-
}
|
| 274 |
-
}
|
| 275 |
-
|
| 276 |
-
// Redirect the origin to the proxy
|
| 277 |
-
options.origin = `https://${proxy.hostname}`;
|
| 278 |
-
// For Pools/Clients, we might need to override the internal state or just hope the dispatch options take precedence.
|
| 279 |
-
// In most undici versions, options.origin takes precedence in Dispatcher.dispatch.
|
| 280 |
-
}
|
| 281 |
-
return origDispatch.call(this, options, handler);
|
| 282 |
-
};
|
| 283 |
-
exports.Dispatcher.prototype.dispatch._patched = true;
|
| 284 |
-
if (DEBUG) log("[cloudflare-proxy] Patched undici.Dispatcher.prototype.dispatch");
|
| 285 |
-
}
|
| 286 |
};
|
| 287 |
|
| 288 |
// Patch already loaded undici instances
|
|
|
|
| 192 |
|
| 193 |
const patchUndiciInstance = (exports) => {
|
| 194 |
if (!exports) return;
|
| 195 |
+
|
| 196 |
+
const patchDispatch = (proto, name) => {
|
| 197 |
+
if (proto && proto.dispatch && !proto.dispatch._patched) {
|
| 198 |
+
const origDispatch = proto.dispatch;
|
| 199 |
+
proto.dispatch = function(options, handler) {
|
| 200 |
+
let origin = options.origin || this.origin;
|
| 201 |
+
if (origin && typeof origin !== 'string') {
|
| 202 |
+
try { origin = origin.origin || origin.toString(); } catch (e) { origin = ""; }
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
let hostname = "";
|
| 206 |
+
try {
|
| 207 |
+
hostname = new URL(String(origin)).hostname;
|
| 208 |
+
} catch(e) {
|
| 209 |
+
hostname = String(origin || "").split(':')[0];
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
if (hostname && shouldProxyHost(hostname)) {
|
| 213 |
+
if (DEBUG) log(`[cloudflare-proxy] Redirecting undici ${name}.dispatch: ${hostname}${options.path || ""} -> ${proxy.hostname}`);
|
| 214 |
+
|
| 215 |
+
let headers = options.headers;
|
| 216 |
+
const targetHeader = "x-target-host";
|
| 217 |
+
const secretHeader = "x-proxy-key";
|
| 218 |
+
|
| 219 |
+
if (Array.isArray(headers)) {
|
| 220 |
+
let foundTarget = false;
|
| 221 |
+
for (let i = 0; i < headers.length; i += 2) {
|
| 222 |
+
if (String(headers[i]).toLowerCase() === targetHeader) {
|
| 223 |
+
foundTarget = true;
|
| 224 |
+
break;
|
| 225 |
+
}
|
| 226 |
+
}
|
| 227 |
+
if (!foundTarget) {
|
| 228 |
+
headers.push(targetHeader, hostname);
|
| 229 |
+
if (PROXY_SHARED_SECRET) headers.push(secretHeader, PROXY_SHARED_SECRET);
|
| 230 |
+
}
|
| 231 |
+
} else {
|
| 232 |
+
options.headers = headers || {};
|
| 233 |
+
if (options.headers instanceof Map || (typeof options.headers.set === 'function')) {
|
| 234 |
+
options.headers.set(targetHeader, hostname);
|
| 235 |
+
if (PROXY_SHARED_SECRET) options.headers.set(secretHeader, PROXY_SHARED_SECRET);
|
| 236 |
+
} else {
|
| 237 |
+
options.headers[targetHeader] = hostname;
|
| 238 |
+
if (PROXY_SHARED_SECRET) options.headers[secretHeader] = PROXY_SHARED_SECRET;
|
| 239 |
+
}
|
| 240 |
+
}
|
| 241 |
+
options.origin = `https://${proxy.hostname}`;
|
| 242 |
+
}
|
| 243 |
+
return origDispatch.call(this, options, handler);
|
| 244 |
+
};
|
| 245 |
+
proto.dispatch._patched = true;
|
| 246 |
+
if (DEBUG) log(`[cloudflare-proxy] Patched undici ${name}.prototype.dispatch`);
|
| 247 |
+
}
|
| 248 |
+
};
|
| 249 |
+
|
| 250 |
+
patchDispatch(exports.Dispatcher?.prototype, "Dispatcher");
|
| 251 |
+
patchDispatch(exports.Client?.prototype, "Client");
|
| 252 |
+
patchDispatch(exports.Pool?.prototype, "Pool");
|
| 253 |
+
patchDispatch(exports.Agent?.prototype, "Agent");
|
| 254 |
+
patchDispatch(exports.ProxyAgent?.prototype, "ProxyAgent");
|
| 255 |
+
|
| 256 |
if (exports.fetch && !exports.fetch._patched) {
|
| 257 |
exports.fetch = async function (input, init) {
|
| 258 |
return globalThis.fetch(input, init);
|
|
|
|
| 283 |
exports.request._patched = true;
|
| 284 |
if (DEBUG) log("[cloudflare-proxy] Patched undici.request");
|
| 285 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 286 |
};
|
| 287 |
|
| 288 |
// Patch already loaded undici instances
|