Clean URLs with Lighttpd
For those who have stepped up a notch in performance and moved from Apache to Lighttpd, you need to fix you clean URLs. There are two ways to do so:
Using url rewrites
First you can use the following configuration for Lighty's mod_rewrite module:
url.rewrite-final = (
"^/system/test/(.*)$" => "/index.php?q=system/test/$1",
"^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
"^/([^.?]*)$" => "/index.php?q=$1",
"^/rss.xml" => "/index.php?q=rss.xml"
)The first line ensures that Drupal's clean URL check (when saving Settings) succeeds (Drupal makes an HTTP request for a path of the form /system/test/yLgnwqqUu5cWnvPi4Hrz.png). It's a special case that must be handled separately (read on for the reason).
The two following lines let Drupal handle any URL that doesn't contain a dot. This is significant because we can assume, fairly confidently, that addresses like /node/add are Drupal URLs, but addresses such as /themes/bluemarine/style.css are physical files. So the above configuration will work for all cases where this assumption holds true; if there are exceptions to the rule, they can be manually added to the rewrite configuration.
The last line handles the important exception of rss.xml, a Drupal URL that contains a dot.
See also the related discussion at http://drupal.org/node/20766
Using mod magnet
Second you can use lighty's mod magnet module together with a simple lua scripts. Have a look at the tutorials
http://realize.be/drupal-lighttpd-clean-urls-made-easy or
http://more.zites.net/lighttpd_and_drupal_clean_urls_flexible
This way has the advantage that there are no problems with dots.

Addition of search-related rewrite
I use the following rule in my lighttpd config:
url.rewrite-once = (
"^/system/test/(.*)$" => "/index.php?q=system/test/$1",
"^/search/node/(.*)$" => "/index.php?q=search/node/$1",
"^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
"^/([^.?]*)$" => "/index.php?q=$1"
)
lighttpd config
Bear in mind that you can't necessarily just cut and paste the examples. I'm running lighty as my local dev server for several sites on a windows machine and file downloads are set to private. The local path for the server is c:/lighttpd/ and each site is c:/lighttpd/sitename-here/htdocs/. I used the following config:
url.rewrite-final = ("^/sitename-here/htdocs/system/test/(.*)$" => "/sitename-here/htdocs/index.php?q=system/test/$1",
"^/sitename-here/htdocs/([^.?]*)\?(.*)$" => "/sitename-here/htdocs/index.php?q=$1&$2",
"^/sitename-here/htdocs/([^.?]*)$" => "/sitename-here/htdocs/index.php?q=$1",
"^/sitename-here/htdocs/system/files/(.*)$" => "/sitename-here/htdocs/index.php?q=system/files/$1",
"^/sitename-here/htdocs/search/node/(.*)$" => "/sitename-here/htdocs/index.php?q=search/node/$1"
)
New version offers less hacky approach
Since lighttpd 1.4.12 and mod_magnet it has been possible to implement this in a more sophisticated manner (i.e. so dots in a non-file URL won't break it). Full details to follow when I've gone through it.
Docs here: http://trac.lighttpd.net/trac/wiki/Docs%3AModMagnet#complex-rewrites
This is how to do it
In lighttpd.conf:
magnet.attract-physical-path-to = ( "/etc/lighttpd/rewrite_drupal.lua" )
(Also, make sure mod_magnet appears and is not commented out in the modules list).
/etc/lighttpd/rewrite_drupal.lua:
attr = lighty.stat(lighty.env["physical.path"])
if (not attr) then
lighty.env["uri.query"] = "q=" .. lighty.env["uri.path"]
lighty.env["uri.path"] = "/index.php"
lighty.env["physical.rel-path"] = lighty.env["uri.path"]
lighty.env["physical.path"] = lighty.env["physical.doc-root"] .. lighty.env["physical.rel-path"]
end
I have rewrite_drupal.lua owned by root and chmod 755.
You need lighttpd >= 4.1.12, configured --with-lua. Debian users, this means you need to be running Etch (currently testing) with lighttpd-mod-magnet installed.
Where'd you get lighty.stat
Where'd you get lighty.stat from? Is that something you pulled in from LuaFileSystem?
EDIT: Ah, I see, it's supposed to be part of mod_magnet since 1.4.13. Except it isn't in the Ubuntu 1.4.13 mod_magnet package for some reason...
EDIT2: For anyone else coming along, the default Edgy Ubuntu 1.4.13 package for lighttpd is actually only RC13, so I guess that's why lighty.stat isn't in there. The newer packages (full 1.4.13 release) work fine.
mod_magnet script and pagers?
Hi - currently playing with mod_magnet and your lua code (cheers!) - seem to be experiencing problems with pagers, eg:
http://example.com/node?page=2
(which is perhaps expanding to http://example.com/?q=node?page=2 instead of http://example.com/?q=node&page=2). Any ideas?
---
paul byrne
paul.leafish.co.uk | www.leafish.co.uk
It would be a problem if there is another query string already
more safe way to rewrite url will look like this:
attr = lighty.stat(lighty.env["physical.path"])
-- we couldn't stat() the file so we need to rewrite
if (not attr) then
-- physical path should be a Drupal's main index.php
lighty.env["physical.path"] = lighty.env["physical.doc-root"] .."index.php"
-- if there is another query string already, prepend it with ours
if(lighty.env["uri.query"]) then
lighty.env["uri.query"]="q="..lighty.env["physical.rel-path"].."&"..lighty.env["uri.query"]
else
-- initial query string was empty, we generate our own
lighty.env["uri.query"]="q="..lighty.env["physical.rel-path"]
end
end
/Michael
mod-magnet on ubuntu
If you are running Ubuntu Feisty, the mod-magnet is a separate package: lighttpd-mod-magnet.
I followed the instructions at http://nordisch.org/2007/2/6/drupal-on-lighttpd-with-clean-urls
Worked like a charm, even on virtual hosts.
Hope this helps someone with this.
Zanlus
I vouch
The linked configuration works great. Unfortunately, it only works if drupal is in the webroot and not a subdirectory. It does work great though.
Simpler url rule that works with dots
For setups with drupal in subdirs:
url.rewrite = ( "^/([^/]*)/(?!(misc|theme|module|site))([^?]*)\??(.*)$" => "/$1/index.php?q=$3&$4" )
For drupal in the webroot (untested, but should work):
url.rewrite = ( "^/(?!(misc|theme|module|site))([^?]*)\??(.*)$" => "/index.php?q=$2&$3" )
It guesses the static files (images, css, js, uploaded files[usually in the site subdir]) by not matching on the subdirectories were these are usually located (rather than by skipping paths with a dot. It works with appended query strings (e.g. destinations for redirects and pager links).
I've described a flexible
I've described a flexible way to support clean-URLs by using the lua-script. So there also no troubles with dots :)
http://more.zites.net/lighttpd_and_drupal_clean_urls_flexible
Woohoo!
Thanks fago, this is the only lua script that worked for me right away, no modifications.
Ignore this post
Using the mod-rewrite,
With dots and @s it will display 404 error.
Edit. @s works too, pardon me.