Hugging8N / outbound-proxy-worker.js
somratpro's picture
feat: upgrade to universal outbound proxy with x-target-host header
72ece3f
raw
history blame
2.03 kB
/**
* Cloudflare Worker: Universal Outbound Proxy
*
* Deployment:
* 1. Go to dash.cloudflare.com -> Workers & Pages -> Create Worker.
* 2. Paste this code and deploy.
* 3. Use your worker URL (e.g., https://my-proxy.workers.dev) as OUTBOUND_PROXY_URL.
*
* This worker reads the 'x-target-host' header to determine where to forward the request.
*/
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const targetHost = request.headers.get("x-target-host");
let targetBase = "";
if (targetHost) {
// Use the host provided in the header (preferred)
targetBase = `https://${targetHost}`;
} else {
// Fallback: Guess based on path (legacy support)
if (url.pathname.startsWith("/bot")) {
targetBase = "https://api.telegram.org";
} else if (url.pathname.startsWith("/api/webhooks") || url.pathname.startsWith("/api/v")) {
targetBase = "https://discord.com";
} else {
return new Response("Invalid request. 'x-target-host' header missing and target not recognized via path.", { status: 400 });
}
}
const targetUrl = targetBase + url.pathname + url.search;
// Copy headers and remove internal/Cloudflare-specific ones
const headers = new Headers(request.headers);
headers.delete("cf-connecting-ip");
headers.delete("cf-ray");
headers.delete("cf-visitor");
headers.delete("x-real-ip");
headers.delete("x-target-host"); // Don't leak this to the target
const modifiedRequest = new Request(targetUrl, {
method: request.method,
headers: headers,
body: request.body,
redirect: "follow",
});
try {
const response = await fetch(modifiedRequest);
// Special handling for Discord/Telegram which might return 403 on some CF IPs
// If needed, you can add retry logic here.
return response;
} catch (e) {
return new Response(`Proxy Error: ${e.message}`, { status: 502 });
}
},
};