aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xapp/Controllers/feedController.php41
-rw-r--r--app/Models/Feed.php4
-rw-r--r--p/api/pshb.php36
3 files changed, 55 insertions, 26 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index 075ecb5e6..2aae5a0a8 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -393,12 +393,14 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
}
/**
+ * @param \SimplePie\SimplePie|null $simplePiePush Used by WebSub (PubSubHubbub) to push updates
+ * @param string $selfUrl Used by WebSub (PubSubHubbub) to override the feed URL
* @return array{0:int,1:FreshRSS_Feed|null,2:int,3:array<FreshRSS_Feed>} Number of updated feeds, first feed or null, number of new articles,
* list of feeds for which a cache refresh is needed
* @throws FreshRSS_BadUrl_Exception
*/
public static function actualizeFeeds(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null,
- ?\SimplePie\SimplePie $simplePiePush = null): array {
+ ?\SimplePie\SimplePie $simplePiePush = null, string $selfUrl = ''): array {
if (function_exists('set_time_limit')) {
@set_time_limit(300);
}
@@ -422,6 +424,9 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
if ($feed_id !== null || $feed_url !== null) {
$feed = $feed_id !== null ? $feedDAO->searchById($feed_id) : $feedDAO->searchByUrl($feed_url);
if ($feed !== null && $feed->id() > 0) {
+ if ($selfUrl !== '') {
+ $feed->_selfUrl($selfUrl);
+ }
$feeds[] = $feed;
$feed_id = $feed->id();
}
@@ -692,22 +697,19 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
$feedProperties['attributes'] = $feed->attributes();
}
- if ($pubsubhubbubEnabledGeneral && $feed->hubUrl() !== '' && $feed->selfUrl() !== '') { //selfUrl has priority for WebSub
- if ($feed->selfUrl() !== $url) { // https://github.com/pubsubhubbub/PubSubHubbub/wiki/Moving-Feeds-or-changing-Hubs
- $selfUrl = checkUrl($feed->selfUrl());
- if ($selfUrl != false) {
- Minz_Log::debug('WebSub unsubscribe ' . $feed->url(false));
- if (!$feed->pubSubHubbubSubscribe(false)) { //Unsubscribe
- Minz_Log::warning('Error while WebSub unsubscribing from ' . $feed->url(false));
- }
- $feed->_url($selfUrl, false);
- Minz_Log::notice('Feed ' . $url . ' canonical address moved to ' . $feed->url(false));
- $feedDAO->updateFeed($feed->id(), ['url' => $feed->url()]);
- }
+ if ($feed->url() !== $url) { // HTTP 301 Moved Permanently
+ Minz_Log::warning('Feed ' . \SimplePie\Misc::url_remove_credentials($url) .
+ ' moved permanently to ' . $feed->url(includeCredentials: false));
+ $feedProperties['url'] = $feed->url();
+ } elseif ($simplePiePush !== null && $selfUrl !== '' && $selfUrl !== $feed->url()) { // selfUrl has priority for WebSub
+ // https://github.com/pubsubhubbub/PubSubHubbub/wiki/Moving-Feeds-or-changing-Hubs
+ Minz_Log::debug('WebSub unsubscribe ' . $feed->url(includeCredentials: false));
+ if (!$feed->pubSubHubbubSubscribe(false)) { //Unsubscribe
+ Minz_Log::warning('Error while WebSub unsubscribing from ' . $feed->url(includeCredentials: false));
}
- } elseif ($feed->url() !== $url) { // HTTP 301 Moved Permanently
- Minz_Log::notice('Feed ' . \SimplePie\Misc::url_remove_credentials($url) .
- ' moved permanently to ' . \SimplePie\Misc::url_remove_credentials($feed->url(false)));
+ $feed->_url($selfUrl);
+ Minz_Log::warning('Feed ' . \SimplePie\Misc::url_remove_credentials($url) .
+ ' canonical address moved to ' . $feed->url(includeCredentials: false));
$feedProperties['url'] = $feed->url();
}
@@ -826,14 +828,17 @@ class FreshRSS_feed_Controller extends FreshRSS_ActionController {
}
/**
+ * @param \SimplePie\SimplePie|null $simplePiePush Used by WebSub (PubSubHubbub) to push updates
+ * @param string $selfUrl Used by WebSub (PubSubHubbub) to override the feed URL
* @return array{0:int,1:FreshRSS_Feed|null,2:int,3:array<FreshRSS_Feed>} Number of updated feeds, first feed or null, number of new articles,
* list of feeds for which a cache refresh is needed
* @throws FreshRSS_BadUrl_Exception
*/
public static function actualizeFeedsAndCommit(?int $feed_id = null, ?string $feed_url = null, ?int $maxFeeds = null,
- ?SimplePie\SimplePie $simplePiePush = null): array {
+ ?SimplePie\SimplePie $simplePiePush = null, string $selfUrl = ''): array {
$entryDAO = FreshRSS_Factory::createEntryDao();
- [$nbUpdatedFeeds, $feed, $nbNewArticles, $feedsCacheToRefresh] = FreshRSS_feed_Controller::actualizeFeeds($feed_id, $feed_url, $maxFeeds, $simplePiePush);
+ [$nbUpdatedFeeds, $feed, $nbNewArticles, $feedsCacheToRefresh] =
+ FreshRSS_feed_Controller::actualizeFeeds($feed_id, $feed_url, $maxFeeds, $simplePiePush, $selfUrl);
if ($nbNewArticles > 0) {
$entryDAO->beginTransaction();
FreshRSS_feed_Controller::commitNewEntries();
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index b91d1af75..171b054ca 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -463,6 +463,10 @@ class FreshRSS_Feed extends Minz_Model {
$this->url = $url;
}
+ public function _selfUrl(string $value): void {
+ $this->selfUrl = $value;
+ }
+
public function _kind(int $value): void {
$this->kind = $value;
}
diff --git a/p/api/pshb.php b/p/api/pshb.php
index 6b5bda4b5..91dd4e901 100644
--- a/p/api/pshb.php
+++ b/p/api/pshb.php
@@ -104,13 +104,33 @@ $simplePie->init();
unset($ORIGINAL_INPUT);
$links = $simplePie->get_links('self');
-$self = $links[0] ?? null;
+$self = $links[0] ?? '';
+
+// Support HTTP header `Link: <http://example.net/hub.php>; rel="hub", <http://example.net/feed.php>; rel="self"`
+$httpLink = is_string($_SERVER['HTTP_LINK'] ?? null) ? $_SERVER['HTTP_LINK'] : '';
+if ($httpLink !== '' && preg_match_all('/<([^>]+)>;\\s*rel="([^"]+)"/', $httpLink, $matches, PREG_SET_ORDER)) {
+ $links = [];
+ foreach ($matches as $match) {
+ if (!empty($match[1]) && !empty($match[2])) {
+ $links[$match[2]] = $match[1];
+ }
+ }
+ // if (!empty($links['hub'])) {
+ // // TODO: Support WebSub hub redirection
+ // }
+ if (!empty($links['self'])) {
+ $httpSelf = checkUrl($links['self']) ?: '';
+ if ($self !== '' && $self !== $httpSelf) {
+ Minz_Log::warning('Warning: Self URL mismatch between XML [' . $self . '] and HTTP!: ' . $httpSelf, PSHB_LOG);
+ }
+ $self = $httpSelf;
+ }
+}
if ($self !== $canonical) {
//header('HTTP/1.1 422 Unprocessable Entity');
Minz_Log::warning('Warning: Self URL [' . $self . '] does not match registered canonical URL!: ' . $canonical, PSHB_LOG);
//die('Self URL does not match registered canonical URL!');
- $self = $canonical;
}
Minz_ExtensionManager::init();
@@ -120,7 +140,7 @@ $nb = 0;
foreach ($users as $userFilename) {
$username = basename($userFilename, '.txt');
if (!file_exists(USERS_PATH . '/' . $username . '/config.php')) {
- Minz_Log::warning('Warning: Removing broken user link: ' . $username . ' for ' . $self, PSHB_LOG);
+ Minz_Log::warning('Warning: Removing broken user link: ' . $username . ' for ' . $canonical, PSHB_LOG);
unlink($userFilename);
continue;
}
@@ -134,15 +154,15 @@ foreach ($users as $userFilename) {
Minz_ExtensionManager::enableByList(FreshRSS_Context::userConf()->extensions_enabled, 'user');
Minz_Translate::reset(FreshRSS_Context::userConf()->language);
- [$nbUpdatedFeeds, ] = FreshRSS_feed_Controller::actualizeFeedsAndCommit(null, $self, null, $simplePie);
+ [$nbUpdatedFeeds, ] = FreshRSS_feed_Controller::actualizeFeedsAndCommit(feed_url: $canonical, simplePiePush: $simplePie, selfUrl: $self);
if ($nbUpdatedFeeds > 0) {
$nb++;
} else {
- Minz_Log::warning('Warning: User ' . $username . ' does not subscribe anymore to ' . $self, PSHB_LOG);
+ Minz_Log::warning('Warning: User ' . $username . ' does not subscribe anymore to ' . $canonical, PSHB_LOG);
unlink($userFilename);
}
} catch (Exception $e) {
- Minz_Log::error('Error: ' . $e->getMessage() . ' for user ' . $username . ' and feed ' . $self, PSHB_LOG);
+ Minz_Log::error('Error: ' . $e->getMessage() . ' for user ' . $username . ' and feed ' . $canonical, PSHB_LOG);
}
}
@@ -151,12 +171,12 @@ unset($simplePie);
if ($nb === 0) {
header('HTTP/1.1 410 Gone');
- Minz_Log::warning('Warning: Nobody subscribes to this feed anymore after all!: ' . $self, PSHB_LOG);
+ Minz_Log::warning('Warning: Nobody subscribes to this feed anymore after all!: ' . $canonical, PSHB_LOG);
die('Nobody subscribes to this feed anymore after all!');
} elseif (!empty($hubJson['error'])) {
$hubJson['error'] = false;
file_put_contents('./!hub.json', json_encode($hubJson));
}
-Minz_Log::notice('WebSub ' . $self . ' done: ' . $nb, PSHB_LOG);
+Minz_Log::notice('WebSub ' . $canonical . ' done: ' . $nb, PSHB_LOG);
exit('Done: ' . $nb . "\n");