Download fails on files greater than 10M

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
cesarcesar
Forum Contributor
Posts: 111
Joined: Mon Oct 18, 2004 3:28 pm

Download fails on files greater than 10M

Post by cesarcesar »

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: Select all

 
    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;
 
    }
 
nincha
Forum Contributor
Posts: 191
Joined: Fri Mar 28, 2003 12:30 pm
Location: CA, USA

Re: Download fails on files greater than 10M

Post by nincha »

Check your php.ini settings.
cesarcesar
Forum Contributor
Posts: 111
Joined: Mon Oct 18, 2004 3:28 pm

Re: Download fails on files greater than 10M

Post by cesarcesar »

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: Select all

    //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();
    }
 
cesarcesar
Forum Contributor
Posts: 111
Joined: Mon Oct 18, 2004 3:28 pm

Re: Download fails on files greater than 10M

Post by cesarcesar »

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?
Post Reply