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/