=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- title: Making Better Use of the `Accept` Header date: 2024-03-06 05:51:00 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- A while back, I wrote about a Jekyll plugin I created that cross-compiles all of my blog posts in plaintext [0] (you can see it for yourself, just click the `txt` link at the bottom of this or any other post). It was a fun experiment, and allowed me to not only create a mechanism that ensures my writing can be accessed on just about any browser imaginable now, but also gave me an opportunity to DRY [1] up my phlog [2] code as well. One thing I have been wanting to do for a while, though, was make better use of some HTTP request headers—specifically the `Accept` header—to create a more dynamic and customizable experience (and also, eventually, easter eggs). So now, as of this past weekend, you can request my blog posts in plaintext format by passing the `text/plain` MIME type in the `Accept` header! How did I do it? Surprisingly, it only took a handful of lines of configuration in my Caddyfile: ```caddyfile @text { header Accept text/plain path_regexp html (.*)(\.html)$ } handle @text { @html { path_regexp html (.*)(\.html)$ } rewrite @html {re.html.1} try_files {uri}.txt {uri}.html file_server } ``` So... what exactly is happening here? Basically, I created a Named Matcher [3] called `@text` that looks for two things: 1. An `Accept` header set to `text/plain` 2. A request to an HTML page When these two things are matched, I then created a Handler to respond to matched `@text` requests, which does a few things before responding: 1. First, it strips the `.html` suffix off of the path (for example, turning `/index.html` to just `/index`) 2. Next, it tries to load a corresponding `.txt` file (`/index.txt`) 3. And finally, if that file can't be found, it falls back to the originally requested `.html` file (`/index.html` again) All things considered, it's a pretty simple solution, but here's what it looks like in action with the `Accept` header passed: ``` $ curl -v -H 'Accept: text/plain' http://flower.codes/2024/01/13/four-oh-four.html * Trying 37.16.19.121:80... * Connected to flower.codes (37.16.19.121) port 80 (#0) > GET /2024/01/13/four-oh-four.html HTTP/1.1 > Host: flower.codes > User-Agent: curl/7.82.0 > Accept: text/plain > * Mark bundle as not supporting multiuse < HTTP/1.1 200 OK < accept-ranges: bytes < content-length: 2385 < etag: "s9um4u1u9" < last-modified: Tue, 05 Mar 2024 00:17:18 GMT < server: Fly/e29f4368 (2024-03-04) < date: Tue, 05 Mar 2024 13:00:21 GMT < via: 1.1 fly.io < fly-request-id: 01HR7B6SF7PGEK6PVDZ6SY8QP5-chi < =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- title: Four, Oh, Four... date: 2024-01-13 14:50:00 soundtrack: "You & Me = Forever" by Zak Vortex =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- I did it. I finally broke down and added the _tiniest_ bit of JavaScript to my site. I know, I'm awful, but hear me out. I've been thinking about retro computing a lot again, especially as it pertains to The Internet (capital "T," capital "I," baby), and I've been wanting to add a little more personality (and maybe an easter egg or two) to things. One thing that I _haven't_ yet set up for myself is a kickass 404 page—or... you know... a 404 page at all. I think I designed a simple one a million moons ago, but I never actually configured my web server to serve it up. But I'm nothing if not an expert procrastinator, so I finally jumped into my Caddyfile [0], pointed all its 404 responses to my 404 page, and... was supremely disappointed. The page I had was _boring_. So I dug into the depths of my brainpan and remembered an old glitch effect I used half-a-dozen years ago that felt right at home with my preferred aesthetic. Unfortunately, this meant importing one small JavaScript file and adding a single line of code to activate it. But, in the interest of keeping things tidy, it's only loaded on my error page (alongside a fun deconstruction of a rotary phone, courtesy of our friends at OpenAI), and is all sorts of fun to look at. If you're interested, feel free to head directly to /404.html [1], or just mash your keyboard a bit to get to an actual 404 error on the flower.codes domain. Oh, and in case you were wondering how old browsers deal with this? The answer is twofold: not well, and it doesn't really matter. While the actual `404.html` page can be loaded in older browsers, most of them ignore the `