X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FOStatus%2Fclasses%2FFeedSub.php;h=0a6abfa1bef239346fe4c30ae6d8da4943eb643b;hb=5fd6053220d9ff2c28735fcf5b8c99b83b09ecc0;hp=c055420ed91307a685db7d04320e4aeca2cd4718;hpb=ab4113168f32c46946b20674c80ec79c19dbccd7;p=quix0rs-gnu-social.git diff --git a/plugins/OStatus/classes/FeedSub.php b/plugins/OStatus/classes/FeedSub.php index c055420ed9..0a6abfa1be 100644 --- a/plugins/OStatus/classes/FeedSub.php +++ b/plugins/OStatus/classes/FeedSub.php @@ -67,7 +67,7 @@ class FeedSub extends Managed_DataObject // PuSH subscription data public $huburi; public $secret; - public $sub_state; // subscribe, active, unsubscribe, inactive + public $sub_state; // subscribe, active, unsubscribe, inactive, nohub public $sub_start; public $sub_end; public $last_update; @@ -83,7 +83,7 @@ class FeedSub extends Managed_DataObject 'uri' => array('type' => 'varchar', 'not null' => true, 'length' => 255, 'description' => 'FeedSub uri'), 'huburi' => array('type' => 'text', 'description' => 'FeedSub hub-uri'), 'secret' => array('type' => 'text', 'description' => 'FeedSub stored secret'), - 'sub_state' => array('type' => 'enum("subscribe","active","unsubscribe","inactive")', 'not null' => true, 'description' => 'subscription state'), + 'sub_state' => array('type' => 'enum("subscribe","active","unsubscribe","inactive","nohub")', 'not null' => true, 'description' => 'subscription state'), 'sub_start' => array('type' => 'datetime', 'description' => 'subscription start'), 'sub_end' => array('type' => 'datetime', 'description' => 'subscription end'), 'last_update' => array('type' => 'datetime', 'not null' => true, 'description' => 'when this record was last updated'), @@ -97,6 +97,37 @@ class FeedSub extends Managed_DataObject ); } + /** + * Get the feed uri (http/https) + */ + public function getUri() + { + if (empty($this->uri)) { + throw new ServerException('No URI for FeedSub entry'); + } + return $this->uri; + } + + /** + * Do we have a hub? Then we are a PuSH feed. + * https://en.wikipedia.org/wiki/PubSubHubbub + * + * If huburi is empty, then doublecheck that we are not using + * a fallback hub. If there is a fallback hub, it is only if the + * sub_state is "nohub" that we assume it's not a PuSH feed. + */ + public function isPuSH() + { + if (empty($this->huburi) + && (!common_config('feedsub', 'fallback_hub') + || $this->sub_state === 'nohub')) { + // Here we have no huburi set. Also, either there is no + // fallback hub configured or sub_state is "nohub". + return false; + } + return true; + } + /** * Fetch the StatusNet-side profile for this feed * @return Profile @@ -167,8 +198,14 @@ class FeedSub extends Managed_DataObject public function subscribe() { if ($this->sub_state && $this->sub_state != 'inactive') { - common_log(LOG_WARNING, "Attempting to (re)start PuSH subscription to {$this->uri} in unexpected state {$this->sub_state}"); + common_log(LOG_WARNING, sprintf('Attempting to (re)start PuSH subscription to %s in unexpected state %s', $this->getUri(), $this->sub_state)); + } + + if (!Event::handle('FeedSubscribe', array($this))) { + // A plugin handled it + return true; } + if (empty($this->huburi)) { if (common_config('feedsub', 'fallback_hub')) { // No native hub on this feed? @@ -198,8 +235,14 @@ class FeedSub extends Managed_DataObject */ public function unsubscribe() { if ($this->sub_state != 'active') { - common_log(LOG_WARNING, "Attempting to (re)end PuSH subscription to {$this->uri} in unexpected state {$this->sub_state}"); + common_log(LOG_WARNING, sprintf('Attempting to (re)end PuSH subscription to %s in unexpected state %s', $this->getUri(), $this->sub_state)); } + + if (!Event::handle('FeedUnsubscribe', array($this))) { + // A plugin handled it + return true; + } + if (empty($this->huburi)) { if (common_config('feedsub', 'fallback_hub')) { // No native hub on this feed? @@ -235,10 +278,10 @@ class FeedSub extends Managed_DataObject Event::handle('FeedSubSubscriberCount', array($this, &$count)); if ($count) { - common_log(LOG_INFO, __METHOD__ . ': ok, ' . $count . ' user(s) left for ' . $this->uri); + common_log(LOG_INFO, __METHOD__ . ': ok, ' . $count . ' user(s) left for ' . $this->getUri()); return false; } else { - common_log(LOG_INFO, __METHOD__ . ': unsubscribing, no users left for ' . $this->uri); + common_log(LOG_INFO, __METHOD__ . ': unsubscribing, no users left for ' . $this->getUri()); return $this->unsubscribe(); } } @@ -249,7 +292,7 @@ class FeedSub extends Managed_DataObject $fs = new FeedSub(); // the "" empty string check is because we historically haven't saved unsubscribed feeds as NULL $fs->whereAdd('sub_end IS NOT NULL AND sub_end!="" AND sub_end < NOW() - INTERVAL 1 day'); - if ($fs->find() === false) { + if (!$fs->find()) { // find can be both false and 0, depending on why nothing was found throw new NoResultException($fs); } return $fs; @@ -261,11 +304,16 @@ class FeedSub extends Managed_DataObject } /** + * Setting to subscribe means it is _waiting_ to become active. This + * cannot be done in a transaction because there is a chance that the + * remote script we're calling (as in the case of PuSHpress) performs + * the lookup _while_ we're POSTing data, which means the transaction + * never completes (PushcallbackAction gets an 'inactive' state). + * * @return boolean true on successful sub/unsub, false on failure */ protected function doSubscribe($mode) { - $this->query('BEGIN'); $orig = clone($this); if ($mode == 'subscribe') { $this->secret = common_random_hexstr(32); @@ -279,9 +327,11 @@ class FeedSub extends Managed_DataObject $headers = array('Content-Type: application/x-www-form-urlencoded'); $post = array('hub.mode' => $mode, 'hub.callback' => $callback, - 'hub.verify' => 'async', // TODO: deprecated, remove when noone uses PuSH <0.4 + 'hub.verify' => 'async', // TODO: deprecated, remove when noone uses PuSH <0.4 (only 'async' method used there) + 'hub.verify_token' => 'Deprecated-since-PuSH-0.4', // TODO: rm! + 'hub.secret' => $this->secret, - 'hub.topic' => $this->uri); + 'hub.topic' => $this->getUri()); $client = new HTTPClient(); if ($this->huburi) { $hub = $this->huburi; @@ -300,7 +350,6 @@ class FeedSub extends Managed_DataObject $response = $client->post($hub, $headers, $post); $status = $response->getStatus(); if ($status == 202) { - $this->query('COMMIT'); common_log(LOG_INFO, __METHOD__ . ': sub req ok, awaiting verification callback'); return true; } else if ($status >= 200 && $status < 300) { @@ -308,11 +357,9 @@ class FeedSub extends Managed_DataObject } else { common_log(LOG_ERR, __METHOD__ . ": sub req failed with HTTP $status: " . $response->getBody()); } - $this->query('ROLLBACK'); } catch (Exception $e) { - $this->query('ROLLBACK'); // wtf! - common_log(LOG_ERR, __METHOD__ . ": error \"{$e->getMessage()}\" hitting hub $this->huburi subscribing to $this->uri"); + common_log(LOG_ERR, __METHOD__ . ": error \"{$e->getMessage()}\" hitting hub $this->huburi subscribing to " . $this->getUri()); $orig = clone($this); $this->sub_state = 'inactive'; @@ -378,10 +425,10 @@ class FeedSub extends Managed_DataObject */ public function receive($post, $hmac) { - common_log(LOG_INFO, __METHOD__ . ": packet for \"$this->uri\"! $hmac $post"); + common_log(LOG_INFO, __METHOD__ . ": packet for \"" . $this->getUri() . "\"! $hmac $post"); if ($this->sub_state != 'active') { - common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH for inactive feed $this->uri (in state '$this->sub_state')"); + common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH for inactive feed " . $this->getUri() . " (in state '$this->sub_state')"); return; } @@ -436,9 +483,9 @@ class FeedSub extends Managed_DataObject if ($tempfile) { file_put_contents($tempfile, $post); } - common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed $this->uri on $this->huburi; saved to $tempfile"); + common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed " . $this->getUri() . " on $this->huburi; saved to $tempfile"); } else { - common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed $this->uri on $this->huburi"); + common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bad SHA-1 HMAC: got $their_hmac, expected $our_hmac for feed " . $this->getUri() . " on $this->huburi"); } } else { common_log(LOG_ERR, __METHOD__ . ": ignoring PuSH with bogus HMAC '$hmac'");