lighttpd

Add custom dynamic header to lighttpd


I want to add a custom header containing MD5 hash of the file being downloaded.

First I used mod_setenv:

$HTTP["url"] =~ "myfile.bin$" {
    setenv.set-response-header = ( "x-MD5" => "add7e78a99cfee8a376b5f12e5b6f6b2")
}

And it works. But I want to set that MD5 value dynamically without needing to restart lighttpd. So I've tried mod_magnet and lua:

$HTTP["url"] =~ "myfile.bin$" {
    magnet.attract-physical-path-to = ( "/etc/lighttpd/md5.lua" )
}

md5.lua:

f = assert(io.open("/etc/lighttpd/md5", "r"))
md5 = f:read("*all")
f:close()

lighty.header["x-MD5"] = md5

And it adds that header but removes all other headers that were there before, like Content-Type, Last-Modified, Content-Length, Date etc:

$ wget --server-response --spider localhost/myfile.bin
Spider mode enabled. Check if remote file exists.
--2022-12-31 13:10:14--  http://localhost/myfile.bin
Resolving localhost (localhost)... 127.0.0.1
Connecting to localhost (localhost)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response...
  HTTP/1.1 200 OK
  x-MD5: add7e78a99cfee8a376b5f12e5b6f6b2
Length: unspecified
Remote file exists and could contain further links,
but recursion is disabled -- not retrieving.

How do I deal with this? In this case I tried reading MD5 hash stored in a file but the best solution would be if this lua script could read the hash of the file on the fly.


Solution

  • Your /etc/lighttpd/md5.lua script is broken. You are setting "x-MD5" to the entire contents of "/etc/lighttpd/md5", which might contain multiple lines, including newlines. You need to select a single line, and you need to remove any newlines before you set the header, or else you have corrupted the HTTP response from lighttpd, and that looks like exactly what you are seeing.

    If the file /etc/lighttpd/md5.lua contains a single line, then you should remove the newline before setting the header value. However, in that case, you might instead modify /etc/lighttpd/md5.lua with a hard-coded MD5 each time the MD5 of your target file changes. lighttpd will automatically reload /etc/lighttpd/md5.lua each time the timestamp on /etc/lighttpd/md5.lua is updated, without requiring that lighttpd be restarted.

    A more generic solution would be to have the lua script read the file and calculate the MD5, then add the header.

    If you're running lighttpd 1.4.60 or later, you should use lighty.r.resp_header["x-MD5"] = md5 to set the response header. See https://wiki.lighttpd.net/mod_magnet