Browse Source

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

Andrew Dolgov 1 year ago
parent
commit
8b73bd28d8

+ 3 - 18
classes/handler/public.php

@@ -969,24 +969,9 @@ class Handler_Public extends Handler {
 
 			if (file_exists($filename)) {
 				header("Content-Disposition: inline; filename=\"$hash\"");
-				$mimetype = mime_content_type($filename);
-
-				/* See if we can use X-Sendfile */
-				$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);
-				}
+
+				send_local_file($filename);
+
 			} else {
 				header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
 				echo "File not found.";

+ 1 - 0
classes/pluginhost.php

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

+ 30 - 0
include/functions.php

@@ -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;
+		}
+	}
+

+ 1 - 5
plugins/af_zz_imgproxy/init.php

@@ -55,13 +55,9 @@ class Af_Zz_ImgProxy extends Plugin {
 		header("Content-Disposition: inline; filename=\"".basename($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";
-			header("Last-Modified: $stamp", true);
+			send_local_file($local_filename);
 
-			readfile($local_filename);
 		} else {
 			$data = fetch_file_contents(array("url" => $url));
 

+ 1 - 17
plugins/cache_starred_images/init.php

@@ -66,27 +66,11 @@ class Cache_Starred_Images extends Plugin implements IHandler {
 		if ($hash) {
 
 			$filename = $this->cache_dir . "/" . basename($hash);
-			$is_video = strpos($filename, ".mp4") !== FALSE;
 
 			if (file_exists($filename)) {
 				header("Content-Disposition: attachment; filename=\"$hash\"");
 
-				/* See if we can use X-Sendfile */
-				$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);
-				}
+				send_local_file($filename);
 			} else {
 				header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
 				echo "File not found.";