lighttpd

Set header for a file with a rewrite-if-not-file rule


We are using lighttpd as a webserver for static files. I have to add a header to all requests that serve the file index.$SYSTEM_ENV.html. There is also a rewrite-if-not-file rule that complicates all things:

# Return index.html when the requested file does not exist.
url.rewrite-if-not-file = ("/(.*)" => "/index." + env.SYSTEM_ENV + ".html")

I would like to add the header to all requests that serve the file "/index." + env.SYSTEM_ENV + ".html".

How can I do that? The header should only be added if the file index.$SYSTEM_ENV.html was served. *.js and *.css do not need this header. Is there a way to add a rule for the physical file instead of the path of the request?

Currently, we add this header to all files:

# Set security headers
$HTTP["url"] =~ "/.*" {
    setenv.add-response-header += ("X-Frame-Options" => "DENY")
}

Solution

  • lighttpd mod_rewrite re-runs the configuration after a URL is rewritten internally.

    Did you try the following?

    var.index_system_env = "/index." + env.SYSTEM_ENV + ".html"
    $HTTP["url"] == var.index_system_env {
        setenv.add-response-header += ("X-Frame-Options" => "DENY")
    }
    

    If the above does not meet your needs then you can look at using lighttpd mod_magnet with magnet.attract-response-start-to = ("/path/to/your/lua.script") and write a simple Lua script to set the response header as needed.

    server.modules += ("mod_magnet", "mod_setenv")
    magnet.attract-response-start-to = ("/path/to/system_env_index.lua")
    var.index_system_env = "/index." + env.SYSTEM_ENV + ".html"
    setenv.set-environment += ("SYSTEM_ENV" => env.SYSTEM_ENV)
    $HTTP["url"] == var.index_system_env {
        setenv.add-response-header += ("X-Frame-Options" => "DENY")
    }
    

    /path/to/system_env_index.lua

    local r = lighty.r
    -- if r.req_attr["response.http-status"] == "404" then   -- lighttpd <1.4.65
    if r.req_item.http_status == 404 then                    -- lighttpd 1.4.65+
      local target = r.req_attr["physical.doc-root"] ..
                     '/index.' .. r.req_env["SYSTEM_ENV"] .. '.html'
      local st = lighty.c.stat(target)
      if st then
        r.resp_header["X-Frame-Options"] = "DENY"
        r.resp_body.set()
        return st["http-response-send-file"]
      end
    end
    

    I do not know how or why you are using SYSTEM_ENV, but the above would be simpler without it.