Tuesday, April 06, 2010
Write Apache modules quickly in Lua
I really like mod_lua
, even in its alpha state. In less
than five minutes I had a webpage that would display a different quote each
time it was referenced. I was able to modify the Lua based qotd, changing:
QUOTESFILE = "/home/spc/quotes/quotes.txt" quotes = {} do local eoln = "\r\n" local f = io.open(QUOTESFILE,"r") local s = "" for line in f:lines() do if line == "" then -- each quote is separated by a blank link if #s < 512 then table.insert(quotes,s) end s = "" else s = s .. line .. eoln end end f:close() end math.randomseek(os.time()) function main(socket) socket:write(quotes[math.random(#quotes)]) end
to
QUOTESFILE = "/home/spc/quotes/quotes.txt" quotes = {} do local eoln = "\r\n" local f = io.open(QUOTESFILE,"r") local s = "" for line in f:lines() do if line == "" then -- each quote is separated by a blank link if #s < 512 then table.insert(quotes,s) end s = "" else s = s .. line .. eoln end end f:close() end math.randomseek(os.time()) function handler(r) r.content_type = "text/plain" r:puts(quotes[math.random(#quotes)]) end
(you can see, it didn't take much), and adding
LuaMapHandler /quote.html /home/spc/web/lua/lib/quote.lua
to the site configuration (what you don't see is the only other line you
need, LuaRoot
), reload Apache and I now have webpage backed by
Lua.
And from there, it isn't much to add some HTML to the output, but it should be clear that adding Apache modules in Lua isn't that hard.
What did take me by surprise is that there's no real way to do the heavy
initialization just once. That bit of reading in the quotes file? It's
actually done for every request—mod_lua
just compiles the
code and keeps the compiled version cached and for each request, runs the
compiled code. It'd be nice if there was a way to do some persistent
initialization once (a feature I use in the current mod_litbook
),
but as written, mod_lua
doesn't have support for that.
I also haven't see any action on my bug report—not a good sign.
I'm wondering if I might not have to pick up the ball
mod_lua
and run with it …