Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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);
@MER2000

This comment has been minimized.

Copy link

@MER2000 MER2000 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

This comment has been minimized.

Copy link

@VSG24 VSG24 commented Dec 6, 2016

Great script. Thanks.

@dausruddin

This comment has been minimized.

Copy link

@dausruddin dausruddin commented Dec 16, 2016

Nice. Working great.

@jiaghara

This comment has been minimized.

Copy link

@jiaghara jiaghara commented Dec 29, 2016

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.

@shivsingh7150

This comment has been minimized.

Copy link

@shivsingh7150 shivsingh7150 commented Apr 18, 2017

working fine 👍

@Binaryhat

This comment has been minimized.

Copy link

@Binaryhat Binaryhat commented Jul 12, 2017

Thank you so much... It worked!

@agh620

This comment has been minimized.

Copy link

@agh620 agh620 commented Nov 5, 2017

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

@tumatanquang

This comment has been minimized.

Copy link

@tumatanquang tumatanquang commented May 2, 2018

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

This comment has been minimized.

Copy link

@amoozesh98com amoozesh98com commented Aug 28, 2018

Why does it stop working when the session starts?

@altugaykut

This comment has been minimized.

Copy link

@altugaykut altugaykut commented Jan 9, 2019

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

@antayirp

This comment has been minimized.

Copy link

@antayirp 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
You can’t perform that action at this time.