Reputation: 425
I'm trying to send files (attachments) for users outside webroot. I made force download script, which sends the file in the header and outputs it in stream. This works good, until I call readfile (could be also header settings), which outputs a file which contains a half of my html source (of this specific page). I did file_get_contents() and the file contained the proper string: "test". What is the problem here?
<?php
//The path where the files are stored
$file_path = "";
if(isset($_GET['file'])) {
$file_path = $_GET['file'];
}
else {
header('HTTP/1.0 404 Not Found');
die('File not found!');
}
$file_name = basename($_GET['file']);
//Make sure the file exists
if(!file_exists($file_path) && !is_file($file_name)) {
header('HTTP/1.0 404 Not Found');
die('File not found!');
}
//Initialize the actual file.
$file = $file_path;
//Notice: Remember to set fifo extension in php.ini
//Windows users must include the bundled php_fileinfo.dll DLL file in php.ini to enable this extension.
$finfo = new finfo(FILEINFO_MIME);
$mime = "";
if(function_exists("finfo_open")) {
$finfo = finfo_open(FILEINFO_MIME);
$mime = finfo_file($finfo, $file);
}
// Provide a default type in case all else fails
else {
$mime = "application/octet-stream";
}
//Set the appropriate content-type and provide the content-length.
header('Content-Description: File Transfer');
header('Content-Transfer-Encoding: binary');
header('Content-type: '.$mime);
header('Content-Disposition: attachment; filename='.$file_name);
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: '.filesize($file));
//Print the image data
readfile($file);
exit;
?>
The $file is called test.txt and contains string "test". Mime/content-type is proper.
The output of this script however is html source.
Upvotes: 4
Views: 2947
Reputation: 101614
From the readfile
docs, they make two call before the readfile
(with a forced download): ob_clean()
& flush()
. My assumptions is they call these to make sure headers have been sent and the client understands there's content coming.
I suggest adding those in there, and it should work.
Upvotes: 6