01 Oct 2010 18:03
TAGS: lighttpd php wikidot xsendfile
Instead of having a PHP process copying file through FastCGI to Lighttpd (which would copy it again to the client) we send a special header to Lighttpd naming the file it should serve to the client. This means PHP processes are terminated quicker, which result in overall better performance.
When working on a Wikidot bug (some uploaded files with some special characters in their names are not accessible using links generated by Wikidot itself), I discovered Wikidot also doesn't serve files whose name end with a space.
The problem disappeared when I (just for test) disabled X-Sendfile mechanism. Pure PHP has no problems in reading such files and sending them through Lighttpd to browser, so it seemed there's a problem with Lighttpd.
Lighttpd v1.4.24 introduced a second X-Sendfile header: X-Sendfile2, which asks Lighttpd to send a chunk of a file (from byte Xth, to Yth), but also a whole file (from byte 0th to the last one). The syntax is:
X-Sendfile2: PATH RANGE
Where PATH is URL-encoded file path (PHP's rawurlencode, not the non-standard urlencode), RANGE is X-Y (or "0-" for whole file), so changing:
header("X-Sendfile: " . $path);
header("X-Sendfile2: " . rawurlencode($path) . " 0-");
fixes the problem.