0

i created a file with php that can stream a file in a server but the only problem i am having is the resume and i can download only with 1 parallel using IDM i have been searching for a week without finding any thing that helps this is my code

    <?php
$file = 'http://www.affymetrix.com/support/downloads/demo_data/Demo_Data_Barley_MAS5.zip';


function get_size($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HEADER, true);
    curl_setopt($ch, CURLOPT_NOBODY, true);
    curl_exec($ch);
    $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);
    return intval($size);
}


$fp = @fopen($file, 'rb');

$size   = get_size($file); // File size
$length = $size;           // Content length
$start  = 0;               // Start byte
$end    = $size - 1;       // End byte
header('Content-Type: application/octet-stream');
 header("Content-Disposition: attachment; filename=Demo_Data_Barley_MAS5.zip");
//header('Content-type: video/mp4');
header("Accept-Ranges: 0-$length");
if (isset($_SERVER['HTTP_RANGE'])) {

    $c_start = $start;
    $c_end   = $end;

    list(, $range) = explode('=', $_SERVER['HTTP_RANGE'], 2);
    if (strpos($range, ',') !== false) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    if ($range == '-') {
        $c_start = $size - substr($range, 1);
    }else{
        $range  = explode('-', $range);
        $c_start = $range[0];
        $c_end   = (isset($range[1]) && is_numeric($range[1])) ? $range[1] : $size;
    }
    $c_end = ($c_end > $end) ? $end : $c_end;
    if ($c_start > $c_end || $c_start > $size - 1 || $c_end >= $size) {
        header('HTTP/1.1 416 Requested Range Not Satisfiable');
        header("Content-Range: bytes $start-$end/$size");
        exit;
    }
    $start  = $c_start;
    $end    = $c_end;
    $length = $end - $start + 1;
    fseek($fp, $start);
    header('HTTP/1.1 206 Partial Content');
}
header("Content-Range: bytes $start-$end/$size");
header("Content-Length: ".$length);


$buffer = 1024 * 8;
while(!feof($fp) && ($p = ftell($fp)) <= $end) {

    if ($p + $buffer > $end) {
        $buffer = $end - $p + 1;
    }
    set_time_limit(0);
    echo fread($fp, $buffer);
    flush();
}

fclose($fp);
exit();
?>

i am really thank full if some one can help me out here

1 Answers1

0

Use following gist source code for this: https://gist.github.com/kijin/9735300 (im sorry for that linked gist source code annotated by Korean)

Translation of header:

supports:
 1. do not break filename when use UTF-8 filename.
 2. remove or replace if included unknown character by OS.
 3. Add Cache-Control, Expires header when you want to use cache.
 4. Fix the download error when use cache and IE <= 8.
 5. Support resume download (automatically detect Range header, auto generate Accept-Ranges header)
 6. Fix memory leak when download large file.
 7. Can limit download speed.

How to use: send_attachment('filename that provide to client', 'file path', [period of the caching], [speed limit]);

this example is download 'foo.jpg' from server to client named 'photo.jpg'
 send_attachment('photo.jpg', '/srv/www/files/uploads/foo.jpg')

Return: true when successfully sent else false.

Warning: 1. please execute 'exit' when end the transfer.
         2. don't ensure that php version is very low(< 5.1) or not UTF-8 environment.
         3. speed limitation is very dangerous when you using FastCGI/FPM. recommend to use web server's speed limitation.
         4. some android versions does not support UTF-8 encoding.

Note: I recommend to use X-Accel-Redirect(nginx) or X-Sendfile(apache) header when transfer a big file. If you transfer big file on the php interpreter, the php have many load and it works very inefficiently.

Add: here is the code that you want to do - https://gist.github.com/ssut/a3d97c7a35e5458687ed (note: I'm very poor in english, some translation is imprecise)

I tested this code on nginx + php 5.5(fpm) environment and this is test code: send_attachment('ubuntu.iso', 'http://ftp.daum.net/ubuntu-releases/trusty/ubuntu-14.04-server-amd64.iso');

IDM screenshot:

ssut
  • 431
  • 2
  • 8
  • Thank you so much, but do you have any other document that can clear more about what should i exactly use and thank you again :) – oussama benyaala Jul 07 '14 at 20:56
  • ok. so you want to send a linked file(line 2) to client and support resume download. right? – ssut Jul 08 '14 at 01:23
  • Yes that's what i want to do :) – oussama benyaala Jul 08 '14 at 01:54
  • Thank you so much you are a lifesaver, that's exactly what i am looking for, except i have done the same like you but all i get i white result that's what i have done $filename = 'ubuntu.iso'; $server_filename = 'http://ftp.daum.net/ubuntu-releases/trusty/ubuntu-14.04-server-amd64.iso'; function send_attachment($filename, $server_filename, $expires = 0, $speed_limit = 1024); { $remote = false; Here : 192.249.59.242/try/attachment.php but i get nothing – oussama benyaala Jul 08 '14 at 13:43
  • you need to call the function. its just a function of implementation. take a look: http://pastebin.com/tNV8VGFA and try again. – ssut Jul 08 '14 at 14:39
  • Thank you so much it is just the function it's working Great you did save me a lot of time thank you :D i wanted to vote up for you but i need 15 reputations Thank you So much. – oussama benyaala Jul 08 '14 at 14:48
  • @oussamabenyaala plz click the accpet button below the vote button. it is helpful for me! – ssut Jul 08 '14 at 14:56
  • Thank you i did click it and i will try to collect 15 reputations to add them too you did help me thank you so much:D – oussama benyaala Jul 08 '14 at 15:07