by mars on 2006-09-26 0 Comments
filed in Work with tags ,

Update 18 May 2007: While this article may still be useful, the original purpose of this prose was to explain how to implement extensionless URL's with lighttpd, which is now updated & improved, no LFS necessary.

URL rewriting is a serious tool for the web developer; a little known world of regular expressions, domain specific languages, HTTP protocol manipulation, and web server mechanics.

I've been using an Apache mod_rewrite sequence that enables extension-less URL's to HTML files at almost every site I've produced over the past five years. This (and many other) Apache-specific mod_rewrite functionality has not been so easy to move to lighttpd, whose mod_rewrite really just does simple regular expression search & replace on URL's.

Until now, as of lighttpd 1.4.12, we finally have mod_magnet, a Lua-language execution environment running in lighttpd's core for lightning-fast, complex URL manipulations. With the LuaFileSystem [lfs] module, it's possible to check for existence of files & directories inside a Lua script.

LuaFileSystem for on OS X

Lua is a bit difficult to get working on OS X, and LuaFileSystem even more so. Follow along to lighttpd URL-rewriting heaven.

Before beginning here, you may want to read my previous article for how to install mod_magnet on OS X.

Install Compat-5.1

Get & unarchive Compat-5.1 (currently r5):
http://luaforge.net/frs/?group_id=82

%  cd compat-5.1r5/
%  sudo mkdir -p /usr/local/share/lua/5.0/
%  sudo mkdir -p /usr/local/lib/lua/5.0/
%  sudo cp compat-5.1.lua /usr/local/share/lua/5.0/
%  sudo cp compat-5.1.h /usr/local/include/

Additional Lua components can be loaded by installing them into /usr/local/share/lua/5.0/; if you install modules elsewhere, you must update the package.path (LUA_PATH) & package.cpath (LUA_CPATH) values so that Lua can find them.

Build LuaFileSystem

Get & unarchive LuaFileSystem (currently 1.2):
http://luaforge.net/frs/?group_id=66

%  cd luafilesystem-1.2/

Using your favorite text editor, revise the 'config' file for your system:

LIB_OPTION= -shared #for Linux
#LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X
  becomes
#LIB_OPTION= -shared #for Linux
LIB_OPTION= -bundle -undefined dynamic_lookup #for MacOS X

COMPAT_DIR= ../compat/src
  becomes
COMPAT_DIR= ../compat-5.1r5
  (set this to where-ever the Compat archive was unpacked)

Then:

%  make
%  sudo make install

Edit lighttpd.conf

Enable mod_setenv (before mod_magnet). Lua's package loader Compat-5.1 must be initialized via a directive place into an environment variable.

server.modules             = ( .. "mod_setenv", "mod_magnet" .. )
setenv.add-environment     = ("LUA_INIT" => "@/usr/local/share/lua/5.0/compat-5.1.lua")

My Favorite Magnet

a.k.a. Why I crave filesystem-aware rewrites.

You can create magnets at the global level of the lighttpd.conf, or inside conditionals:

magnet.attract-physical-path-to = ("/Users/mars/etc/magnet_extensionless_html.lua")

In that file, I have the following Lua code, which enables extension-less URL's to HTML files:

require "lfs"

-- if the requested file doesn't exist, try magically appending ".html"
if (not lfs.attributes(lighty.env["physical.path"])) then
  if (lfs.attributes(lighty.env["physical.path"] .. ".html")) then
  
    lighty.content = { { filename =  lighty.env["physical.path"] .. ".html" } }
    lighty.header["Content-Type"] = "text/html"
    return 200
  end
end

Beware that all mod_magnet scripts run in lighttpd core, and will block all requests while running. So, keep these scripts short & sweet.

Further references for writing magnets in Lua is available:

Comments are welcome. Please let me know if you have success (or failure!) Cheers!

Leave a Reply

Markdown is in effect.



Everything is here.