Spaces:
Running
Running
fix: improve undici dispatcher proxying by resolving origin from instance context and supporting diverse header formats
Browse files- cloudflare-proxy.js +44 -11
cloudflare-proxy.js
CHANGED
|
@@ -226,24 +226,57 @@ if (PROXY_URL) {
|
|
| 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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 230 |
let hostname = "";
|
| 231 |
try {
|
| 232 |
-
hostname = new URL(origin).hostname;
|
| 233 |
} catch(e) {
|
| 234 |
-
hostname = origin.split(':')[0];
|
| 235 |
}
|
| 236 |
-
|
| 237 |
-
|
| 238 |
-
if (
|
| 239 |
-
|
| 240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
} else {
|
| 242 |
-
|
| 243 |
-
options.headers
|
| 244 |
-
if (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 245 |
}
|
|
|
|
|
|
|
| 246 |
options.origin = `https://${proxy.hostname}`;
|
|
|
|
|
|
|
| 247 |
}
|
| 248 |
return origDispatch.call(this, options, handler);
|
| 249 |
};
|
|
|
|
| 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 |
};
|