Is it possible to use a worker to enable multiple origins for custom domains (Cloudflare SaaS) without enterprise

I’ve never worked with Cloudflare workers before, and i’m wondering if a worker example is applicable in a case for Cloudflare for SaaS.

I do not have an enterprise account, but i wish to route traffic from certain SaaS custom domains to one origin and certain to another origin (during a move/upgrade). By default this is not possible since multiple fallback domains requires an enterprise account.

But the documentation states that i can use a worker as the origin. Could I then use a worker to route the traffic from one domain to the other origin without the client seeing it? Or is that outside the scope of a worker? Will this cause any noticable performance issues if possible?

I was looking at this example:

Kind

If anyone is interested it worked fine.

The Cloudflare for SaaS custom domains has a worker origin that acts as a reverse proxy and depending on requested host redirects to different origins. Since one of my origins were an azure app service i had to make sure to add the X-Forwarded-Host header so that the solution got it correctly.

Kind regards
Martin

Could you provide a code sample of how you added the X-Forwarded-Host header in the worker? Trying to accomplish basically the same thing but running into difficulty with getting the header added.

Hiya,
Sure thing, I remember I initially had an issue with it and I think it was related to cloning, maybe I didn’t clone the request before adding headers which caused it to not work until i did, I didn’t realise that I couldn’t change the original request.

Then in the azure app you need to see to it that it uses the forwarded headers, in my case it is a .NET app and then i use UseForwardedHeaders Middleware (code snipped below worker, which also forwards the protocol).

Worker code example:

addEventListener("fetch", (event) => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {

  const ORIGINS = {
    'examplecloudflarerouteddomain.com': 'x.azurewebsites.net',
    'examplecloudflarerouteddomain2.com': 'y.azurewebsites.net',


  const url = new URL(request.url);

  if (url.hostname in ORIGINS) {
    
    // Clone request so it isn't immutable
    const newRequest = new Request(request);
    newRequest.headers.append('X-Forwarded-Host', url.hostname);

    // Get target for new request.
    let target = ORIGINS[url.hostname];
    url.hostname = target;

    const response = await fetch(url.toString(), newRequest);

    return response;
  }

  // Otherwise, process request as normal
  return await fetch(request);
};
 app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost
            });
1 Like

I just realised that’s the part with Azure only, in the production case I have two separate lists of domains, the one from the example on azure, and then another one that has targets of proxy domains on cloudflare, that in turn points older servers with IIS on windows that we were migrating from.
If the domains were on that list, then i resolve it differently and don’t add the forwarded header. Then at the time of the moved/upgrade/migration, we switched lists and which made it a seamless migration.

Code snippet (if-statement below the other one)

if (url.hostname in LEGACY_ORIGINS) {
    let target = LEGACY_ORIGINS[url.hostname];
    return await fetch(request, { cf: { resolveOverride: target } });
  }
1 Like

Thank you! This is working.