somratpro commited on
Commit
0c73284
·
1 Parent(s): 91a84e2

fix: improve undici dispatcher proxying by resolving origin from instance context and supporting diverse header formats

Browse files
Files changed (1) hide show
  1. 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
- const origin = options.origin ? String(options.origin) : "";
 
 
 
 
 
 
230
  let hostname = "";
231
  try {
232
- hostname = new URL(origin).hostname;
233
  } catch(e) {
234
- hostname = origin.split(':')[0];
235
  }
236
- if (shouldProxyHost(hostname)) {
237
- if (DEBUG) log(`[cloudflare-proxy] Redirecting undici dispatch: ${hostname}${options.path} -> ${proxy.hostname}`);
238
- if (Array.isArray(options.headers)) {
239
- options.headers.push("x-target-host", hostname);
240
- if (PROXY_SHARED_SECRET) options.headers.push("x-proxy-key", PROXY_SHARED_SECRET);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  } else {
242
- options.headers = options.headers || {};
243
- options.headers["x-target-host"] = hostname;
244
- if (PROXY_SHARED_SECRET) options.headers["x-proxy-key"] = PROXY_SHARED_SECRET;
 
 
 
 
 
 
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
  };