. */ /** * @package FeedSubPlugin * @maintainer Brion Vibber */ if (!defined('STATUSNET')) { exit(1); } class PushCallbackAction extends Action { protected function handle() { GNUsocial::setApi(true); // Minimize error messages to aid in debugging parent::handle(); if ($this->isPost()) { return $this->handlePost(); } return $this->handleGet(); } /** * Handler for POST content updates from the hub */ function handlePost() { $feedid = $this->arg('feed'); common_log(LOG_INFO, "POST for feed id $feedid"); if (!$feedid) { // TRANS: Server exception thrown when referring to a non-existing or empty feed. throw new ServerException(_m('Empty or invalid feed id.'), 400); } $feedsub = FeedSub::getKV('id', $feedid); if (!$feedsub instanceof FeedSub) { // TRANS: Server exception. %s is a feed ID. throw new ServerException(sprintf(_m('Unknown WebSub subscription feed id %s'),$feedid), 400); } $hmac = ''; if (isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) { $hmac = $_SERVER['HTTP_X_HUB_SIGNATURE']; } $post = file_get_contents('php://input'); // Queue this to a background process; we should return // as quickly as possible from a distribution POST. // If queues are disabled this'll process immediately. $data = array('feedsub_id' => $feedsub->id, 'post' => $post, 'hmac' => $hmac); $qm = QueueManager::get(); $qm->enqueue($data, 'pushin'); } /** * Handler for GET verification requests from the hub. */ public function handleGet() { $mode = $this->arg('hub_mode'); $topic = $this->arg('hub_topic'); $challenge = $this->arg('hub_challenge'); $lease_seconds = $this->arg('hub_lease_seconds'); // Must be >0 for PuSH 0.4! And only checked on mode='subscribe' of course common_log(LOG_INFO, __METHOD__ . ": sub verification mode: $mode topic: $topic challenge: $challenge lease_seconds: $lease_seconds"); if ($mode != 'subscribe' && $mode != 'unsubscribe') { // TRANS: Client exception. %s is an invalid value for hub.mode. throw new ClientException(sprintf(_m('Bad hub.mode "$s".',$mode)), 404); } $feedsub = FeedSub::getKV('uri', $topic); if (!$feedsub instanceof FeedSub) { // TRANS: Client exception. %s is an invalid feed name. throw new ClientException(sprintf(_m('Bad hub.topic feed "%s".'),$topic), 404); } if ($mode == 'subscribe') { // We may get re-sub requests legitimately. if ($feedsub->sub_state != 'subscribe' && $feedsub->sub_state != 'active') { // TRANS: Client exception. %s is an invalid topic. throw new ClientException(sprintf(_m('Unexpected subscribe request for %s.'),$topic), 404); } } else { if ($feedsub->sub_state != 'unsubscribe') { // TRANS: Client exception. %s is an invalid topic. throw new ClientException(sprintf(_m('Unexpected unsubscribe request for %s.'),$topic), 404); } } if ($mode == 'subscribe') { $renewal = ($feedsub->sub_state == 'active'); if ($renewal) { common_log(LOG_INFO, __METHOD__ . ': sub update confirmed'); } else { common_log(LOG_INFO, __METHOD__ . ': sub confirmed'); } $feedsub->confirmSubscribe($lease_seconds); if (!$renewal) { // Kickstart the feed by importing its most recent backlog // FIXME: Disabled until we can either limit the amount and/or send to background queue handling //common_log(LOG_INFO, __METHOD__ . ': Confirmed a new subscription, importing backlog...'); //$feedsub->importFeed(); } } else { common_log(LOG_INFO, __METHOD__ . ": unsub confirmed; deleting sub record for $topic"); $feedsub->confirmUnsubscribe(); } print $challenge; } }