From 17a603b333f305a5a9c8fdd36468575bc1cd8f74 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 17 May 2014 12:08:47 +0200 Subject: SimplePie patch accepted Merged into master branch of SimplePie https://github.com/simplepie/simplepie/pull/352 --- lib/SimplePie/SimplePie.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/SimplePie/SimplePie.php') diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index d7aaeb0c5..685fe1cc0 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -1331,7 +1331,7 @@ class SimplePie // First check to see if input has been overridden. if ($this->input_encoding !== false) { - $encodings[] = strtoupper($this->input_encoding); //FreshRSS + $encodings[] = strtoupper($this->input_encoding); } $application_types = array('application/xml', 'application/xml-dtd', 'application/xml-external-parsed-entity'); @@ -1355,7 +1355,7 @@ class SimplePie { if (isset($headers['content-type']) && preg_match('/;\x20?charset=([^;]*)/i', $headers['content-type'], $charset)) { - $encodings[] = strtoupper($charset[1]); //FreshRSS + $encodings[] = strtoupper($charset[1]); } else { -- cgit v1.2.3 From 63c9c47a761b9925e6811ae630c3b77ef05b9fc8 Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 1 Jul 2014 23:28:51 +0200 Subject: SimplePie HTTP 301 Moved Permanently Add support for HTTP 301 Moved Permanently in SimplePie FreshRSS will automatically update the address of a feed, only in this case. --- app/Controllers/feedController.php | 64 ++++++++++++++++++++------------------ app/Models/Feed.php | 41 ++++++++++++++---------- lib/SimplePie/SimplePie.php | 38 +++++++++++++++++----- lib/SimplePie/SimplePie/File.php | 12 +++++-- 4 files changed, 97 insertions(+), 58 deletions(-) (limited to 'lib/SimplePie/SimplePie.php') diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index fce008399..5f5a40bc7 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -162,38 +162,39 @@ class FreshRSS_feed_Controller extends Minz_ActionController { } Minz_Request::forward (array ('c' => 'configure', 'a' => 'feed', 'params' => $params), true); - } - - // GET request so we must ask confirmation to user - Minz_View::prependTitle(Minz_Translate::t('add_rss_feed') . ' · '); - $this->view->categories = $this->catDAO->listCategories(); - $this->view->feed = new FreshRSS_Feed($url); - try { - // We try to get some more information about the feed - $this->view->feed->load(true); - $this->view->load_ok = true; - } catch (Exception $e) { - $this->view->load_ok = false; - } + } else { - $feed = $feedDAO->searchByUrl($this->view->feed->url()); - if ($feed) { - // Already subscribe so we redirect to the feed configuration page - $notif = array( - 'type' => 'bad', - 'content' => Minz_Translate::t( - 'already_subscribed', $feed->name() - ) - ); - Minz_Session::_param('notification', $notif); + // GET request so we must ask confirmation to user + Minz_View::prependTitle(Minz_Translate::t('add_rss_feed') . ' · '); + $this->view->categories = $this->catDAO->listCategories(); + $this->view->feed = new FreshRSS_Feed($url); + try { + // We try to get some more information about the feed + $this->view->feed->load(true); + $this->view->load_ok = true; + } catch (Exception $e) { + $this->view->load_ok = false; + } - Minz_Request::forward(array( - 'c' => 'configure', - 'a' => 'feed', - 'params' => array( - 'id' => $feed->id() - ) - ), true); + $feed = $feedDAO->searchByUrl($this->view->feed->url()); + if ($feed) { + // Already subscribe so we redirect to the feed configuration page + $notif = array( + 'type' => 'bad', + 'content' => Minz_Translate::t( + 'already_subscribed', $feed->name() + ) + ); + Minz_Session::_param('notification', $notif); + + Minz_Request::forward(array( + 'c' => 'configure', + 'a' => 'feed', + 'params' => array( + 'id' => $feed->id() + ) + ), true); + } } } @@ -300,7 +301,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $feedDAO->commit(); } $flux_update++; - if ($feed->url() !== $url) { //URL has changed (auto-discovery) + if (($feed->url() !== $url)) { //HTTP 301 Moved Permanently + Minz_Log::record('Feed ' . $url . ' moved permanently to ' . $feed->url(), Minz_Log::NOTICE); $feedDAO->updateFeed($feed->id(), array('url' => $feed->url())); } } catch (FreshRSS_Feed_Exception $e) { diff --git a/app/Models/Feed.php b/app/Models/Feed.php index 757eacd59..14b52b143 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -17,6 +17,7 @@ class FreshRSS_Feed extends Minz_Model { private $error = false; private $keep_history = -2; private $hash = null; + private $lockPath = ''; public function __construct ($url, $validate=true) { if ($validate) { @@ -193,28 +194,35 @@ class FreshRSS_Feed extends Minz_Model { } $feed = customSimplePie(); $feed->set_feed_url ($url); + if (!$loadDetails) { //Only activates auto-discovery when adding a new feed + $feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE); + } $mtime = $feed->init(); if ((!$mtime) || $feed->error()) { throw new FreshRSS_Feed_Exception ($feed->error() . ' [' . $url . ']'); } - // si on a utilisé l'auto-discover, notre url va avoir changé - $subscribe_url = $feed->subscribe_url (); - if ($subscribe_url !== null && $subscribe_url !== $this->url) { - if ($this->httpAuth != '') { - // on enlève les id si authentification HTTP - $subscribe_url = preg_replace ('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url); - } - $this->_url ($subscribe_url); - } - if ($loadDetails) { + // si on a utilisé l'auto-discover, notre url va avoir changé + $subscribe_url = $feed->subscribe_url(false); + $title = strtr(html_only_entity_decode($feed->get_title()), array('<' => '<', '>' => '>', '"' => '"')); //HTML to HTML-PRE //ENT_COMPAT except & $this->_name ($title == '' ? $this->url : $title); $this->_website(html_only_entity_decode($feed->get_link())); $this->_description(html_only_entity_decode($feed->get_description())); + } else { + //The case of HTTP 301 Moved Permanently + $subscribe_url = $feed->subscribe_url(true); + } + + if ($subscribe_url !== null && $subscribe_url !== $this->url) { + if ($this->httpAuth != '') { + // on enlève les id si authentification HTTP + $subscribe_url = preg_replace ('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url); + } + $this->_url ($subscribe_url); } if (($mtime === true) || ($mtime > $this->lastUpdate)) { @@ -288,20 +296,19 @@ class FreshRSS_Feed extends Minz_Model { } function lock() { - $lock = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; - if (file_exists($lock) && ((time() - @filemtime($lock)) > 3600)) { - @unlink($lock); + $this->lockPath = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; + if (file_exists($this->lockPath) && ((time() - @filemtime($this->lockPath)) > 3600)) { + @unlink($this->lockPath); } - if (($handle = @fopen($lock, 'x')) === false) { + if (($handle = @fopen($this->lockPath, 'x')) === false) { return false; } - //register_shutdown_function('unlink', $lock); + //register_shutdown_function('unlink', $this->lockPath); @fclose($handle); return true; } function unlock() { - $lock = TMP_PATH . '/' . md5(Minz_Configuration::salt() . $this->url) . '.freshrss.lock'; - @unlink($lock); + @unlink($this->lockPath); } } diff --git a/lib/SimplePie/SimplePie.php b/lib/SimplePie/SimplePie.php index 685fe1cc0..06c100f59 100644 --- a/lib/SimplePie/SimplePie.php +++ b/lib/SimplePie/SimplePie.php @@ -445,6 +445,13 @@ class SimplePie */ public $feed_url; + /** + * @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently + * @see SimplePie::subscribe_url() + * @access private + */ + public $permanent_url = null; //FreshRSS + /** * @var object Instance of SimplePie_File to use as a feed * @see SimplePie::set_file() @@ -735,6 +742,7 @@ class SimplePie else { $this->feed_url = $this->registry->call('Misc', 'fix_protocol', array($url, 1)); + $this->permanent_url = $this->feed_url; //FreshRSS } } @@ -749,6 +757,7 @@ class SimplePie if ($file instanceof SimplePie_File) { $this->feed_url = $file->url; + $this->permanent_url = $this->feed_url; //FreshRSS $this->file =& $file; return true; } @@ -1602,7 +1611,7 @@ class SimplePie } $this->raw_data = $file->body; - + $this->permanent_url = $file->permanent_url; //FreshRSS $headers = $file->headers; $sniffer = $this->registry->create('Content_Type_Sniffer', array(&$file)); $sniffed = $sniffer->get_type(); @@ -1788,26 +1797,39 @@ class SimplePie /** * Get the URL for the feed + * + * When the 'permanent' mode is enabled, returns the original feed URL, + * except in the case of an `HTTP 301 Moved Permanently` status response, + * in which case the location of the first redirection is returned. * - * May or may not be different from the URL passed to {@see set_feed_url()}, + * When the 'permanent' mode is disabled (default), + * may or may not be different from the URL passed to {@see set_feed_url()}, * depending on whether auto-discovery was used. * * @since Preview Release (previously called `get_feed_url()` since SimplePie 0.8.) - * @todo If we have a perm redirect we should return the new URL - * @todo When we make the above change, let's support as well + * @todo Support * @todo Also, |atom:link|@rel=self + * @param bool $permanent Permanent mode to return only the original URL or the first redirection + * iff it is a 301 redirection * @return string|null */ - public function subscribe_url() + public function subscribe_url($permanent = false) { - if ($this->feed_url !== null) + if ($permanent) //FreshRSS { - return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); + if ($this->permanent_url !== null) + { + return $this->sanitize($this->permanent_url, SIMPLEPIE_CONSTRUCT_IRI); + } } else { - return null; + if ($this->feed_url !== null) + { + return $this->sanitize($this->feed_url, SIMPLEPIE_CONSTRUCT_IRI); + } } + return null; } /** diff --git a/lib/SimplePie/SimplePie/File.php b/lib/SimplePie/SimplePie/File.php index faf5dd1f1..b1bbe4420 100644 --- a/lib/SimplePie/SimplePie/File.php +++ b/lib/SimplePie/SimplePie/File.php @@ -64,6 +64,7 @@ class SimplePie_File var $redirects = 0; var $error; var $method = SIMPLEPIE_FILE_SOURCE_NONE; + var $permanent_url; //FreshRSS public function __construct($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false) { @@ -74,6 +75,7 @@ class SimplePie_File $url = SimplePie_Misc::compress_parse_url($parsed['scheme'], $idn->encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); } $this->url = $url; + $this->permanent_url = $url; //FreshRSS $this->useragent = $useragent; if (preg_match('/^http(s)?:\/\//i', $url)) { @@ -142,7 +144,10 @@ class SimplePie_File { $this->redirects++; $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); - return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + $previousStatusCode = $this->status_code; + $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + $this->permanent_url = ($previousStatusCode == 301) ? $location : $url; //FreshRSS + return; } } } @@ -224,7 +229,10 @@ class SimplePie_File { $this->redirects++; $location = SimplePie_Misc::absolutize_url($this->headers['location'], $url); - return $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + $previousStatusCode = $this->status_code; + $this->__construct($location, $timeout, $redirects, $headers, $useragent, $force_fsockopen); + $this->permanent_url = ($previousStatusCode == 301) ? $location : $url; //FreshRSS + return; } if (isset($this->headers['content-encoding'])) { -- cgit v1.2.3