X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FOStatus%2Fclasses%2FHubSub.php;h=c9d65c56a7a45b09a6beff359f1d2753207eeb23;hb=ad7cd155fbc643c9b873415d542745bb79c4e239;hp=7db528a4e85772a23ad35823cb5592e0edde6951;hpb=d9e56e15cc3174093fc994e524d1d9cf402ae8a3;p=quix0rs-gnu-social.git diff --git a/plugins/OStatus/classes/HubSub.php b/plugins/OStatus/classes/HubSub.php index 7db528a4e8..c9d65c56a7 100644 --- a/plugins/OStatus/classes/HubSub.php +++ b/plugins/OStatus/classes/HubSub.php @@ -17,18 +17,22 @@ * along with this program. If not, see . */ +if (!defined('STATUSNET')) { + exit(1); +} + /** * PuSH feed subscription record * @package Hub * @author Brion Vibber */ -class HubSub extends Memcached_DataObject +class HubSub extends Managed_DataObject { public $__table = 'hubsub'; public $hashkey; // sha1(topic . '|' . $callback); (topic, callback) key is too long for myisam in utf8 - public $topic; - public $callback; + public $topic; // varchar(191) not 255 because utf8mb4 takes more space + public $callback; // varchar(191) not 255 because utf8mb4 takes more space public $secret; public $lease; public $sub_start; @@ -36,86 +40,35 @@ class HubSub extends Memcached_DataObject public $created; public $modified; - public /*static*/ function staticGet($topic, $callback) - { - return parent::staticGet(__CLASS__, 'hashkey', self::hashkey($topic, $callback)); - } - protected static function hashkey($topic, $callback) { return sha1($topic . '|' . $callback); } - /** - * return table definition for DB_DataObject - * - * DB_DataObject needs to know something about the table to manipulate - * instances. This method provides all the DB_DataObject needs to know. - * - * @return array array of column definitions - */ - - function table() - { - return array('hashkey' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL, - 'topic' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL, - 'callback' => DB_DATAOBJECT_STR + DB_DATAOBJECT_NOTNULL, - 'secret' => DB_DATAOBJECT_STR, - 'lease' => DB_DATAOBJECT_INT, - 'sub_start' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME, - 'sub_end' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME, - 'created' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL, - 'modified' => DB_DATAOBJECT_STR + DB_DATAOBJECT_DATE + DB_DATAOBJECT_TIME + DB_DATAOBJECT_NOTNULL); - } - - static function schemaDef() - { - return array(new ColumnDef('hashkey', 'char', - /*size*/40, - /*nullable*/false, - /*key*/'PRI'), - new ColumnDef('topic', 'varchar', - /*size*/255, - /*nullable*/false, - /*key*/'MUL'), - new ColumnDef('callback', 'varchar', - 255, false), - new ColumnDef('secret', 'text', - null, true), - new ColumnDef('lease', 'int', - null, true), - new ColumnDef('sub_start', 'datetime', - null, true), - new ColumnDef('sub_end', 'datetime', - null, true), - new ColumnDef('created', 'datetime', - null, false), - new ColumnDef('modified', 'datetime', - null, false)); - } - - function keys() + public static function getByHashkey($topic, $callback) { - return array_keys($this->keyTypes()); + return self::getKV('hashkey', self::hashkey($topic, $callback)); } - function sequenceKey() + public static function schemaDef() { - return array(false, false, false); - } - - /** - * return key definitions for DB_DataObject - * - * DB_DataObject needs to know about keys that the table has; this function - * defines them. - * - * @return array key definitions - */ - - function keyTypes() - { - return array('hashkey' => 'K'); + return array( + 'fields' => array( + 'hashkey' => array('type' => 'char', 'not null' => true, 'length' => 40, 'description' => 'HubSub hashkey'), + 'topic' => array('type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'HubSub topic'), + 'callback' => array('type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'HubSub callback'), + 'secret' => array('type' => 'text', 'description' => 'HubSub stored secret'), + 'lease' => array('type' => 'int', 'description' => 'HubSub leasetime'), + 'sub_start' => array('type' => 'datetime', 'description' => 'subscription start'), + 'sub_end' => array('type' => 'datetime', 'description' => 'subscription end'), + 'created' => array('type' => 'datetime', 'not null' => true, 'description' => 'date this record was created'), + 'modified' => array('type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'), + ), + 'primary key' => array('hashkey'), + 'indexes' => array( + 'hubsub_topic_idx' => array('topic'), + ), + ); } /** @@ -161,7 +114,7 @@ class HubSub extends Memcached_DataObject } $data = array('sub' => clone($this), 'mode' => $mode, - 'token' => $token, + 'token' => $token, // let's put it in there if remote uses PuSH <0.4 'retries' => $retries); $qm = QueueManager::get(); $qm->enqueue($data, 'hubconf'); @@ -179,15 +132,15 @@ class HubSub extends Memcached_DataObject { assert($mode == 'subscribe' || $mode == 'unsubscribe'); - $challenge = common_good_rand(32); + $challenge = common_random_hexstr(32); $params = array('hub.mode' => $mode, 'hub.topic' => $this->topic, 'hub.challenge' => $challenge); if ($mode == 'subscribe') { $params['hub.lease_seconds'] = $this->lease; } - if ($token !== null) { - $params['hub.verify_token'] = $token; + if ($token !== null) { // TODO: deprecated in PuSH 0.4 + $params['hub.verify_token'] = $token; // let's put it in there if remote uses PuSH <0.4 } // Any existing query string parameters must be preserved @@ -204,20 +157,21 @@ class HubSub extends Memcached_DataObject $status = $response->getStatus(); if ($status >= 200 && $status < 300) { - common_log(LOG_INFO, "Verified $mode of $this->callback:$this->topic"); + common_log(LOG_INFO, "Verified {$mode} of {$this->callback}:{$this->topic}"); } else { - throw new ClientException("Hub subscriber verification returned HTTP $status"); + // TRANS: Client exception. %s is a HTTP status code. + throw new ClientException(sprintf(_m('Hub subscriber verification returned HTTP %s.'),$status)); } - $old = HubSub::staticGet($this->topic, $this->callback); + $old = HubSub::getByHashkey($this->topic, $this->callback); if ($mode == 'subscribe') { - if ($old) { + if ($old instanceof HubSub) { $this->update($old); } else { $ok = $this->insert(); } } else if ($mode == 'unsubscribe') { - if ($old) { + if ($old instanceof HubSub) { $old->delete(); } else { // That's ok, we're already unsubscribed. @@ -237,16 +191,6 @@ class HubSub extends Memcached_DataObject return parent::insert(); } - /** - * Update wrapper; transparently update modified column. - * @return boolean success - */ - function update($old=null) - { - $this->modified = common_sql_now(); - return parent::update($old); - } - /** * Schedule delivery of a 'fat ping' to the subscriber's callback * endpoint. If queues are disabled, this will run immediately. @@ -260,42 +204,11 @@ class HubSub extends Memcached_DataObject $retries = intval(common_config('ostatus', 'hub_retries')); } - if (common_config('ostatus', 'local_push_bypass')) { - // If target is a local site, bypass the web server and drop the - // item directly into the target's input queue. - $url = parse_url($this->callback); - $wildcard = common_config('ostatus', 'local_wildcard'); - $site = Status_network::getFromHostname($url['host'], $wildcard); - - if ($site) { - if ($this->secret) { - $hmac = 'sha1=' . hash_hmac('sha1', $atom, $this->secret); - } else { - $hmac = ''; - } - - // Hack: at the moment we stick the subscription ID in the callback - // URL so we don't have to look inside the Atom to route the subscription. - // For now this means we need to extract that from the target URL - // so we can include it in the data. - $parts = explode('/', $url['path']); - $subId = intval(array_pop($parts)); - - $data = array('feedsub_id' => $subId, - 'post' => $atom, - 'hmac' => $hmac); - common_log(LOG_DEBUG, "Cross-site PuSH bypass enqueueing straight to $site->nickname feed $subId"); - $qm = QueueManager::get(); - $qm->enqueue($data, 'pushin', $site->nickname); - return; - } - } - // We dare not clone() as when the clone is discarded it'll // destroy the result data for the parent query. // @fixme use clone() again when it's safe to copy an // individual item from a multi-item query again. - $sub = HubSub::staticGet($this->topic, $this->callback); + $sub = HubSub::getByHashkey($this->topic, $this->callback); $data = array('sub' => $sub, 'atom' => $atom, 'retries' => $retries); @@ -307,9 +220,9 @@ class HubSub extends Memcached_DataObject /** * Queue up a large batch of pushes to multiple subscribers * for this same topic update. - * + * * If queues are disabled, this will run immediately. - * + * * @param string $atom well-formed Atom feed * @param array $pushCallbacks list of callback URLs */ @@ -352,11 +265,9 @@ class HubSub extends Memcached_DataObject if ($response->isOk()) { return true; } else { - throw new Exception("Callback returned status: " . - $response->getStatus() . - "; body: " . - trim($response->getBody())); + // TRANS: Exception. %1$s is a response status code, %2$s is the body of the response. + throw new Exception(sprintf(_m('Callback returned status: %1$s. Body: %2$s'), + $response->getStatus(),trim($response->getBody()))); } } } -