Geographic routing and load balancing with Cloudflare workers

Full explanation in my Codiva.io blog

Cloudflare adds CF-IPCountry header to all requests once Cloudflare IP Geolocation is enabled.

You can access it using,

var countryCode = req.headers.get('CF-IPCountry');

A simple example. in my case, to route traffic from India and its neighbors to India data center.

const US_HOSTS = [
  0.us.example.com,
  1.us.example.com,
  2.us.example.com
];

const IN_HOSTS = [
  0.in.example.com,
  1.in.example.com,
  2.in.example.com
];

var COUNTRIES_MAP = {
  IN: IN_HOSTS,
  PK: IN_HOSTS,
  BD: IN_HOSTS,
  SL: IN_HOSTS,
  NL: IN_HOSTS
}
addEventListener('fetch', event => {
  var url = new URL(event.request.url);

  var countryCode = req.headers.get('CF-IPCountry');
  var hostnames = US_HOSTS;
  if (COUNTRIES_MAP[countryCode]) {
    hostnames = COUNTRIES_MAP[countryCode];
  }
  // Randomly pick the next host 
  url.hostname = hostnames[getRandomInt(hostnames.length)];
  
  event.respondWith(fetch(event.request));
});

function getRandomInt(max) {
  return Math.floor(Math.random() * Math.floor(max));
}
3 Likes

Nice, @jayaprabhakar!

I have a couple minor bugfixes. :slight_smile:

  1. req.headers.get('CF-IPCountry') should be event.request.headers.get('CF-IPCountry'), since req is undefined.

  2. fetch() needs to be passed the modified URL for this to work, so event.respondWith(fetch(event.request)) should be event.respondWith(fetch(url, event.request)). Without that, fetch() will go to the original URL.

Harris

1 Like

Could this be used to run a worker on many edge nodes in parallel?

Workers will run autonomously at the edge, closer to the client, every time they are called.

Hi Harris.

That array being used for US_HOSTS etc., is node really smart enough to check if the hosts are alive, and use the second one if not? Or is that not the reason for the array?

Thanks.

That isn’t the scope of the code, it’s possible to do (note that you will have either multiple requests to your origin per customer request or multiplied latency), but it would be best if done using the proper load balancing product.

2 Likes