Tycoon Talk
Become a Big fish!
The number 1 forum for online business!
Post topics, ask questions, share your knowledge.
Tycoon Talk is part of Freelancer.com - find skilled workers online at a fraction of the cost.

PHP Forum


You are currently viewing our PHP Forum as a guest. Please register to participate.
Login



Freelance Jobs

Reply
Download fails on files greater than 10M
Old 03-04-2008, 03:18 PM Download fails on files greater than 10M
Extreme Talker

Posts: 199
Trades: 0
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;

    }
empiresolutions is offline
Reply With Quote
View Public Profile
 
 
Register now for full access!
Old 03-04-2008, 04:01 PM Re: Download fails on files greater than 10M
tripy's Avatar
Do not try this at home!

Posts: 3,621
Name: Thierry
Location: I'm the uber Spaminator !
Trades: 0
What error do you have ?
__________________
Only a biker knows why a dog sticks his head out the window.
tripy is offline
Reply With Quote
View Public Profile Visit tripy's homepage!
 
Old 03-04-2008, 04:09 PM Re: Download fails on files greater than 10M
Extreme Talker

Posts: 199
Trades: 0
PHP Fatal error: Allowed memory size of 8388608
bytes exhausted (tried to allocate 11076561 bytes)
empiresolutions is offline
Reply With Quote
View Public Profile
 
Old 03-04-2008, 04:39 PM Re: Download fails on files greater than 10M
tripy's Avatar
Do not try this at home!

Posts: 3,621
Name: Thierry
Location: I'm the uber Spaminator !
Trades: 0
What I thought....

If your file is binary, there are many chances that the datas are stored on 1 big line.
You use fread, good. But you need to specify a "read up to" value below your max_memory threshold.
Right now, you ask it to get the whole file content in 1 operation.
PHP Code:
fread($fp,filesize($file)) 
You will need to split the processing in several parts.
Look at that comment for an example.
It should resolve your case.
PHP Code:
$total     filesize($file);
$sent      0;
$blocksize = (<< 20); //2M chunks
$handle    fopen($file"r");

while(
$sent $total){
    echo 
fread($handle$blocksize);
    
$sent += $blocksize;
}
            
exit(
0); 
And for those (like me) that didn't knew about the << operator, it's a "bitwise shift left".
http://www.php.net/manual/en/languag...rs.bitwise.php
Now, I need to understand what it does.....

Edit:
Ok, now, Wikipedia was really useful to understand it better. If any of you is interested:
http://en.wikipedia.org/wiki/Bitwise_operation
__________________
Only a biker knows why a dog sticks his head out the window.

Last edited by tripy; 03-04-2008 at 04:58 PM..
tripy is offline
Reply With Quote
View Public Profile Visit tripy's homepage!
 
Old 03-04-2008, 05:33 PM Re: Download fails on files greater than 10M
mgraphic's Avatar
Truth Seeker

Latest Blog Post:
JAMISONTUNES
Posts: 2,918
Name: Keith Marshall
Location: Connecticut
Trades: 0
These two lines might help in your htaccess file:

Code:
php_value post_max_size 110M
php_value upload_max_filesize 100M
__________________

<mgraphic /> - I don't have a solution but I admire the problem.
mgraphic is offline
Reply With Quote
View Public Profile
 
Old 03-04-2008, 05:45 PM Re: Download fails on files greater than 10M
tripy's Avatar
Do not try this at home!

Posts: 3,621
Name: Thierry
Location: I'm the uber Spaminator !
Trades: 0
Quote:
Originally Posted by mgraphic View Post
These two lines might help in your htaccess file:

Code:
php_value post_max_size 110M
php_value upload_max_filesize 100M
Nope, they will not.
He sends a file for download, he's not receiving an upload.

He should alter the max_memory value if he would to achieve this without modifying the script, but he might hit the wall again the day a file definitively bigger than the max_memory will be downloaded.
It can go up to crashing the server because all it's memory would be dispatched to the script.

That's why I explained why to fix it rather than how raising the max_memory limit.
__________________
Only a biker knows why a dog sticks his head out the window.
tripy is offline
Reply With Quote
View Public Profile Visit tripy's homepage!
 
Old 03-05-2008, 12:57 AM Re: Download fails on files greater than 10M
mtishetsky's Avatar
King Spam Talker

Posts: 1,226
Name: Mike
Location: Mataro, Spain
Trades: 0
Wtf. You never should send files through php fread(). Install some lightweight webserver like nginx or lighttpd to send large static files with conditions check.
__________________

