diff options
author | Andrew Dolgov <[email protected]> | 2019-08-14 08:25:09 +0300 |
---|---|---|
committer | Andrew Dolgov <[email protected]> | 2019-08-14 08:25:09 +0300 |
commit | 65450f8a2bbf325d26177c2589c3a9bbe67d8f80 (patch) | |
tree | 932b65b145294955ac4628cd9b0536c83c392ce6 /classes | |
parent | b0fbae938dbc7c66c7829a86f7dd0fe6fb689908 (diff) | |
parent | fdb6066bf67751ebb388a3de082d80f5444e3681 (diff) |
Merge branch 'master' of git.tt-rss.org:fox/tt-rss
Diffstat (limited to 'classes')
-rwxr-xr-x | classes/api.php | 4 | ||||
-rwxr-xr-x | classes/article.php | 4 | ||||
-rw-r--r-- | classes/diskcache.php | 149 | ||||
-rwxr-xr-x | classes/feeds.php | 2 | ||||
-rwxr-xr-x | classes/handler/public.php | 29 | ||||
-rwxr-xr-x | classes/pluginhost.php | 4 | ||||
-rwxr-xr-x | classes/rssutils.php | 31 |
7 files changed, 174 insertions, 49 deletions
diff --git a/classes/api.php b/classes/api.php index e505dcc91..45e4d3062 100755 --- a/classes/api.php +++ b/classes/api.php @@ -379,7 +379,7 @@ class API extends Handler { $article = $p->hook_render_article_api(array("article" => $article)); } - $article['content'] = rewrite_cached_urls($article['content']); + $article['content'] = DiskCache::rewriteUrls($article['content']); array_push($articles, $article); @@ -801,7 +801,7 @@ class API extends Handler { $headline_row = $p->hook_render_article_api(array("headline" => $headline_row)); } - $headline_row['content'] = rewrite_cached_urls($headline_row['content']); + $headline_row['content'] = DiskCache::rewriteUrls($headline_row['content']); array_push($headlines, $headline_row); } diff --git a/classes/article.php b/classes/article.php index 43b25f94f..62ea1f3b9 100755 --- a/classes/article.php +++ b/classes/article.php @@ -446,7 +446,7 @@ class Article extends Handler_Protected { foreach ($result as $line) { foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_ENCLOSURE_ENTRY) as $plugin) { - $line = $plugin->hook_enclosure_entry($line); + $line = $plugin->hook_enclosure_entry($line, $id); } $url = $line["content_url"]; @@ -676,7 +676,7 @@ class Article extends Handler_Protected { while ($line = $sth->fetch()) { if (file_exists(CACHE_DIR . '/images/' . sha1($line["content_url"]))) { - $line["content_url"] = get_self_url_prefix() . '/public.php?op=cached_url&hash=' . sha1($line["content_url"]); + $line["content_url"] = DiskCache::getUrl(sha1($line["content_url"])); } array_push($rv, $line); diff --git a/classes/diskcache.php b/classes/diskcache.php new file mode 100644 index 000000000..41609d6b5 --- /dev/null +++ b/classes/diskcache.php @@ -0,0 +1,149 @@ +<?php +class DiskCache { + private $dir; + + public function __construct($dir) { + $this->dir = CACHE_DIR . "/" . basename($dir); + } + + public function getDir() { + return $this->dir; + } + + public function makeDir() { + if (!is_dir($this->dir)) { + return mkdir($this->dir); + } + } + + public function isWritable($filename = "") { + if ($filename) { + if (file_exists($this->getFullPath($filename))) + return is_writable($this->getFullPath($filename)); + else + return is_writable($this->dir); + } else { + return is_writable($this->dir); + } + } + + public function exists($filename) { + return file_exists($this->getFullPath($filename)); + } + + public function getSize($filename) { + if ($this->exists($filename)) + return filesize($this->getFullPath($filename)); + else + return -1; + } + + public function getFullPath($filename) { + $filename = basename($filename); + + return $this->dir . "/" . $filename; + } + + public function put($filename, $data) { + return file_put_contents($this->getFullPath($filename), $data); + } + + public function touch($filename) { + return touch($this->getFullPath($filename)); + } + + public function get($filename) { + if ($this->exists($filename)) + return file_get_contents($this->getFullPath($filename)); + else + return null; + } + + public function getMimeType($filename) { + if ($this->exists($filename)) + return mime_content_type($this->getFullPath($filename)); + else + return null; + } + + public function send($filename) { + header("Content-Disposition: inline; filename=\"$filename\""); + + return send_local_file($this->getFullPath($filename)); + } + + static public function getUrl($filename) { + return get_self_url_prefix() . "/public.php?op=cached_url&file=" . $filename; + } + + // check for locally cached (media) URLs and rewrite to local versions + // this is called separately after sanitize() and plugin render article hooks to allow + // plugins work on original source URLs used before caching + static public function rewriteUrls($str) + { + $res = trim($str); + if (!$res) return ''; + + $doc = new DOMDocument(); + if ($doc->loadHTML('<?xml encoding="UTF-8">' . $res)) { + $xpath = new DOMXPath($doc); + $cache = new DiskCache("images"); + + $entries = $xpath->query('(//img[@src]|//picture/source[@src]|//video[@poster]|//video/source[@src]|//audio/source[@src])'); + + $need_saving = false; + + foreach ($entries as $entry) { + + if ($entry->hasAttribute('src') || $entry->hasAttribute('poster')) { + + // should be already absolutized because this is called after sanitize() + $src = $entry->hasAttribute('poster') ? $entry->getAttribute('poster') : $entry->getAttribute('src'); + $cached_filename = sha1($src); + + if ($cache->getSize($cached_filename) > 0) { + + $src = DiskCache::getUrl(sha1($src)); + + if ($entry->hasAttribute('poster')) + $entry->setAttribute('poster', $src); + else + $entry->setAttribute('src', $src); + + $need_saving = true; + } + } + } + + if ($need_saving) { + $doc->removeChild($doc->firstChild); //remove doctype + $res = $doc->saveHTML(); + } + } + return $res; + } + + static function expire() { + $dirs = array_filter(glob(CACHE_DIR . "/*"), "is_dir"); + + foreach ($dirs as $cache_dir) { + $num_deleted = 0; + + if (is_writable($cache_dir) && !file_exists("$cache_dir/.no-auto-expiry")) { + $files = glob("$cache_dir/*"); + + if ($files) { + foreach ($files as $file) { + if (time() - filemtime($file) > 86400*CACHE_MAX_DAYS) { + unlink($file); + + ++$num_deleted; + } + } + } + + Debug::log("Expired $cache_dir: removed $num_deleted files."); + } + } + } +} diff --git a/classes/feeds.php b/classes/feeds.php index c1f973830..b89f4e4ca 100755 --- a/classes/feeds.php +++ b/classes/feeds.php @@ -307,7 +307,7 @@ class Feeds extends Handler_Protected { $line = $p->hook_render_article_cdm($line); } - $line['content'] = rewrite_cached_urls($line['content']); + $line['content'] = DiskCache::rewriteUrls($line['content']); if ($line['note']) $line['note'] = Article::format_article_note($id, $line['note']); diff --git a/classes/handler/public.php b/classes/handler/public.php index 0e990bec7..901844e36 100755 --- a/classes/handler/public.php +++ b/classes/handler/public.php @@ -382,7 +382,7 @@ class Handler_Public extends Handler { $line = $p->hook_render_article($line); } - $line['content'] = rewrite_cached_urls($line['content']); + $line['content'] = DiskCache::rewriteUrls($line['content']); $enclosures = Article::get_article_enclosures($line["id"]); @@ -1202,24 +1202,21 @@ class Handler_Public extends Handler { } function cached_url() { - @$req_filename = basename($_GET['hash']); + $filename = $_GET['file']; - // we don't need an extension to find the file, hash is a complete URL - $hash = preg_replace("/\.[^\.]*$/", "", $req_filename); - - if ($hash) { - - $filename = CACHE_DIR . '/images/' . $hash; - - if (file_exists($filename)) { - header("Content-Disposition: inline; filename=\"$req_filename\""); + if (strpos($filename, "/") !== FALSE) { + list ($cache_dir, $filename) = explode("/", $filename, 2); + } else { + $cache_dir = "images"; + } - send_local_file($filename); + $cache = new DiskCache($cache_dir); - } else { - header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); - echo "File not found."; - } + if ($cache->exists($filename)) { + $cache->send($filename); + } else { + header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found"); + echo "File not found."; } } diff --git a/classes/pluginhost.php b/classes/pluginhost.php index a3c12ecae..001d5bae2 100755 --- a/classes/pluginhost.php +++ b/classes/pluginhost.php @@ -470,4 +470,8 @@ class PluginHost { function get_filter_actions() { return $this->plugin_actions; } + + function get_owner_uid() { + return $this->owner_uid; + } } diff --git a/classes/rssutils.php b/classes/rssutils.php index 4c8da4546..6ba5eaa0b 100755 --- a/classes/rssutils.php +++ b/classes/rssutils.php @@ -871,7 +871,7 @@ class RSSUtils { $entry_ref_id = $ref_id; if (RSSUtils::find_article_filter($article_filters, "filter")) { - Debug::log("article is filtered out, nothing to do."); + Debug::log("article is filtered out, nothing to do.", Debug::$LOG_VERBOSE); $pdo->commit(); continue; } @@ -1284,32 +1284,6 @@ class RSSUtils { Debug::log("Removed $num_deleted old lock files."); } - static function expire_cached_files() { - foreach (array("feeds", "images", "export", "upload") as $dir) { - $cache_dir = CACHE_DIR . "/$dir"; - - Debug::log("Expiring $cache_dir", Debug::$LOG_VERBOSE); - - $num_deleted = 0; - - if (is_writable($cache_dir)) { - $files = glob("$cache_dir/*"); - - if ($files) { - foreach ($files as $file) { - if (time() - filemtime($file) > 86400*CACHE_MAX_DAYS) { - unlink($file); - - ++$num_deleted; - } - } - } - } - - Debug::log("$cache_dir: removed $num_deleted files."); - } - } - /** * Source: http://www.php.net/manual/en/function.parse-url.php#104527 * Returns the url query as associative array @@ -1498,7 +1472,8 @@ class RSSUtils { } static function housekeeping_common() { - RSSUtils::expire_cached_files(); + DiskCache::expire(); + RSSUtils::expire_lock_files(); RSSUtils::expire_error_log(); RSSUtils::expire_feed_archive(); |