Hello there,
I googled for this problem a lot and did some digging in this forum, but nothing really matches my problem.
As the summary suggests, I made a script which serves a file, thus masking its path on the server and supporting authorisation.
Unfortunately some customers complain about getting corrupted files. Even reloading the files does not help. The data on the server is definitely not corrupted for this problem does only occur very rarely. Alas I have not got further information about those having trouble with corrupted files.
I checked whether there are chars before <?php or after ?>, which is not the case. To be sure, I even set error_reporting(0); for testing purposes on the download page.
Recently I realised that the response headers on the customer’s server server differ from my local Apache and my private webspace. Especially the Content-Length header is not set on my customer’s server for a reason I cannot understand. I also suspect the “Transfer-Encoding: chunked” which magically appears although never being set by me to maybe cause trouble.
Before posting the basic code of my script with all the headers and the different response headers, I shape my question:
Is it possible that these cases with corrupted data occur due to the headers sent on the customer’s server?
If yes: What can I do about it? The headers below are the only ones I set in my entire script.
If no: What else can cause the files being corrupted constantly for several customers?
I appreciate any help, thank you in anticipation!
Sincerely yours.
error_reporting(0);
$file = "file.exe";
header('Content-Description: File Transfer');
$modified = gmdate('D, d M Y H:i:s').' GMT';
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Last-Modified: $modified");
$filesize = filesize($file);
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: binary");
header("Expires: ".date("r", time() + (24 * 3600)));
header('Accept-Ranges: bytes');
header("Cache-Control: private", false);
header("Pragma: private");
header("Content-Length: ".$filesize);
header('Content-Disposition: attachment; filename="'.basename($file).'"');
ob_clean();
flush();
readfile($file);
exit;
Output on the customer’s server:
HTTP/1.1 200 OK
Date Thu, 11 Mar 2010 13:05:14 GMT
Server Apache/2.2.14 (Unix)
X-Powered-By PHP/5.2.12
Content-Description File Transfer
Cache-Control must-revalidate, post-check=0, pre-check=0, private
Content-Transfer-Encoding binary
Last-Modified Thu, 11 Mar 2010 13:05:15 GMT
Expires Fri, 12 Mar 2010 14:05:15 +0100
Accept-Ranges bytes
Vary Accept-Encoding
Pragma private
Content-Encoding gzip
Content-Disposition attachment; filename="file.exe"
Content-Type application/octet-stream
Transfer-Encoding chunked
Output on my webspace:
HTTP/1.1 200 OK
Date Thu, 11 Mar 2010 13:12:12 GMT
Server Apache/2.2.9 (Debian) DAV/2 mod_ssl/2.2.9 OpenSSL/0.9.8g PHP/5.2.6-1+lenny3 with Suhosin-Patch
X-Powered-By PHP/5.2.6-1+lenny3
Content-Description File Transfer
Cache-Control must-revalidate, post-check=0, pre-check=0
Content-Transfer-Encoding binary
Last-Modified Thu, 11 Mar 2010 13:12:12 GMT
Expires Fri, 12 Mar 2010 14:12:12 +0100
Accept-Ranges bytes
Cache-Control private
Pragma private
Content-Length 573943
Content-Disposition attachment; filename="file.exe"
Content-Type application/octet-stream
Output on my local Apache:
HTTP/1.1 200 OK
Date Thu, 11 Mar 2010 13:02:53 GMT
Server Apache/2.2.13 (Win32) PHP/5.2.11
X-Powered-By PHP/5.2.11
Content-Description File Transfer
Cache-Control must-revalidate, post-check=0, pre-check=0
Content-Transfer-Encoding binary
Last-Modified Thu, 11 Mar 2010 13:02:53 GMT
Expires Fri, 12 Mar 2010 14:02:53 +0100
Accept-Ranges bytes
Cache-Control private
Pragma private
Content-Length 573943
Content-Disposition attachment; filename="file.exe"
Content-Type application/octet-stream