I have a force-download script that produces good results with PDF and plain text, and is semi-OK with ZIP archives (they work in Windows, not in Linux). However, application files and images all fail. These make up the vast majority of the files I must handle. Zipping all downloads, as I’ve seen suggested on similar topics here, is not an option.
The failing files download to their full size, and are written to disk under the correct name. Attempts to open them result in a error message, which differs between types. Comparing downloaded files to their originals in hexdump, I can see that the script inserts the following characters at the start of each downloaded file:
ef bb bf
The downloaded file then reproduces the original until it stops at its specified size – so the original’s last 6 characters are always missing.
Unfortunately I know nothing about how binary files are made up, what these characters might mean, or how/why the script is inserting them.
This is the script as-is:
$file = '94.ppt';
$path = $_SERVER['DOCUMENT_ROOT']."/relative/path/";
$full_path = $path.$file;
if ($fd = fopen ($full_path, "r")) {
$fsize = filesize($full_path);
$path_parts = pathinfo($full_path);
$ext = strtolower($path_parts["extension"]);
switch ($ext) {
case "pdf":
header("Content-type: application/pdf");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "txt":
header("Content-type: text/plain");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "jpg":
header("Content-type: image/jpeg");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
case "ppt":
header("Content-Type: application/vnd.ms-powerpoint");
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\"");
break;
default;
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Content-Transfer-Encoding: binary");
header("Content-length: $fsize");
header("Cache-control: private");
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
}
fclose ($fd);
exit;
The development system is PHP 5.3.2-1 on Apache 2.2.14 (Ubuntu). The production host is PHP 5.2.9 on Apache 2.0.63 (some type of Linux).
EF BB BFis the UTF-8 encoding Byte Order Mark (BOM). I suspect there is some configuration option to turn off the BOM.Edit: File editors should allow you to turn off the BOM when saving an file in relevant character encodings (e.g. UTF-8).