Please login or register to view this content. Registration is FREE
-
Please login or register to view this content. Registration is FREE
-
Please login or register to view this content. Registration is FREE

And don't forget to give me talkupation!
mtishetsky is offline
Reply With Quote
View Public Profile Visit mtishetsky's homepage!
 
Old 03-05-2008, 04:30 AM Re: Download fails on files greater than 10M
Extreme Talker

Posts: 199
Trades: 0
Thanks Trippy, your solution worked.

Now it seem my fseek() is failing... actually $_SERVER['HTTP_RANGE'] is never being set. How do i get this to set?
empiresolutions is offline
Reply With Quote
View Public Profile
 
Old 03-05-2008, 04:44 AM Re: Download fails on files greater than 10M
tripy's Avatar
Do not try this at home!

Posts: 3,621
Name: Thierry
Location: I'm the uber Spaminator !
Trades: 0
Quote:
actually $_SERVER['HTTP_RANGE'] is never being set. How do i get this to set?
For that, I have no idea. Sorry.
PHP Code:
//seek to start of missing part
        
fseek($fp,$range); 
it's because you don't set any $range value in your else.
Set it to 0 (I guess) and try again.
__________________
Only a biker knows why a dog sticks his head out the window.
tripy is offline
Reply With Quote
View Public Profile Visit tripy's homepage!
 
Old 03-10-2008, 12:57 AM Re: Download fails on files greater than 10M
Extreme Talker

Posts: 199
Trades: 0
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?
empiresolutions is offline
Reply With Quote
View Public Profile
 
Old 03-10-2008, 07:31 AM Re: Download fails on files greater than 10M
tripy's Avatar
Do not try this at home!

Posts: 3,621
Name: Thierry
Location: I'm the uber Spaminator !
Trades: 0
hmm, don't know, as we don't see your page code.
But, did you tried to redirect after the end of the download() function ?
PHP Code:
header("location: /sompage.html");
die(); 
__________________
Only a biker knows why a dog sticks his head out the window.
tripy is offline
Reply With Quote
View Public Profile Visit tripy's homepage!
 
Old 03-11-2008, 04:06 AM Re: Download fails on files greater than 10M
Extreme Talker

Posts: 199
Trades: 0
This is my function so far. I still haven't gotten the header() at the end to work, or the resume on fail feature. Still working on it.
PHP Code:
function download() {

    global 
$_GET,$_SERVER;

    require 
'../db/db.inc';
    
$connection mysql_connect($hostname,$username,$password);
    if (!(
$connection)) die ("can not connect");
    
mysql_select_db($databasename,$connection);

    
/*   update download count for file. update who downloaded - 3/1/2008 */
    
$query_update "UPDATE datalog SET timesdownloaded = timesdownloaded + 1 WHERE dataid = '".$_GET['id']."'";
    
mysql_query($query_update,$connection);

    
/*   update download count for file. update who downloaded - 3/1/2008 */
    
$query_update "INSERT INTO download_log (universalid,dataid,status) VALUES ('".$_SERVER['HTTP_SM_UNIVERSALID']."','".$_GET['id']."','1')";
    
mysql_query($query_update,$connection);

    
//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'$filenamesubstr_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);

    
//reset time limit for big files
    
set_time_limit(0);

    
//start buffered download
    
while(!feof($fp)){

        
$total     filesize($file);
        
$sent      0;
        
$blocksize = (<< 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;
        }

        @
flush();
        @
ob_flush();
    }

    
fclose($fp);

header("location: /welcome.php");



Last edited by empiresolutions; 03-11-2008 at 04:08 AM..
empiresolutions is offline
Reply With Quote
View Public Profile
 
Old 03-13-2008, 09:06 AM Re: Download fails on files greater than 10M
amw_drizz's Avatar
Ultra Talker

Posts: 340
Name: Jon
Location: New York
Trades: 0
the header wont work if there is out put to the browser before it. so if there is no output it will work
__________________
AMW_Drizz
Dev Machine:: Apache 2.2.6 PHP 5.2.6 MySQL 5.1
amw_drizz is offline
Reply With Quote
View Public Profile Visit amw_drizz's homepage!
 
Reply     « Reply to Download fails on files greater than 10M
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off





   
RSS Feed  Feeds: RSS   JS   XML
RSS Feed  Feeds for this forum: RSS   JS   XML



Page generated in 0.41757 seconds with 12 queries