X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=plugins%2FOStatus%2Fclasses%2FHubSub.php;h=7ffda88e748c596496177e7f26c684ba03e96e36;hb=c393bc95635cc7b5584135bfd6f447dcc03c961b;hp=cdace3c1fc86e66b34f9dbde346c10628e2198d2;hpb=7277b59734cf0e39c8c77e01b13e8d997533bacf;p=quix0rs-gnu-social.git diff --git a/plugins/OStatus/classes/HubSub.php b/plugins/OStatus/classes/HubSub.php index cdace3c1fc..7ffda88e74 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() + public static function getByHashkey($topic, $callback) { - 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); + return self::getKV('hashkey', self::hashkey($topic, $callback)); } - static function schemaDef() + public 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() - { - return array_keys($this->keyTypes()); - } - - function sequenceKey() - { - 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. @@ -264,7 +208,7 @@ class HubSub extends Memcached_DataObject // 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); @@ -273,6 +217,31 @@ class HubSub extends Memcached_DataObject $qm->enqueue($data, 'hubout'); } + /** + * 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 + */ + function bulkDistribute($atom, array $pushCallbacks) + { + if (empty($pushCallbacks)) { + common_log(LOG_ERR, 'Callback list empty for bulkDistribute.'); + return false; + } + $data = array('atom' => $atom, + 'topic' => $this->topic, + 'pushCallbacks' => $pushCallbacks); + common_log(LOG_INFO, "Queuing PuSH batch: $this->topic to " . + count($pushCallbacks) . " sites"); + $qm = QueueManager::get(); + $qm->enqueue($data, 'hubprep'); + return true; + } + /** * Send a 'fat ping' to the subscriber's callback endpoint * containing the given Atom feed chunk. @@ -301,11 +270,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()))); } } } -