Workers a good solution to adding GeoCookies?

Hey everyone! I've got a client that's asking us to add cookies that identify geolocation before it hits the server (otherwise, if the server sets it, it won't be available on initial request). Is something like this a good use case for workers? I've seen a lot of examples where workers provide routes that can be used to invoke the worker script. But can it act at the request layer to modify it before it hits the host? Thanks!!
10 Replies
Hello, I’m Allie!
Does it need to be a cookie specifically, or just a header?
Saeven
SaevenOP10mo ago
Yeah I had the same want. I do see that CF provides headers, and I could print the headers into script through a server-side transform - but the client wants this in a cookie (which would have to be set preflight) Is this something Workers can do, or am I barking up the wrong tree?
Hello, I’m Allie!
Definitely, but I'm checking rn to see if you could do it in a Rule. If so, then it would be free
Saeven
SaevenOP10mo ago
oh interesting appreciate the gesture!
Hello, I’m Allie!
Do Header rules automatically get coallesced?
Saeven
SaevenOP10mo ago
I agree! Just one of those crazy large-corp shenanigans. sounds like a good idea - I've never authored a Worker. Have only really used CF for WAF and basic network tasks. The worker example code I've found seems to serve pages outright. Are there any that deal with setting cookies whilst still serving the request from the host?
Hello, I’m Allie!
If it is toward the origin, wouldn’t that also work as a Request Header Transform?
Saeven
SaevenOP10mo ago
Makes sense - thank you so much
Hello, I’m Allie!
Now you got me curious, wondering if you can simplify it with a concat... Wut? Apparently you can't edit the cookie header with Transforms... Like, not even that it might be difficult to format them, just that it fails to deploy because you can't perform a set operation on a cookie header Well, that quickly nuked my hopes Wonder if that is because you could mess with the CF Detection Cookie, or that you might bungle the header entirely... Maybe a warning, instead of a full block... idk
Saeven
SaevenOP10mo ago
Thanks for pointing me in the right direction. I was able to get the data into a cookie like so:
// Fetch the request and pass it through the function
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
});

async function fetchAndApply(request){

let response = await fetch(request);
response = new Response(response.body, response);

// create header in format you like using `request.cf.*` fields - https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties
response.headers.append("Set-Cookie", `llxp_geo_country=${request.cf.country}; path=/; secure; SameSite=None`);
response.headers.append("Set-Cookie", `llxp_geo_region=${request.cf.regionCode}; path=/; secure; SameSite=None`);

// assumes the worker sits in front of the site you're proxying, this fetch will go to the origin
// if it doesn't, you may need to manipulate the URL here
return response;
}
// Fetch the request and pass it through the function
addEventListener('fetch', event => {
event.respondWith(fetchAndApply(event.request))
});

async function fetchAndApply(request){

let response = await fetch(request);
response = new Response(response.body, response);

// create header in format you like using `request.cf.*` fields - https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties
response.headers.append("Set-Cookie", `llxp_geo_country=${request.cf.country}; path=/; secure; SameSite=None`);
response.headers.append("Set-Cookie", `llxp_geo_region=${request.cf.regionCode}; path=/; secure; SameSite=None`);

// assumes the worker sits in front of the site you're proxying, this fetch will go to the origin
// if it doesn't, you may need to manipulate the URL here
return response;
}
Want results from more Discord servers?
Add your server