lighttpd, magnet, and more! posted Thu, 10 Dec 2009 17:44:26 UTC

Today I was asked to deal with some broken e-mail marketing links we’ve been publishing for awhile now. We previously handled these misprinted URI’s via PHP, but since we’ve moved all of our static content to lighttpd servers recently, this wasn’t an option.

The solution it turns out was fairly straight forward. lighttpd does fortunately allow some amount of arbitrary logic during each request using LUA as part of mod_magnet. So after installing lighttpd-mod-magnet on my Debian servers and enabling it, I ended up adding the following to my lighttpd configuration:


$HTTP["url"] =~ "^/logos" {
        magnet.attract-physical-path-to = ( "/etc/lighttpd/strtolower.lua" )
}

and the following LUA script:

-- helper function to check for existence of a file
function file_exists(path)
        local attr = lighty.stat(path)
        if (attr) then
                return true
        else
                return false
        end
end

-- main code block
-- look for requested file first, then all lower case version of the same
if (file_exists(lighty.env["physical.path"])) then
        lighty.content = {{ filename = lighty.env["physical.path"] }}
        return 200
elseif (file_exists(string.lower(lighty.env["physical.path"]))) then
        lighty.content = {{ filename = string.lower(lighty.env["physical.path"]) }}
        return 200
else
        -- top level domains to search through
        local tld = { ".com", ".net", ".info", ".biz", ".ws", ".org", ".us" }
        for i,v in ipairs(tld) do
                local file = lighty.env["physical.path"]
                file = string.sub(file, 1, -5)
                if (file_exists(string.lower(file .. v .. ".gif"))) then
                        lighty.content = {{ filename = string.lower(file .. v .. ".gif") }}
                        return 200
                end
        end
        return 404
end

And that was it! The script checks for the existence of the requested file, and if it fails, it first forces the string to lowercase (since someone in our marketing department felt it would be a good idea to use mixed case URI’s in our marketing publications) and failing that, it will also look for the same file with a few top level domains inserted into the name (again, brilliance by someone in marketing publishing crap with the wrong file names).

Failing all of that, you get a 404. Sorry, we tried.