I’ve created a script that lets the user download files:
function file_size($filename)
{
exec('stat -c %s ' . escapeshellarg($filename), $return);
return (float)$return[0];
}
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filename));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . file_size($filename));
readfile($filename);
exit;
Very simple. The file_size function lets me detect file sizes larger than 2 GB.
The problem is that Content-length never is above 2 GB:
< HTTP/1.1 200 OK
< Date: Sun, 21 Aug 2011 09:33:20 GMT
< Server: Apache
< Content-Description: File Transfer
< Content-Disposition: attachment; filename=very-large-file
< Content-Transfer-Encoding: binary
< Expires: 0
< Cache-Control: must-revalidate, post-check=0, pre-check=0
< Pragma: public
< Content-Length: 2147483647
< Content-Type: application/octet-stream
Doing a var_dump on 'Content-Length: ' . file_size($filename) returns string(26) "Content-Length: 4689218232". If I access the file directly without a PHP script, there is no problem and Apache is reporting the correct file size:
< HTTP/1.1 200 OK
< Date: Sun, 21 Aug 2011 09:58:33 GMT
< Server: Apache
< Last-Modified: Thu, 06 Jan 2011 21:56:47 GMT
< ETag: "8ba8f5e0-1177fcab8-49934940b30e5"
< Accept-Ranges: bytes
< Content-Length: 4689218232
But I’d really like to serve the file through my PHP script. Thank you for your time.
Sending huge files with
readfileis not good practice.Use
X-Sendfile, like this:header("X-Sendfile: $filename");. You’ll need apachemod_sendfile. This should also solve your file-size problem.