remove apache-specific x-sendfile stuff

implement a hook (HOOK_SEND_LOCAL_FILE) which plugins may use to send files
via httpd-specific implementation to increase performance typically on larger files
This commit is contained in:
Andrew Dolgov 2017-10-08 17:10:05 +03:00
parent 852496fa15
commit 8b73bd28d8
5 changed files with 34 additions and 38 deletions

View File

@ -969,24 +969,9 @@ class Handler_Public extends Handler {
if (file_exists($filename)) { if (file_exists($filename)) {
header("Content-Disposition: inline; filename=\"$hash\""); header("Content-Disposition: inline; filename=\"$hash\"");
$mimetype = mime_content_type($filename);
/* See if we can use X-Sendfile */ send_local_file($filename);
$xsendfile = false;
if (function_exists('apache_get_modules') &&
array_search('mod_xsendfile', apache_get_modules()))
$xsendfile = true;
if ($xsendfile) {
header("X-Sendfile: $filename");
header("Content-type: $mimetype");
header('Content-Disposition: inline; filename="' . basename($filename) . '"');
} else {
header("Content-type: $mimetype");
$stamp = gmdate("D, d M Y H:i:s", filemtime($filename)). " GMT";
header("Last-Modified: $stamp", true);
readfile($filename);
}
} else { } else {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
echo "File not found."; echo "File not found.";

View File

@ -55,6 +55,7 @@ class PluginHost {
const HOOK_FORMAT_ARTICLE = 34; const HOOK_FORMAT_ARTICLE = 34;
const HOOK_FORMAT_ARTICLE_CDM = 35; const HOOK_FORMAT_ARTICLE_CDM = 35;
const HOOK_FEED_BASIC_INFO = 36; const HOOK_FEED_BASIC_INFO = 36;
const HOOK_SEND_LOCAL_FILE = 37;
const KIND_ALL = 1; const KIND_ALL = 1;
const KIND_SYSTEM = 2; const KIND_SYSTEM = 2;

View File

@ -2514,3 +2514,33 @@
} }
} }
/* this is essentially a wrapper for readfile() which allows plugins to hook
output with httpd-specific "fast" implementation i.e. X-Sendfile or whatever else
hook function should return true if request was handled (or at least attempted to)
note that this can be called without user context so the plugin to handle this
should be loaded systemwide in config.php */
function send_local_file($filename) {
if (file_exists($filename)) {
$tmppluginhost = new PluginHost();
$tmppluginhost->load(PLUGINS, PluginHost::KIND_SYSTEM);
$tmppluginhost->load_data();
foreach ($tmppluginhost->get_hooks(PluginHost::HOOK_SEND_LOCAL_FILE) as $plugin) {
if ($plugin->hook_send_local_file($filename)) return true;
}
$mimetype = mime_content_type($filename);
header("Content-type: $mimetype");
$stamp = gmdate("D, d M Y H:i:s", filemtime($filename)) . " GMT";
header("Last-Modified: $stamp", true);
return readfile($filename);
} else {
return false;
}
}

View File

@ -55,13 +55,9 @@ class Af_Zz_ImgProxy extends Plugin {
header("Content-Disposition: inline; filename=\"".basename($local_filename)."\""); header("Content-Disposition: inline; filename=\"".basename($local_filename)."\"");
if (file_exists($local_filename)) { if (file_exists($local_filename)) {
$mimetype = mime_content_type($local_filename);
header("Content-type: $mimetype");
$stamp = gmdate("D, d M Y H:i:s", filemtime($local_filename)). " GMT"; send_local_file($local_filename);
header("Last-Modified: $stamp", true);
readfile($local_filename);
} else { } else {
$data = fetch_file_contents(array("url" => $url)); $data = fetch_file_contents(array("url" => $url));

View File

@ -66,27 +66,11 @@ class Cache_Starred_Images extends Plugin implements IHandler {
if ($hash) { if ($hash) {
$filename = $this->cache_dir . "/" . basename($hash); $filename = $this->cache_dir . "/" . basename($hash);
$is_video = strpos($filename, ".mp4") !== FALSE;
if (file_exists($filename)) { if (file_exists($filename)) {
header("Content-Disposition: attachment; filename=\"$hash\""); header("Content-Disposition: attachment; filename=\"$hash\"");
/* See if we can use X-Sendfile */ send_local_file($filename);
$xsendfile = false;
if (function_exists('apache_get_modules') &&
array_search('mod_xsendfile', apache_get_modules()))
$xsendfile = true;
if ($xsendfile) {
header("X-Sendfile: $filename");
header("Content-type: application/octet-stream");
header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
} else {
header("Content-type: " . ($is_video ? "video/mp4" : "image/png"));
$stamp = gmdate("D, d M Y H:i:s", filemtime($filename)). " GMT";
header("Last-Modified: $stamp", true);
readfile($filename);
}
} else { } else {
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
echo "File not found."; echo "File not found.";