I've the next script to allow a customer download personal files:
header( 'Content-Type: application/octet-stream' ); header( 'Content-Transfer-Encoding: binary' ); header( 'Content-Disposition: attachment; filename=' . $fileName ); header( 'Content-Length: ' . filesize( $filePath ) ); header( 'Content-Description: Download' ); header( 'Cache-Control: private' ); header( 'Pragma: no-cache' ); header( 'Expires: 0' ); readfile( $filePath ); exit();
It does not work perfectly. (I have also place the filename in quotes, same result).
It reacts very slow, and often the downloads even halt. In Opera especially, it halts on 99% from the download. It sometimes even immediately shows 99% completed, it begins installing and halts around 34%.
The server is really a shared host, Mac OS X server.
With using Firefox's Live HTTP headers add-on, I have observed the server adds aditional headers towards the response:
HTTP/1.1 200 OK Date: Thu, 18 Feb 2010 09:27:25 GMT Server: Apache X-Powered-By: PHP/5.2.12 Content-Transfer-Encoding: binary Content-Disposition: attachment; filename=test.psd Content-Length: 398635 Content-Description: Download Cache-Control: private Pragma: no-cache Expires: 0 Content-Encoding: gzip // <-- expecially this one, Vary: Accept-Encoding // <-- this one, MS-Author-Via: DAV // <-- and this one Keep-Alive: timeout=10, max=100 Connection: Keep-Alive Content-Type: application/octet-stream
Could these be the reason for the issue?
After I run the script on my small localhost everything works fine. Also, after i directly download files out of this host, the rate can also be fine and fluent.
I am really rather unaware on that one. Your assistance is appeciated. Thanks ahead of time.
I believe I've simplified the issue lower towards the bottleneck. The webserver instantly gzip compresses the output. After I removed the
Content-Length header from the PHP script everything began installing smooth. This will make sense: The need for the
Content-Length does not match the particular gzipped output any longer. In PHP I just read the uncompressed filesize to create the
Content-Length header, but later on, Apache compresses it, which is most likely in which the browsers clogged.
I'll follow this track of an issue concerning how to set the right
Content-Length header size once the webserver instantly gzip compresses output.
Try unsetting the gzip-Content-Encoding.
ob_start() in the beginning of the script before setting your headers, use
@ob_end_clean(); and immediately after it, explicitely set
header("Content-Encoding:"); to try and unset any gzip-Encoding that may are available in.
In the finish of the file place
The output loading functions are handy to create the header-setting more failsafe, but most likely not associated with your condition. I just be sure you went into problems inside a setup in which the attaching PHP code used doctor_gzhandler and that i required to unset it.
I personally use the code below and delay pills work. Suggesting the reality I didn't undersyand yet correctly all of the header which i send, I still was without time to research, I discovered explanations in:
http://www.opendesigns.org/forum/discussion/1437/php-download-counter/#pgbottom http://www.webdeveloper.com/forum/showthread.php?t=115815&highlight=PHP+download+counter http://php.net/manual/en/function.header.php#83384
anyway it really works:
/* TODO: still to be read and better understood. */ //no caching (I don't uderstand what is this part useful for) header("Pragma: public"); //? header("Expires: 0"); //? header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); //? header("Cache-Control: private", false); //? //sending download file header("Content-Type: application/octet-stream"); //application/zip can use application/octet-stream that is more generic it works because in now days browsers are able to detect file anyway header("Content-Disposition: attachment; filename=\"" . basename($file_serverfullpath) . "\""); //ok header("Content-Transfer-Encoding: binary"); //? header("Content-Length: " . filesize($file_serverfullpath)); //ok readfile($file_serverfullpath);