Geographic routing and load balancing with Cloudflare workers

recipe-exchange

#1

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));
}

#2

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