Connecting Tech Pros Worldwide Forums | Help | Site Map

Download fails on files greater than 10M

Familiar Sight
 
Join Date: Apr 2006
Posts: 133
#1: Mar 4 '08
Using the following code, files greater than 10Megs do not download. Less than 10 is working. Can anyone explain why? Files that will be downloaded are 5G plus in size.

Expand|Select|Wrap|Line Numbers
  1.     function download() {
  2.  
  3.         global $_GET;
  4.  
  5.         //Gather relevent info about file
  6.         $file = "/user/dac420/tts/incoming/".$_GET['name'];
  7.         $len = filesize($file);
  8.         $filename = basename($file);
  9.         $file_extension = strtolower(substr(strrchr($filename,"."),1));
  10.  
  11.         // Determine correct MIME type
  12.         switch($file_extension){
  13.  
  14.             case "asf":     $ctype = "video/x-ms-asf";                break;
  15.             case "avi":     $ctype = "video/x-msvideo";               break;
  16.             case "exe":     $ctype = "application/octet-stream";      break;
  17.             case "mov":     $ctype = "video/quicktime";               break;
  18.             case "mp3":     $ctype = "audio/mpeg";                    break;
  19.             case "mpg":     $ctype = "video/mpeg";                    break;
  20.             case "mpeg":    $ctype = "video/mpeg";                    break;
  21.             case "rar":     $ctype = "encoding/x-compress";           break;
  22.             case "txt":     $ctype = "text/plain";                    break;
  23.             case "wav":     $ctype = "audio/wav";                     break;
  24.             case "wma":     $ctype = "audio/x-ms-wma";                break;
  25.             case "wmv":     $ctype = "video/x-ms-wmv";                break;
  26.             case "zip":     $ctype = "application/x-zip-compressed";  break;
  27.             default:        $ctype = "application/force-download";    break;
  28.  
  29.         }
  30.  
  31.         //Begin writing headers
  32.         header("Cache-Control:");
  33.         header("Cache-Control: public");
  34.  
  35.         //Use the switch-generated Content-Type
  36.         header("Content-Type: $ctype");
  37.  
  38.         if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
  39.             # workaround for IE filename bug with multiple periods / multiple dots in filename
  40.             # that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
  41.             $iefilename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
  42.             header("Content-Disposition: attachment; filename=\"$iefilename\"");
  43.         } else {
  44.             header("Content-Disposition: attachment; filename=\"$filename\"");
  45.         }
  46.  
  47.         header("Accept-Ranges: bytes");
  48.  
  49.         $size=filesize($file);
  50.  
  51.         //check if http_range is sent by browser (or download manager)
  52.         if(isset($_SERVER['HTTP_RANGE'])) {
  53.  
  54.             list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
  55.  
  56.             //if yes, download missing part
  57.             str_replace($range, "-", $range);
  58.             $size2=$size-1;
  59.             $new_length=$size2-$range;
  60.  
  61.             header("HTTP/1.1 206 Partial Content");
  62.             header("Content-Length: $new_length");
  63.             header("Content-Range: bytes $range$size2/$size");
  64.  
  65.         } else {
  66.  
  67.             $size2=$size-1;
  68.             header("Content-Range: bytes 0-$size2/$size");
  69.             header("Content-Length: ".$size);
  70.  
  71.         }
  72.  
  73.         //open the file
  74.         $fp=fopen("$file","rb");
  75.  
  76.         //seek to start of missing part
  77.         fseek($fp,$range);
  78.  
  79.         //start buffered download
  80.         while(!feof($fp)){
  81.  
  82.             //reset time limit for big files
  83.             set_time_limit(0);
  84.  
  85.             print(fread($fp,filesize($file)));
  86.             flush();
  87.             ob_flush();
  88.  
  89.         }
  90.  
  91.         fclose($fp);
  92.         exit;
  93.  
  94.     }
  95.  

MarkoKlacar's Avatar
Expert
 
Join Date: Aug 2007
Location: Stockholm, Sweden
Posts: 294
#2: Mar 5 '08

re: Download fails on files greater than 10M


Hi,

Did you set any limit to the file size in the form you use to upload the files?
Familiar Sight
 
Join Date: Apr 2006
Posts: 133
#3: Mar 10 '08

re: Download fails on files greater than 10M


The solution is to split the file into chunks when sending. Thanks to everyone for your suggestions.

replace the while() in my above code.

Expand|Select|Wrap|Line Numbers
  1.     //start buffered download
  2.     while(!feof($fp)){
  3.  
  4.         $total     = filesize($file);
  5.         $sent      = 0;
  6.         $blocksize = (2 << 20); //2M chunks
  7.         $handle    = fopen($file, "r");
  8.  
  9.         // Now we need to loop through the file and echo out chunks of file data
  10.         // Dumping the whole file fails at > 30M!
  11.         while($sent < $total){
  12.             echo fread($handle, $blocksize);
  13.             $sent += $blocksize;
  14.         }
  15.  
  16.         exit(0);
  17.         @flush();
  18.         @ob_flush();
  19.     }
  20.  
Familiar Sight
 
Join Date: Apr 2006
Posts: 133
#4: Mar 10 '08

re: Download fails on files greater than 10M


So now that I have the download working I need to know why the page is not refreshing at the end of the script. The download happen, then nothing. How do i get the page to continue after download?
MarkoKlacar's Avatar
Expert
 
Join Date: Aug 2007
Location: Stockholm, Sweden
Posts: 294
#5: Mar 10 '08

re: Download fails on files greater than 10M


Quote:

Originally Posted by empiresolutions

So now that I have the download working I need to know why the page is not refreshing at the end of the script. The download happen, then nothing. How do i get the page to continue after download?

Hi,

What you can do is send the user to the correct page using header.

Good luck
Markus's Avatar
Moderator
 
Join Date: Jun 2007
Location: York, England, with wolves.
Posts: 4,948
#6: Mar 10 '08

re: Download fails on files greater than 10M


Nothing greatly important here but, you don't need to globalise GET as it is already a SUPERGLOBAL.

Is that correct?
Familiar Sight
 
Join Date: Apr 2006
Posts: 133
#7: Mar 11 '08

re: Download fails on files greater than 10M


Quote:

Originally Posted by MarkoKlacar

Hi,

What you can do is send the user to the correct page using header.

Good luck

header() is not working after the feof() call
Reply