I set a header in the following way:
header('Content-Length: ' . filesize($strPath));
On my PC with ZendServer it works fine and I can download a file with the correct file size. On the production server, a Solaris with Apache and compiled PHP, I get a file with the file size equal to zero, so an empty file.
Is there a config parameter? Something that can prevent to set 'Content-Length: 1222'?
Thanks.
The code:
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
require 'includes/prepend.inc.php';
require __ADMIN_DIR__.'/AdminInfo.php';
$intFile = QApplication::QueryString('fileID');
if($intFile == '') die('Error: missing ID');
$objFile = File::Load($intFile);
$blnRight = false;
$objAdminInfo = new AdminInfo();
if($objAdminInfo->isAdmin()) {
$blnRight = true;
}
else {
$objSecMan = new SecurityManager(
'file:'.$objFile->FileID,
$objAdminInfo->getUserID()
);
$blnRight = $objSecMan->processResource('view');
}
// if the user can modify and or publish, can even view the file
if(!$blnRight) {
$blnRight = $objSecMan->processResource('modify');
if(!$blnRight) {
$blnRight = $objSecMan->processResource('publish');
}
}
//$strPath = __UPLOADS__.DIRECTORY_SEPARATOR.$objFile->FileID;
$strPath = 'subdept.csv';
if (file_exists($strPath) && $blnRight) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$strPath);//$objFile->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: ' . filesize($strPath));
ob_clean();
flush();
readfile($strPath);
exit;
}
else {
die('Restricted access');
}
?>
When I comment the code before $strPath it works, so it must be something in the bloody framework. I would like to throw the whole CMS away.
Check for transfer-encoding header. If the transfer encoding is chunked, then the Content-Length field will not be set
Possible causes, is that ZendServer does not do chunked encoding, whereas Apache does
See the following links for details
Make sure that the file really exists under the specified path (is_file
checks both the existance and if the file is a regular file) and is readable (is_readable
) before sending it to the client. filesize
returns false if an error occured. So that might be the cause of your 0 value or empty value for Content-Length.
And, as Ferdinand Beyer already mentioned, make sure that your script is portable and can handle different environments.
Are you sure the file exists on the production server? Maybe it's a case sensitivity issue (e.g, "File" and "file" are the same on Windows, but different on UNIX)? Does the user running Apache/PHP have read access?
Do you get any errors if you enable errors?
error_reporting(E_ALL);
ini_set('display_errors', '1');
A problem may be that Apache is gzipping your download, taking care of correcting the Content-Length, or in your case, removing that header and adding
Content-Encoding: chunked
You can add a .htaccess
RewriteRule to disable gzip:
RewriteRule . - [E=no-gzip:1]
来源:https://stackoverflow.com/questions/1334471/content-length-header-always-zero