Skip to content

Instantly share code, notes, and snippets.

@fzerorubigd
Created October 16, 2012 12:50
  • Star 25 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save fzerorubigd/3899077 to your computer and use it in GitHub Desktop.
A simple download script with resume and multi-part support
<?php
date_default_timezone_set('GMT');
//1- file we want to serve :
$data_file = "/home/f0rud/Aalto Talk with Linus Torvalds [Full-length].mp4";
$data_size = filesize($data_file); //Size is not zero base
$mime = 'application/otect-stream'; //Mime type of file. to begin download its better to use this.
$filename = basename($data_file); //Name of file, no path included
//2- Check for request, is the client support this method?
if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE'])) {
$ranges_str = (isset($_SERVER['HTTP_RANGE']))?$_SERVER['HTTP_RANGE']:$HTTP_SERVER_VARS['HTTP_RANGE'];
$ranges_arr = explode('-', substr($ranges_str, strlen('bytes=')));
//Now its time to check the ranges
if ((intval($ranges_arr[0]) >= intval($ranges_arr[1]) && $ranges_arr[1] != "" && $ranges_arr[0] != "" )
|| ($ranges_arr[1] == "" && $ranges_arr[0] == "")
) {
//Just serve the file normally request is not valid :(
$ranges_arr[0] = 0;
$ranges_arr[1] = $data_size - 1;
}
} else { //The client dose not request HTTP_RANGE so just use the entire file
$ranges_arr[0] = 0;
$ranges_arr[1] = $data_size - 1;
}
//Now its time to serve file
$file = fopen($data_file, 'rb');
$start = $stop = 0;
if ($ranges_arr[0] === "") { //No first range in array
//Last n1 byte
$stop = $data_size - 1;
$start = $data_size - intval($ranges_arr[1]);
} elseif ($ranges_arr[1] === "") { //No last
//first n0 byte
$start = intval($ranges_arr[0]);
$stop = $data_size - 1;
} else {
// n0 to n1
$stop = intval($ranges_arr[1]);
$start = intval($ranges_arr[0]);
}
//Make sure the range is correct by checking the file
fseek($file, $start, SEEK_SET);
$start = ftell($file);
fseek($file, $stop, SEEK_SET);
$stop = ftell($file);
$data_len = $stop - $start;
//Lets send headers
if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE'])) {
header('HTTP/1.0 206 Partial Content');
header('Status: 206 Partial Content');
}
header('Accept-Ranges: bytes');
header('Content-type: ' . $mime);
header('Content-Disposition: attachment; filename="' . $filename . '"');
header("Content-Range: bytes $start-$stop/" . $data_size );
header("Content-Length: " . ($data_len + 1));
//Finally serve data and done ~!
fseek($file, $start, SEEK_SET);
$bufsize = 2048000;
ignore_user_abort(true);
@set_time_limit(0);
while (!(connection_aborted() || connection_status() == 1) && $data_len > 0) {
echo fread($file, $bufsize);
$data_len -= $bufsize;
flush();
}
fclose($file);
@mojerf
Copy link

mojerf commented Feb 7, 2016

cant use to download from another host
why?
i have download host and i cant use this code
please help

@vsg24
Copy link

vsg24 commented Dec 6, 2016

Great script. Thanks.

@dausruddin
Copy link

Nice. Working great.

@jiaghara
Copy link

Brilliant Script Thanks....

i was searching last 3 days but not success.

you are my hero... thanks again.

please do same script for remote URL download with resume. example:- other video URL file via my site url.

@ProgrammerNomad
Copy link

working fine 👍

@Binaryhat
Copy link

Thank you so much... It worked!

@agh620
Copy link

agh620 commented Nov 5, 2017

can i use this for vinaget source?
https://github.com/giaythuytinh176/vinaget-script

@tumatanquang
Copy link

Hi,
$bufsize is what is this? And where is code limit the number of concurrent connections? And what is the code that determines download resume (support or not support download resume)?

@amoozesh98com
Copy link

Why does it stop working when the session starts?

@altugaykut
Copy link

For those who get invalid file format with this script, you should add ob_clean() in line66 after headers.

@antayirp
Copy link

antayirp commented May 7, 2019

Line 9: a typo "otect-stream", should be "octet-stream".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment