mirror of
https://github.com/moodle/moodle.git
synced 2025-04-22 17:02:03 +02:00
MDL-38194 Files: Allow download of large backup files
The PHP readfile function does not work for files more than 2GB. This commit provides a wrapper that can be used so that files less than 2GB are sent with readfile, and files larger than 2GB are sent manually. The change applies to all uses of pluginfile.php, although in reality, backup files are probably the only ones likely to be more than two gigabytes.
This commit is contained in:
parent
83f26f6407
commit
137885b7e9
@ -1959,6 +1959,43 @@ function send_header_404() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The readfile function can fail when files are larger than 2GB (even on 64-bit
|
||||
* platforms). This wrapper uses readfile for small files and custom code for
|
||||
* large ones.
|
||||
*
|
||||
* @param string $path Path to file
|
||||
* @param int $filesize Size of file (if left out, will get it automatically)
|
||||
* @return int|bool Size read (will always be $filesize) or false if failed
|
||||
*/
|
||||
function readfile_allow_large($path, $filesize = -1) {
|
||||
// Automatically get size if not specified.
|
||||
if ($filesize === -1) {
|
||||
$filesize = filesize($path);
|
||||
}
|
||||
if ($filesize <= 2147483647) {
|
||||
// If the file is up to 2^31 - 1, send it normally using readfile.
|
||||
return readfile($path);
|
||||
} else {
|
||||
// For large files, read and output in 64KB chunks.
|
||||
$handle = fopen($path, 'r');
|
||||
if ($handle === false) {
|
||||
return false;
|
||||
}
|
||||
$left = $filesize;
|
||||
while ($left > 0) {
|
||||
$size = min($left, 65536);
|
||||
$buffer = fread($handle, $size);
|
||||
if ($buffer === false) {
|
||||
return false;
|
||||
}
|
||||
echo $buffer;
|
||||
$left -= $size;
|
||||
}
|
||||
return $filesize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced readfile() with optional acceleration.
|
||||
* @param string|stored_file $file
|
||||
@ -2081,7 +2118,7 @@ function readfile_accel($file, $mimetype, $accelerate) {
|
||||
if (is_object($file)) {
|
||||
$file->readfile();
|
||||
} else {
|
||||
readfile($file);
|
||||
readfile_allow_large($file, $filesize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -409,7 +409,7 @@ class stored_file {
|
||||
throw new file_exception('storedfilecannotread', '', $path);
|
||||
}
|
||||
}
|
||||
readfile($path);
|
||||
readfile_allow_large($path, $this->get_filesize());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@ information provided here is intended especially for developers.
|
||||
get_fast_modinfo(). Purging all caches and every core upgrade purges course modinfo cache as well.
|
||||
If function get_fast_modinfo() is called for multiple courses make sure to include field cacherev in course
|
||||
object.
|
||||
* New function readfile_allow_large() in filelib.php for use when very large files may need sending to user.
|
||||
|
||||
DEPRECATIONS:
|
||||
Various previously deprecated functions have now been altered to throw DEBUG_DEVELOPER debugging notices
|
||||
|
Loading…
x
Reference in New Issue
Block a user