Search code examples
caddycaddyfile

Using caddy to serve a tracking pixel (base64 encoded)


I am trying to setup a very simple beacon (pixel tracking) server. Currently all I want to do is have caddy respond with a 1px transparent gif to every request. The URLs will be logged and then we'll parse out the analytics data we're after. However, I can't get Caddy to serve the gif! It appears as a broken image.

Caddyfile

:2015

header Content-Type "image/gif"
header Content-Encoding "base64"
respond /* 200 {
  body "R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
  close
}

I believe that is the correct encoding for a base64 gif. Tested it with

<body>
  [<img src="http://localhost:2015/foo.gif" />]
 [<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">]

</body>

If you load that up, you'll see the inline one is fine, but, the other is not.

I don't particularly want to have to serve an actual file (or use file_server or anything else), however, if that's the only way then I'll do it.

Any help would be wonderful!

-------------Edited to add---------

After the helpful comment I ended up with this simple caddyfile to serve a 1px image. I placed the pix.gif inside /home/patrick/caddplay/temp/pix.gif and then rewrite all requests to that. Seems to work just fine.

:2015

header Content-Type "image/gif"
handle /* {
    root * /home/patrick/caddplay/temp
    rewrite * /pix.gif
    file_server
}

Solution

  • No* browsers support base64 as a content-encoding value for a response body, as opposed to gzip, deflate and br (Brotli), which are commonplace.

    If you're aiming at the highest possible performance, perhaps this can help you:

    • Caddy should use sendfile, so the kernel can send your static pixel file efficiently. The file might actually be transparently cached in memory by your OS. Try and see if there's actually any overhead from responding with a file as opposed to a static string like you're doing now.
    • I guess you could put the pixel on a tmpfs if you wanted to avoid any seeks on your disk, but I imagine with a SSD (and noted above, caching in memory by the OS) this won't lead to a measurable improvement.
    • There are a lot of Caddy plugins, but I haven't seen one that can decode base64-encoded strings on the fly, but perhaps you could create one yourself?

    * neither popular browsers nor any esoteric UA I know of.