Not long after the passing of Terry Pratchett, revered author of the Discworld series (and many other excellent works!), people everywhere wanted to find ways of memorialising him in their own ways. One great solution was based around adding headers to web requests. The “clacks” sempahore system in Terry Pratchett is a form of low-tech, distributed, packet-switched network much like the internet and so it seemed fair to modify our systems to carry on his legacy.
X-Clacks-Overhead In Brief
In the Discworld series, the inventor of the clacks memorialises his son by putting the message “GNU John Dearheart” as a message. The key symbols are:
- G: send the message on
- N: do not log the message
- U: turn the message around at the end of the line and send it back again
This way his son’s legacy will be captured forever in the stream.
We can modify many standard webservers to contain specialised headers, and so by setting X-Clacks-Overhead
to GNU Terry Pratchett
our web traffic can always have a little trace of that wonderful man.
Amazon Web Services: CloudFront
While the GNU Terry Pratchett site has a bunch of instructions for different web servers, it obviously can’t help you with every platform available. This website is hosted via AWS, where it uses Route53 for DNS, CloudFront as the CDN, and S3 for static asset storage; mostly to avoid paying the steeper rates for an always-on virtual server and also avoiding the concomitant maintenance overhead.
Unfortunately you can’t easily set response headers like some other platforms or web servers, but with the release of Lambda@Edge to all AWS customers you can now intercept CloudFront responses and run a Node.js function that modifies the headers.
Cost
There’s no free tier for Lambda@Edge, unlike normal Lambda functions, but the two factors in cost are the following:
- US$0.60 per 1 million requests
- US$0.00000625125 for every 128MB/second (based on multiples of 100ms)
I mucked around with the pricing calculator and it’s going to cost me US$0.00. If you’re blog is getting 100k hits a month this would still only be an extra US$0.04.
Of course, if something ever went super-viral or you misconfigured a Lambda (so it took too much time/memory) it could result in bill shock. Make sure you set up CloudWatch metrics to notify you if your costs suddenly shoot up, that way you can login and fix it without a huge hit. You can also contact AWS support about sudden billing spikes and they may be able to wipe things.
Instructions
- Go to the Lambda console
- Set your region to “US East (N. Virginia)”
- Lambda@Edge is only available in this region, but it will still be deployed to all CloudFront regions/points-of-presence.
- Select the “Use a blueprint”
- Type “cloudfront” in the search bar and hit Enter
- Select
cloudfront-modify-response-header
- Set a name, both
GNUTerryPratchett
andX-Clacks-Overhead
are allowed and descriptive - Create new (execution) role from AWS policy templates
- Set the role name, similar to the Lambda name is fine
- Use the default, already selected policy template (
Basic Lambda@Edge permissions (for CloudFront trigger)
) - Create function
- Select the Lambda name in the designer chart and you should be able to edit the code below
- Set the following code:
'use strict'; exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; const headers = response.headers; headers['x-clacks-overhead'] = [{ key: 'X-Clacks-Overhead', value: "GNU Terry Pratchett" }]; callback(null, response); }
- Use the default, already selected policy template
- Create function
- Select the “CloudFront” trigger that was automatically created
- Click “Deploy to Lambda@Edge”
- Select your distribution from the list
- Leave “Cache Behaviour” as defaults
- Set the “CloudFront Event” to “Viewer response”
- Select the checkbox to confirm you want to deploy it and click “Deploy”
- Go to your CloudFront distributions page and watch it take ages to deploy.
- Enjoy your sick new HTTP headers
Notes
By default, CloudFront will remove any capitalisation from headers, however under RFC 2616, RFC 7230, and RFC 7540 HTTP headers are supposed to be case insensitive so this should not matter. Unfortunately some misconfigured languages/frameworks (PHP is a known bugbear here) use case-sensitive string comparisons, so be aware!