Proxy pass with Cloudflare workers
This is sample POC for the problem below.
Problem
For a website,
- if http:// and/or www is used, it should be redirected to
https://example.com
- for /blog, worker should proxy pass to
https://blog.example.com
- for /pricing, proxy pass to
https://pricing.example.com
Proxy pass: It means that request is internally routed to a different server or a website but client will see it as coming from same website. i.e. client won't see any url changes.
Solution with cloudflare worker
For the sake of this example, I'm using innodollar.com
Here are the DNS records: Make sure we've a DNS record for www as CNAME, and proxy is enabled.
Next up, enable the flag of "Always use https" under SSL/TLS, Edge Certificates tab.
Let's add a page rule to remove "www"
Notice * and $1 They're important to keep the requests intact while changing the root url.
Now, let's handle special cases of /blog and /pricing. Since we don't want clients to notice we're loading a different website, we've to make use of workers instead of forwarding rules.
Let's create a worker:
Briefly, the worker code below accepts /blog and /pricing urls and directs them to acsrujan.net/blog
and example.com/pricing
respectively.
var host = 'https://innodollar.com/'
addEventListener('fetch', event => {
var url = new URL(event.request.url);
if (url.pathname.startsWith('/pricing')) {
proxyExample(event.request, url, event)
} else if (url.pathname.startsWith('/blog')) {
proxyAcsrujan(event.request, url, event)
} else {
console.log("something unhandled")
}
})
async function proxyExample(request, url, event) {
let hostUrl = host
const originUrl = url.toString().replace(
hostUrl,
'https://example.com/');
event.respondWith(fetch(originUrl));
}
async function proxyAcsrujan(request, url, event) {
const originUrl = url.toString().replace(
host,
'https://acsrujan.net/');
event.respondWith(fetch(originUrl));
}
Let's add the above worker using Manage workers
tab below. Once done, we come back to this page to add routes on which worker is to be triggered, as shown. Notice the * in both routes
Let's test
In order to test, we can quickly do a curl request and find out if it all worked out.
Ex (output redacted for brevity):
curl -i http://www.innodollar.com/blog
HTTP/1.1 301 Moved Permanently
Date: Sat, 10 Oct 2020 19:26:38 GMT
Location: https://innodollar.com/blog
Expected behaviour:
http://www.innodollar.com/
and https://www.innodollar.com/
should be redirected to https://innodollar.com
/blog
and /pricing
in any of the above domains should also go to https://innodollar.com/blog
and https://innodollar.com/pricing
Benefits:
And now we've cloudflare workers for proxy pass. The benefit of using worker here, is it is invoked only when users visit specified routes, unlike traditional nginx server which will be hit for every request.
P.S.: Drop me a message on twitter @acsrujan or [email protected] for any queries. :)