Jump to content

Download fails on files greater than 10M


cesarcesar

Recommended Posts

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.

 

    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;

    }

Link to comment
Share on other sites

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

 

replace the while() in my above 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();
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.