function loadfile ($filename, $speed=false) { // } $ filename - the address of the file that we are going to give.// time limit set_time_limit (0); // continue to run when the user is disconnected ignore_user_abort (true); // start buffering ob_start ();
// file size
$ filesize = filesize ($ filename);
// time of the last file change
$ filetime = gmdate ('r', filemtime ($ filename));
// generate etag
$ etag = md5 ($ filename. "=". $ filesize. "=". $ filetime);
$ etag = substr ($ etag, 0, 8) .'- '. substr ($ etag, 8, 7) .'-'. substr ($ etag, 15, 8);
// If they “ask” not to give the whole file, but only a part of it (resume), then so “answer”
if (isset ($ _ SERVER ['HTTP_RANGE'])) {
// divide the string $ _SERVER ['HTTP_RANGE'] into substrings to have
// idea of the necessary part of the file to the user
$ range = substr ($ _ SERVER ['HTTP_RANGE'], strpos ($ _ SERVER ['HTTP_RANGE'], '=') + 1);
$ from = (integer) (strtok ($ range, "-")); // from which byte to start the part
$ to = (integer) (strtok ("-")); // which byte to finish
// Give Headers
header ('HTTP / 1.1 206 Partial Content');
header ('Content-Range: bytes'. $ from .'-'. ($ to-1). '/'. $ filesize);
} else {
header ('HTTP / 1.1 200 Ok');
}
// If the client has not transmitted the information about the last byte, then assign
// independently.
if ($ to == 0) $ to = $ filesize;
if (empty ($ from)) $ from = 0;
function is_active_user ($ clear = false) {
global $ dbi; // this is a database connection
// check for connections from the user
$ result = mysql_query ("SELECT` session_ip` FROM `file_session` WHERE` session_ip` = '". $ _ SERVER [' REMOTE_ADDR ']."' LIMIT 1 ", $ dbi);
if (mysql_num_rows ($ result)) {
// if $ clear is set, then user
// broke the connection. Delete the record.
if (! $ clear) {
return true;
} else {
mysql_query ("DELETE FROM` file_session` WHERE session_ip = '". $ _ SERVER [' REMOTE_ADDR ']."' LIMIT 1 ", $ dbi);
}
} else {
// if there is no entry, then add
mysql_query ("INSERT INTO` file_session` VALUES ('". $ _ SERVER [' REMOTE_ADDR ']."') ", $ dbi);
return false;
}
}
// Give Headers
header ('ETag: "'. $ etag. '"');
header ('Accept-Ranges: bytes');
header ('Content-Length:'. ($ filesize- $ from));
header ('Content-Type: application / octet-stream');
header ('Last-Modified:'. gmdate ('r', filemtime ($ filename)));
header ('Content-Disposition: attachment; filename = "'. $ filename. '";');
// Check if the user has
// active streams is_active_user ()
// and whether it has disconnected connection_status ().
while (is_active_user () and! connection_status ()) {
// we sleep while the user has active threads
sleep (1);
}
// Open the file
$ f = fopen ($ filename, 'rb');
// Set the pointer to the desired position
fseek ($ f, $ from, SEEK_SET);
// Set the total volume of the part and declare a variable that stores the downloaded volume
$ size = $ to - $ from;
$ isready = 0;
// Getting Returns
while (! feof ($ f) and! connection_status () and ($ isready <$ size)) {
// If there are no restrictions, then we read 0.5 MB each and give it without delay.
// Is the limit set? We read and give exactly as much as set by the limit and fall asleep for 1 second.
echo fread ($ f,! $ speed? 512000: $ speed); // read and give
flush (); ob_flush (); // clear the buffer and output to the user
if ($ speed) sleep (1); // fall asleep
$ isready + =! $ speed? 512,000: $ speed; // update counter
}
// Close the file
fclose ($ f);
// Delete the connection information from the database
is_active_user (true);
loadfile ("/files/moifilm.avi", 10240); // Specify the speed in bytes.
Source: https://habr.com/ru/post/51442/
All Articles