views:

651

answers:

4

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.

A: 

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?

Ferdinand Beyer
+2  A: 

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.

Gumbo
It is not an issue of permissions, I am testing a file with 777. It is not an issue of file name. The file exists and has not 0 file size. I can download it by putting the URI in the browser, but the script renders always 0.
rtacconi
@rtacconi: Did you check the actual raw HTTP header of the response?
Gumbo
No, I thought to check it but I should find a tutorial about HTTP for the comment to use in the telnet
rtacconi
@rtacconi: Try http://web-sniffer.net/
Gumbo
I cannot use web sniffer because the site is an intranet, but I have found 'Live HTTP Headers' fine.
rtacconi
A: 

Do you get any errors if you enable errors?

error_reporting(E_ALL);
ini_set('display_errors', '1');
bucabay
No, I do not get any error.
rtacconi
+3  A: 

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

http://en.wikipedia.org/wiki/Chunked_transfer_encoding

http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html

Ram
Thanks! I get:Transfer-Encoding: chunkedand no 'Content-Length'I should find a way to stop the server to do that.
rtacconi
Maybe, though not sure, the Zend framework determines whether to use chunked encoding or not. Need to check the documentation
Ram
ok, thanks a lot
rtacconi