aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-07-01 23:28:51 +0200
committerGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2014-07-01 23:30:01 +0200
commit63c9c47a761b9925e6811ae630c3b77ef05b9fc8 (patch)
tree27831b2cdb270cbade11f5541968434e7d23dbba
parent09602acc5f754c3e814b4b7de9d9d4d283ed45ff (diff)
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.
-rwxr-xr-xapp/Controllers/feedController.php64
-rw-r--r--app/Models/Feed.php41
-rw-r--r--lib/SimplePie/SimplePie.php38
-rw-r--r--lib/SimplePie/SimplePie/File.php12
4 files changed, 97 insertions, 58 deletions
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('<' => '&lt;', '>' => '&gt;', '"' => '&quot;')); //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
@@ -446,6 +446,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()
* @access private
@@ -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 <itunes:new-feed-url> as well
+ * @todo Support <itunes:new-feed-url>
* @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']))
{