. */ /** * @package FeedSubPlugin * @maintainer Brion Vibber */ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } class PushCallbackAction extends Action { function handle() { StatusNet::setApi(true); // Minimize error messages to aid in debugging parent::handle(); if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->handlePost(); } else { $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) { throw new ServerException(_m('Empty or invalid feed id.'), 400); } $feedsub = FeedSub::staticGet('id', $feedid); if (!$feedsub) { // TRANS: Server exception. %s is a feed ID. throw new ServerException(sprintf(_m('Unknown PuSH 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. */ function handleGet() { $mode = $this->arg('hub_mode'); $topic = $this->arg('hub_topic'); $challenge = $this->arg('hub_challenge'); $lease_seconds = $this->arg('hub_lease_seconds'); $verify_token = $this->arg('hub_verify_token'); common_log(LOG_INFO, __METHOD__ . ": sub verification mode: $mode topic: $topic challenge: $challenge lease_seconds: $lease_seconds verify_token: $verify_token"); 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::staticGet('uri', $topic); if (!$feedsub) { // TRANS: Client exception. %s is an invalid feed name. throw new ClientException(sprintf(_m('Bad hub.topic feed "%s".'),$topic), 404); } if ($feedsub->verify_token !== $verify_token) { // TRANS: Client exception. %1$s the invalid token, %2$s is the topic for which the invalid token was given. throw new ClientException(sprintf(_m('Bad hub.verify_token %1$s for %2$s.'),$token,$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') { if ($feedsub->sub_state == 'active') { common_log(LOG_INFO, __METHOD__ . ': sub update confirmed'); } else { common_log(LOG_INFO, __METHOD__ . ': sub confirmed'); } $feedsub->confirmSubscribe($lease_seconds); } else { common_log(LOG_INFO, __METHOD__ . ": unsub confirmed; deleting sub record for $topic"); $feedsub->confirmUnsubscribe(); } print $challenge; } }