You are correct, on both accounts.
I ended up with code that looked like this:
Ignore_User_Abort(True); // finish the script after it starts running
$start_time = time();
$filename = "files/cod/maps/portvillage.zip";
$ext = substr( $filename,-3 );
if( $filename == "" ) {
echo "<html><body>ERROR: Empty file</body></html>";
exit;
} elseif ( ! file_exists( $filename ) ) {
echo "<html><body>ERROR: File not found</body></html>";
exit;
};
switch( $ext ){
case "pdf": $ctype="application/pdf"; break;
case "exe": $ctype="application/octet-stream"; break;
case "zip": $ctype="application/zip"; break;
case "doc": $ctype="application/msword"; break;
case "xls": $ctype="application/vnd.ms-excel"; break;
case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
case "gif": $ctype="image/gif"; break;
case "png": $ctype="image/png"; break;
case "jpg": $ctype="image/jpg"; break;
default: $ctype="application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Content-Type: $ctype");
$user_agent = strtolower ($_SERVER["HTTP_USER_AGENT"]);
if ((is_integer (strpos($user_agent, "msie"))) && (is_integer (strpos($user_agent, "win")))) {
header( "Content-Disposition: filename=".basename($filename).";" );
} else {
header( "Content-Disposition: attachment; filename=".basename($filename).";" );
}
header("Content-Transfer-Encoding: binary");
header("Content-Length: ".filesize($filename));
// write the results to a file
$fo = fopen("stream_result.txt", "wb");
fwrite($fo, "started file size = ".filesize($filename)."\n");
fclose($fo);
$fr = fopen($filename, 'rb');
while(!feof($fr)) {
$handle = fread($fr, filesize($filename));
print($handle); // send the file being read
flush();
}
// write the results to a file
if(connection_status() != 0) {
$fo = fopen("stream_result.txt", "ab");
fwrite($fo, "stopped after ".(time() - $start_time)." seconds\n\n");
fclose($fo);
} else {
$fo = fopen("stream_result.txt", "ab");
fwrite($fo, "completed after ".(time() - $start_time)." seconds\n\n");
fclose($fo);
}
fclose($fr);
I was getting missing data without the fopen.
And also the fopen opens the entire file so I never have an accurate file pointer.
I tried experimenting with opening the file in packets where I would only read so much of the file out to the browser before going back for more. But I couldn't get this to read correctly either.
I can very nicely download a file and log if the file is complete or cancelled.. I just can't estimate the time to completion since I can't determine how much of the file is complete or any other stats during the download process.
I really hate the idea of estimating a general download time for a file since that can often be very inaccurate, but I may be stuck.
Thanks for your input.