mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 04:22:07 +02:00
MDL-55445 files: Helper functions related to serving and caching
The function send_content_uncached() is meant to be used when serving content which should not be cached by browsers/proxies. You will use this in development mode, or when the request is malformed but you need to return some fallback content which shouldn't be stored under the URL it was requested from. The function file_safe_save_content() should only be used for content not stored in the file API. Good candidates for this are resource which fit well in the localcache. The function tries to write the content in the most atomic way as possible to prevent incomplete writes or concurrent writes.
This commit is contained in:
parent
0eb97bfa13
commit
19efee14e2
@ -2070,6 +2070,70 @@ function send_temp_file_finished($path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Serve content which is not meant to be cached.
|
||||
*
|
||||
* This is only intended to be used for volatile public files, for instance
|
||||
* when development is enabled, or when caching is not required on a public resource.
|
||||
*
|
||||
* @param string $content Raw content.
|
||||
* @param string $filename The file name.
|
||||
* @return void
|
||||
*/
|
||||
function send_content_uncached($content, $filename) {
|
||||
$mimetype = mimeinfo('type', $filename);
|
||||
$charset = strpos($mimetype, 'text/') === 0 ? '; charset=utf-8' : '';
|
||||
|
||||
header('Content-Disposition: inline; filename="' . $filename . '"');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT');
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2) . ' GMT');
|
||||
header('Pragma: ');
|
||||
header('Accept-Ranges: none');
|
||||
header('Content-Type: ' . $mimetype . $charset);
|
||||
header('Content-Length: ' . strlen($content));
|
||||
|
||||
echo $content;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely save content to a certain path.
|
||||
*
|
||||
* This function tries hard to be atomic by first copying the content
|
||||
* to a separate file, and then moving the file across. It also prevents
|
||||
* the user to abort a request to prevent half-safed files.
|
||||
*
|
||||
* This function is intended to be used when saving some content to cache like
|
||||
* $CFG->localcachedir. If you're not caching a file you should use the File API.
|
||||
*
|
||||
* @param string $content The file content.
|
||||
* @param string $destination The absolute path of the final file.
|
||||
* @return void
|
||||
*/
|
||||
function file_safe_save_content($content, $destination) {
|
||||
global $CFG;
|
||||
|
||||
clearstatcache();
|
||||
if (!file_exists(dirname($destination))) {
|
||||
@mkdir(dirname($destination), $CFG->directorypermissions, true);
|
||||
}
|
||||
|
||||
// Prevent serving of incomplete file from concurrent request,
|
||||
// the rename() should be more atomic than fwrite().
|
||||
ignore_user_abort(true);
|
||||
if ($fp = fopen($destination . '.tmp', 'xb')) {
|
||||
fwrite($fp, $content);
|
||||
fclose($fp);
|
||||
rename($destination . '.tmp', $destination);
|
||||
@chmod($destination, $CFG->filepermissions);
|
||||
@unlink($destination . '.tmp'); // Just in case anything fails.
|
||||
}
|
||||
ignore_user_abort(false);
|
||||
if (connection_aborted()) {
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the sending of file data to the user's browser, including support for
|
||||
* byteranges etc.
|
||||
|
Loading…
x
Reference in New Issue
Block a user