diff options
| author | 2015-05-15 15:34:51 +0200 | |
|---|---|---|
| committer | 2015-05-15 15:34:51 +0200 | |
| commit | c472569b3861541c322c850c4ff8ca3471572f40 (patch) | |
| tree | ae2ecf23892c289dbffb18079db6b5781293631a /app | |
| parent | 256c8613a4046931dcd28ab22b6aebe8752a98c2 (diff) | |
First alpha of PubSubHubbub
https://github.com/FreshRSS/FreshRSS/issues/312
Using a white list limited to http://push-pub.appspot.com/feed for alpha
testing.
Diffstat (limited to 'app')
| -rwxr-xr-x | app/Controllers/feedController.php | 31 | ||||
| -rw-r--r-- | app/Models/Feed.php | 53 |
2 files changed, 63 insertions, 21 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php index 9117da639..0fb4bdf03 100755 --- a/app/Controllers/feedController.php +++ b/app/Controllers/feedController.php @@ -304,6 +304,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController { continue; } + $url = $feed->url(); //For detection of HTTP 301 try { if ($simplePie) { $feed->loadEntries($simplePie); //Used by PubSubHubbub @@ -317,7 +318,6 @@ class FreshRSS_feed_Controller extends Minz_ActionController { continue; } - $url = $feed->url(); $feed_history = $feed->keepHistory(); if ($feed_history == -2) { // TODO: -2 must be a constant! @@ -404,19 +404,34 @@ class FreshRSS_feed_Controller extends Minz_ActionController { $entryDAO->commit(); } - if ($feed->url() !== $url) { - // HTTP 301 Moved Permanently + if ($feed->hubUrl() && $feed->selfUrl()) { //selfUrl has priority for PubSubHubbub + if ($feed->selfUrl() !== $url) { //https://code.google.com/p/pubsubhubbub/wiki/MovingFeedsOrChangingHubs + $selfUrl = checkUrl($feed->selfUrl()); + if ($selfUrl) { + Minz_Log::debug('PubSubHubbub unsubscribe ' . $feed->url()); + if (!$feed->pubSubHubbubSubscribe(false)) { //Unsubscribe + Minz_Log::warning('Error while PubSubHubbub unsubscribing from ' . $feed->url()); + } + $feed->_url($selfUrl, false); + Minz_Log::notice('Feed ' . $url . ' canonical address moved to ' . $feed->url()); + $feedDAO->updateFeed($feed->id(), array('url' => $feed->url())); + } + } + } + elseif ($feed->url() !== $url) { // HTTP 301 Moved Permanently Minz_Log::notice('Feed ' . $url . ' moved permanently to ' . $feed->url()); $feedDAO->updateFeed($feed->id(), array('url' => $feed->url())); } if ($simplePie === null) { $feed->faviconPrepare(); - if ($feed->url() === 'http://push-pub.appspot.com/feed') { - $secret = $feed->pubSubHubbubPrepare(); - if ($secret != '') { - Minz_Log::debug('PubSubHubbub subscribe ' . $feed->url()); - $feed->pubSubHubbubSubscribe(true, $secret); + if (in_array($feed->url(), array('http://push-pub.appspot.com/feed'))) { //TODO: Remove white-list after testing + Minz_Log::debug('PubSubHubbub match ' . $feed->url()); + if ($feed->pubSubHubbubPrepare()) { + Minz_Log::notice('PubSubHubbub subscribe ' . $feed->url()); + if (!$feed->pubSubHubbubSubscribe(true)) { //Subscribe + Minz_Log::warning('Error while PubSubHubbub subscribing to ' . $feed->url()); + } } } } diff --git a/app/Models/Feed.php b/app/Models/Feed.php index dcf083ea8..a17cf415d 100644 --- a/app/Models/Feed.php +++ b/app/Models/Feed.php @@ -51,6 +51,12 @@ class FreshRSS_Feed extends Minz_Model { public function url() { return $this->url; } + public function selfUrl() { + return $this->selfUrl; + } + public function hubUrl() { + return $this->hubUrl; + } public function category() { return $this->category; } @@ -344,38 +350,59 @@ class FreshRSS_Feed extends Minz_Model { //<PubSubHubbub> function pubSubHubbubPrepare() { - $secret = ''; + $key = ''; if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { $path = PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl); - if (!file_exists($path . '/hub.txt')) { + if ($hubFile = @file_get_contents($path . '/!hub.json')) { + $hubJson = json_decode($hubFile, true); + if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { + Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); + return false; + } + if (empty($hubJson['lease_end']) || $hubJson['lease_end'] <= time()) { + Minz_Log::warning('PubSubHubbub lease expired: ' . $this->url); + $key = $hubJson['key']; //To renew our lease + } + } else { @mkdir($path, 0777, true); - file_put_contents($path . '/hub.txt', $this->hubUrl); - $secret = sha1(FreshRSS_Context::$system_conf->salt . uniqid(mt_rand(), true)); - file_put_contents($path . '/secret.txt', $secret); - @mkdir(PSHB_PATH . '/secrets/'); - file_put_contents(PSHB_PATH . '/secrets/' . $secret . '.txt', base64url_encode($this->selfUrl)); + $key = sha1(FreshRSS_Context::$system_conf->salt . uniqid(mt_rand(), true)); + $hubJson = array( + 'hub' => $this->hubUrl, + 'key' => $key, + ); + file_put_contents($path . '/!hub.json', json_encode($hubJson)); + @mkdir(PSHB_PATH . '/keys/'); + file_put_contents(PSHB_PATH . '/keys/' . $key . '.txt', base64url_encode($this->selfUrl)); Minz_Log::notice('PubSubHubbub prepared for ' . $this->url); file_put_contents(USERS_PATH . '/_/log_pshb.txt', date('c') . "\t" . 'PubSubHubbub prepared for ' . $this->url . "\n", FILE_APPEND); } - $path .= '/' . base64url_encode($this->url); $currentUser = Minz_Session::param('currentUser'); if (ctype_alnum($currentUser) && !file_exists($path . '/' . $currentUser . '.txt')) { - @mkdir($path, 0777, true); touch($path . '/' . $currentUser . '.txt'); } } - return $secret; + return $key; } //Parameter true to subscribe, false to unsubscribe. - function pubSubHubbubSubscribe($state, $secret = '') { + function pubSubHubbubSubscribe($state) { if (FreshRSS_Context::$system_conf->base_url && $this->hubUrl && $this->selfUrl) { - $callbackUrl = checkUrl(FreshRSS_Context::$system_conf->base_url . 'api/pshb.php?s=' . $secret); + $hubFile = @file_get_contents(PSHB_PATH . '/feeds/' . base64url_encode($this->selfUrl) . '/!hub.json'); + if ($hubFile === false) { + Minz_Log::warning('JSON not found for PubSubHubbub: ' . $this->url); + return false; + } + $hubJson = json_decode($hubFile, true); + if (!$hubJson || empty($hubJson['key']) || !ctype_xdigit($hubJson['key'])) { + Minz_Log::warning('Invalid JSON for PubSubHubbub: ' . $this->url); + return false; + } + $callbackUrl = checkUrl(FreshRSS_Context::$system_conf->base_url . 'api/pshb.php?k=' . $hubJson['key']); if ($callbackUrl == '') { + Minz_Log::warning('Invalid callback for PubSubHubbub: ' . $this->url); return false; } - $ch = curl_init(); curl_setopt_array($ch, array( CURLOPT_URL => $this->hubUrl, |
