Bottyz Posted November 23, 2010 Share Posted November 23, 2010 Hi all, I wrote a download script for some protected files a little while back. And on the whole, its works pretty well but occasionally, zip files will not completely download and will end up corrupted. It happens more with bigger files but that i'm guessing is due to the fact it takes longer to download them? I've searched intensively on Google for the past few days and implemented a few new ideas, which hasn't made a difference. Its annoying, in the fact you can try the same file a few times over and it'll download 8 out of 10 times no problem. I even added in the apachesentenv after a recommendation, as the rest of my site is gzip php'd. But that hasn't worked either. Part of the code as follows: apache_setenv('no-gzip', '1'); // if file exists and user access granted: // define the path to your download folder plus assign the file name $path .= $filename; // check that file exists and is readable if (file_exists($path) && is_readable($path)) { // get the file size and send the http headers $size = filesize($path); // required for IE, otherwise Content-disposition is ignored if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression', 'Off'); //content type switch(strtolower(substr(strrchr($filename,'.'),1))) { case "pdf": $mime="application/pdf"; break; case "mp3": $mime="audio/x-mp3"; break; case "zip": $mime="application/zip"; break; case "rar": $mime="application/zip"; break; case "tar": $mime="application/zip"; break; case "sit": $mime="application/zip"; break; case "doc": $mime="application/msword"; break; case "xls": $mime="application/vnd.ms-excel"; break; case "ppt": $mime="application/vnd.ms-powerpoint"; break; case "gif": $mime="image/gif"; break; case "png": $mime="image/png"; break; case "jpeg":$mime="image/jpg"; break; case "jpg": $mime="image/jpg"; break; default: $mime="application/force-download"; } header("Cache-Control: public"); header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Content-Description: File Transfer"); header("Content-Type: " .$mime); header("Content-Disposition: attachment; filename=\"{$filename}\""); header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . filesize($path)); readfile("$path"); if($logging == 1){ $status = "Granted"; include('logit.php'); } exit; } Live http Headers in Firefox displays the following upon clicking a download: http://www.website.com/filedownload.php?file=12 GET /filedownload.php?file=12 HTTP/1.1 Host: www.website.com User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.2.12) Gecko/20101026 Firefox/3.6.12 ( .NET CLR 3.5.30729) Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-gb,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 115 Connection: keep-alive Referer: http://www.website.com/downloads.php Cookie: __utma=100661891.2064943237.1286446219.1290502952.1290505322.70; __utmz=100661891.1290502952.69.8.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=lighthouse%20cjpro; __utmc=100661891; __utmb=100661891.43.10.1290505322; PHPSESSID=8aadcc17930b9e146f103f180f30f470 HTTP/1.1 200 OK Date: Tue, 23 Nov 2010 11:22:13 GMT Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 PHP/5.2.12 X-Powered-By: PHP/5.2.12 Expires: 0 Cache-Control: must-revalidate, post-check=0, pre-check=0 Pragma: public Content-Description: File Transfer Content-Disposition: attachment; filename="Version_5_Software.zip" Content-Transfer-Encoding: binary Content-Length: 62654423 Keep-Alive: timeout=2, max=100 Connection: Keep-Alive Content-Type: application/zip ---------------------------------------------------------- Are my headers wrong? or in the incorrect order? If not, any ideas? I'm a bit stumped! Thanks for taking the time to read my query. Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/ Share on other sites More sharing options...
BlueSkyIS Posted November 23, 2010 Share Posted November 23, 2010 any chance your script is timing out before sending the whole file? Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/#findComment-1138442 Share on other sites More sharing options...
Bottyz Posted November 24, 2010 Author Share Posted November 24, 2010 any chance your script is timing out before sending the whole file? It did cross my mind, but if thats the case then why does it work most of the time and not some of the time? Currently, It will corrupt with all sizes of zip file (since changes i made). Current code is as above and 8 times out of 10 the zips will download fine. Sometimes the file can say its downloaded instantaneously and you open it to find its corrupted, even when the file is supposed to be 40mb? It always states the correct file size when you click save as. Its as if something interrupts the download. Any further help would be appreciated as always! This is getting very frustrating :'( Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/#findComment-1138938 Share on other sites More sharing options...
Bottyz Posted November 24, 2010 Author Share Posted November 24, 2010 Hi all, I've implemented a different set of headers now, which seem to work but won't allow users to download more than one file at a time. Is the following a safe way of overcoming the problem? // if file exists and user access granted: // define the path to your download folder plus assign the file name $path .= $filename; // check that file exists and is readable if (file_exists($path) && is_readable($path)) { apache_setenv('no-gzip', '1'); // required for IE, otherwise Content-disposition is ignored if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); } //content type switch(strtolower(substr(strrchr($filename,'.'),1))) { case "pdf": $mime="application/pdf"; break; case "zip": $mime="application/zip"; break; case "doc": $mime="application/msword"; break; case "xls": $mime="application/vnd.ms-excel"; break; case "jpeg":$mime="image/jpg"; break; case "jpg": $mime="image/jpg"; break; default: $mime="application/force-download"; } header('Content-Disposition: attachment; filename=' . urlencode($filename)); header('Content-Type: application/force-download'); header('Content-Type: application/octet-stream'); header('Content-Type: application/download'); header('Content-Description: File Transfer'); header('Content-Length: ' . filesize($path)); echo file_get_contents($path); if($logging == 1){ $status = "Granted"; include('logit.php'); } exit; } :-\ Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/#findComment-1138999 Share on other sites More sharing options...
Bottyz Posted November 25, 2010 Author Share Posted November 25, 2010 Hi all, found a problem with my revised script. I have a 94mb zip file that just downloads 0kb. Is there some kind of memory limit that file_get_contents can't exceed? The server memory limit is 128mb. thanks Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/#findComment-1139427 Share on other sites More sharing options...
Bottyz Posted November 25, 2010 Author Share Posted November 25, 2010 Right ok, after more tweaking and even looking into cURL as a method of correcting the file downloads (and omitting it as i can't figure out how to present a user with a save to.. dialog), i've come up with the following: // if file exists and user access granted: // Set maximum script execution time in seconds (0 means no limit) set_time_limit(0); // define the path to your download folder plus assign the file name $path .= $filename; // file size in bytes $fsize = filesize($path); // check that file exists and is readable if (file_exists($path) && is_readable($path)) { apache_setenv('no-gzip', '1'); // required for IE, otherwise Content-disposition is ignored if(ini_get('zlib.output_compression')) { ini_set('zlib.output_compression', 'Off'); } //content type switch(strtolower(substr(strrchr($filename,'.'),1))) { case "pdf": $mime="application/pdf"; break; case "zip": $mime="application/zip"; break; case "doc": $mime="application/msword"; break; case "xls": $mime="application/vnd.ms-excel"; break; case "jpeg":$mime="image/jpg"; break; case "jpg": $mime="image/jpg"; break; default: $mime="application/force-download"; } // set headers header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-Type: $mime"); header("Content-Disposition: attachment; filename=\"$filename\""); header("Content-Transfer-Encoding: binary"); header("Content-Length: " . $fsize); // download $file = @fopen($path,"rb"); if ($file) { while(!feof($file)) { print(fread($file, 1024*); flush(); if (connection_status()!=0) { @fclose($file); die(); } } @fclose($file); } if($logging == 1){ $status = "Granted"; include('logit.php'); } exit; } The above seems to work with all files again now, but will need some constant testing for a little while to see if i get anymore corrupted transfers. If anyone can see any obvious mistakes in the code snippet above, please let me know. Also, can anyone see any issues with cpu usage or similar on the above? Hopefully the code will also help anyone else with similar issues... If i don't get anymore errors, i'll post back and mark as solved. I'm surprised no more of you php wizards have been able to help further? Maybe i posted on a dodgy topic. Thanks for reading my random rantings and thoughts anyways! PS. On another note, anybody have an idea as to how you would allow pausing and resuming of downloads? Or am i looking too much into this? lol! Link to comment https://forums.phpfreaks.com/topic/219561-problem-with-downlod-script-maybe-wrong-headers/#findComment-1139455 Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.