Download fails on files greater than 10M

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • empiresolutions
    New Member
    • Apr 2006
    • 162

    Download fails on files greater than 10M

    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.

    Code:
        function download() {
    
            global $_GET;
    
            //Gather relevent info about file
            $file = "/user/dac420/tts/incoming/".$_GET['name'];
            $len = filesize($file);
            $filename = basename($file);
            $file_extension = strtolower(substr(strrchr($filename,"."),1));
    
            // Determine correct MIME type
            switch($file_extension){
    
                case "asf":     $ctype = "video/x-ms-asf";                break;
                case "avi":     $ctype = "video/x-msvideo";               break;
                case "exe":     $ctype = "application/octet-stream";      break;
                case "mov":     $ctype = "video/quicktime";               break;
                case "mp3":     $ctype = "audio/mpeg";                    break;
                case "mpg":     $ctype = "video/mpeg";                    break;
                case "mpeg":    $ctype = "video/mpeg";                    break;
                case "rar":     $ctype = "encoding/x-compress";           break;
                case "txt":     $ctype = "text/plain";                    break;
                case "wav":     $ctype = "audio/wav";                     break;
                case "wma":     $ctype = "audio/x-ms-wma";                break;
                case "wmv":     $ctype = "video/x-ms-wmv";                break;
                case "zip":     $ctype = "application/x-zip-compressed";  break;
                default:        $ctype = "application/force-download";    break;
    
            }
    
            //Begin writing headers
            header("Cache-Control:");
            header("Cache-Control: public");
    
            //Use the switch-generated Content-Type
            header("Content-Type: $ctype");
    
            if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE")) {
                # workaround for IE filename bug with multiple periods / multiple dots in filename
                # that adds square brackets to filename - eg. setup.abc.exe becomes setup[1].abc.exe
                $iefilename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
                header("Content-Disposition: attachment; filename=\"$iefilename\"");
            } else {
                header("Content-Disposition: attachment; filename=\"$filename\"");
            }
    
            header("Accept-Ranges: bytes");
    
            $size=filesize($file);
    
            //check if http_range is sent by browser (or download manager)
            if(isset($_SERVER['HTTP_RANGE'])) {
    
                list($a, $range)=explode("=",$_SERVER['HTTP_RANGE']);
    
                //if yes, download missing part
                str_replace($range, "-", $range);
                $size2=$size-1;
                $new_length=$size2-$range;
    
                header("HTTP/1.1 206 Partial Content");
                header("Content-Length: $new_length");
                header("Content-Range: bytes $range$size2/$size");
    
            } else {
    
                $size2=$size-1;
                header("Content-Range: bytes 0-$size2/$size");
                header("Content-Length: ".$size);
    
            }
    
            //open the file
            $fp=fopen("$file","rb");
    
            //seek to start of missing part
            fseek($fp,$range);
    
            //start buffered download
            while(!feof($fp)){
    
                //reset time limit for big files
                set_time_limit(0);
    
                print(fread($fp,filesize($file)));
                flush();
                ob_flush();
    
            }
    
            fclose($fp);
            exit;
    
        }
  • MarkoKlacar
    Recognized Expert Contributor
    • Aug 2007
    • 296

    #2
    Hi,

    Did you set any limit to the file size in the form you use to upload the files?

    Comment

    • empiresolutions
      New Member
      • Apr 2006
      • 162

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

      replace the while() in my above code.

      Code:
      	//start buffered download
      	while(!feof($fp)){
      
      		$total     = filesize($file);
      		$sent      = 0;
      		$blocksize = (2 << 20); //2M chunks
      		$handle    = fopen($file, "r");
      
      		// Now we need to loop through the file and echo out chunks of file data
      		// Dumping the whole file fails at > 30M!
      		while($sent < $total){
      			echo fread($handle, $blocksize);
      			$sent += $blocksize;
      		}
      
      		exit(0);
      		@flush();
      		@ob_flush();
      	}

      Comment

      • empiresolutions
        New Member
        • Apr 2006
        • 162

        #4
        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?

        Comment

        • MarkoKlacar
          Recognized Expert Contributor
          • Aug 2007
          • 296

          #5
          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

          Comment

          • Markus
            Recognized Expert Expert
            • Jun 2007
            • 6092

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

            Is that correct?

            Comment

            • empiresolutions
              New Member
              • Apr 2006
              • 162

              #7
              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

              Comment

              Working...