≡ Menu

Lighttpd Drupal CMS Clean URL ( SEO ) Rules Set Configuration

Drupal is modular framework and content management system (CMS) and works under Lighttpd too. By default, Drupal passes path arguments to itself via its internally generated URLs. This results in URLs that look like the following: “http://www.example.com/?q=node/83.” This can make URLs hard to read and it also stops many search engines, like Google, from indexing the pages with these URLs.

You can tell Drupal to use “clean URLs”, eliminating the “?q=” in internal URLs. Assuming that your site hosted in rootdirectory itself, open your lighttpd.conf file or domain configuration file:
# vi lighttpd.conf
Make sure mod_rewrite is enabled:
server.modules += ( "mod_rewrite" )
Append following configuration directives:

url.rewrite-final = (
  "^/system/test/(.*)$" => "/index.php?q=system/test/$1",
  "^/system/test-clean-url/(.*)$" => "/index.php?q=system/test-clean-url/$1",
  "/rss.xml$" => "/index.php?q=rss.xml",
  "^/search/(.*)$" => "/index.php?q=search/$1",
  "^/([^.?]*)\?(.*)$" => "/index.php?q=$1&$2",
  "^/([^.?]*)$" => "/index.php?q=$1",
# Error 404
server.error-handler-404  = "/index.php"
# stop these 
url.access-deny = ( "~", ".inc", ".engine", ".install", ".module", ".sh", "sql", ".theme", ".tpl.php", ".xtmpl", "Entries", "Repository", "Root" )

Save and close the file. Restart lighttpd, enter:
# /etc/init.d/lighttpd restart
Feel free to adjust rules as per your setup.

Further readings:

Share this on:

Your support makes a big difference:
I have a small favor to ask. More people are reading the nixCraft. Many of you block advertising which is your right, and advertising revenues are not sufficient to cover my operating costs. So you can see why I need to ask for your help. The nixCraft, takes a lot of my time and hard work to produce. If you use nixCraft, who likes it, helps me with donations:
Become a Supporter →    Make a contribution via Paypal/Bitcoin →   

Don't Miss Any Linux and Unix Tips

Get nixCraft in your inbox. It's free:

{ 4 comments… add one }
  • BlueT July 30, 2008, 8:48 pm

    Don’t forget to enable mod_rewrite, or you’ll face critical problem :-P

  • nixCraft July 31, 2008, 4:11 am


    The post has been updated. Appreciate your post.

  • S. Nilesh August 8, 2008, 6:07 pm

    Vivek, this one is not a good method… exploit drupal internally. Set lighttpd’s 404 handler to /index.php and add the following code in settings.php located in /sites/default/settings.php

    if (strpos($_SERVER['SERVER_SOFTWARE'], 'lighttpd') !== false) {
        $_lighty_url = $base_url.$_SERVER['REQUEST_URI'];
        $_lighty_url = @parse_url($_lighty_url);
        if ($_lighty_url['path'] != '/index.php' && $_lighty_url['path'] != '/') {
            $_SERVER['QUERY_STRING'] = $_lighty_url['query'];
            parse_str($_lighty_url['query'], $_lighty_query);
            foreach ($_lighty_query as $key => $val)
                $_GET[$key] = $_REQUEST[$key] = $val;
            $_GET['q'] = $_REQUEST['q'] = substr($_lighty_url['path'], 1);

    This doesn’t return a 404 by the server if there exists content. :)

  • James August 24, 2008, 8:31 pm

    Hi .. can someone with expertise in lighty rules please help..I am using Drupal CMS on a LLMP stack and I am stuck on trying

    to come up with rules for a particular module I am wanting to use.

    In lighttpd.conf I have:
    $HTTP[“host”] =~ “(^|\.)mydomain\.com” {
    server.document-root = “/var/www/public_html/mydomain.com/”
    index-file.names = ( “index.php” )
    # for clean urls
    magnet.attract-physical-path-to = (“/etc/lighttpd/rewrite_drupal.lua”)

    In rewrite_drupal.lua I have:
    — little helper function
    function file_exists(path)
    local attr = lighty.stat(path)
    if (attr) then
    return true
    return false
    function removePrefix(str, prefix)
    return str:sub(1,#prefix+1) == prefix..”/” and str:sub(#prefix+2)

    — prefix without the trailing slash

    — If reverting back to production mode comment in the above line and uncomment the line below

    local prefix = ”

    — the magic ;)
    if (not file_exists(lighty.env[“physical.path”])) then
    — file still missing. pass it to the fastcgi backend
    request_uri = removePrefix(lighty.env[“uri.path”], prefix)
    if request_uri then
    lighty.env[“uri.path”] = prefix .. “/index.php”
    local uriquery = lighty.env[“uri.query”] or “”
    lighty.env[“uri.query”] = uriquery .. (uriquery ~= “” and “&” or “”) .. “q=” .. request_uri
    lighty.env[“physical.rel-path”] = lighty.env[“uri.path”]
    lighty.env[“request.orig-uri”] = lighty.env[“request.uri”]
    lighty.env[“physical.path”] = lighty.env[“physical.doc-root”] .. lighty.env[“physical.rel-path”]
    — fallthrough will put it back into the lighty request loop
    — that means we get the 304 handling for free. ;)


    Given the above here is my question :

    I want to know how to enable the following rules for a drupal module called “boost” which tries
    to serve cached html pages bypassing php/drupal and the database. There is a write-up on this
    at: http://codesorcery.net/2007/07/23/boost-your-drupal-site

    Now for this Drupal module to work, there are rewrite rules needed. Currently the module author
    has noly provided htaccess rules for Apache. I need lighttpd rules. I have pasted above the rules
    I currently have in lighttpd.conf and rewrite_drupal.lua file. Can someone pls help me with the rules to
    add to the lua or the lighttpd.conf file to make this module work.

    I am pasting below the htaccess rules specific to this module that the author is recommending. If anyone
    has any suggestions on how it can work with lighttpd that would be a big help.

    # Apache htaccess Rewrite rules for static page caching provided by the Boost module:

    Header add Expires “Sun, 19 Nov 1978 05:00:00 GMT”
    Header add Cache-Control “no-store, no-cache, must-revalidate, post-check=0, pre-check=0”

    AddCharset utf-8 .html

    RewriteCond %{REQUEST_METHOD} ^GET$
    RewriteCond %{REQUEST_URI} ^/$
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{HTTP_COOKIE} !DRUPAL_UID
    RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0/index.html -f
    RewriteRule ^(.*)$ cache/%{SERVER_NAME}/0/index.html [L]
    RewriteCond %{REQUEST_METHOD} ^GET$
    RewriteCond %{REQUEST_URI} !^/cache
    RewriteCond %{REQUEST_URI} !^/user/login
    RewriteCond %{REQUEST_URI} !^/admin
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{HTTP_COOKIE} !DRUPAL_UID
    RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0%{REQUEST_URI} -d
    RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0%{REQUEST_URI}/index.html -f
    RewriteRule ^(.*)$ cache/%{SERVER_NAME}/0/$1/index.html [L]
    RewriteCond %{REQUEST_METHOD} ^GET$
    RewriteCond %{REQUEST_URI} !^/cache
    RewriteCond %{REQUEST_URI} !^/user/login
    RewriteCond %{REQUEST_URI} !^/admin
    RewriteCond %{QUERY_STRING} ^$
    RewriteCond %{HTTP_COOKIE} !DRUPAL_UID
    RewriteCond %{DOCUMENT_ROOT}/cache/%{SERVER_NAME}/0%{REQUEST_URI}.html -f
    RewriteRule ^(.*)$ cache/%{SERVER_NAME}/0/$1.html [L]

    # Rewrite current-style URLs of the form ‘index.php?q=x’.
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]

Security: Are you a robot or human?

Leave a Comment

   Tagged with: , , , , , , , , , , , , ,