pushcallback.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <?php
  2. /*
  3. * StatusNet - the distributed open-source microblogging tool
  4. * Copyright (C) 2009, StatusNet, Inc.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * @package FeedSubPlugin
  21. * @maintainer Brion Vibber <brion@status.net>
  22. */
  23. if (!defined('STATUSNET')) {
  24. exit(1);
  25. }
  26. class PushCallbackAction extends Action
  27. {
  28. protected function handle()
  29. {
  30. GNUsocial::setApi(true); // Minimize error messages to aid in debugging
  31. parent::handle();
  32. if ($this->isPost()) {
  33. return $this->handlePost();
  34. }
  35. return $this->handleGet();
  36. }
  37. /**
  38. * Handler for POST content updates from the hub
  39. */
  40. function handlePost()
  41. {
  42. $feedid = $this->arg('feed');
  43. common_log(LOG_INFO, "POST for feed id $feedid");
  44. if (!$feedid) {
  45. // TRANS: Server exception thrown when referring to a non-existing or empty feed.
  46. throw new ServerException(_m('Empty or invalid feed id.'), 400);
  47. }
  48. $feedsub = FeedSub::getKV('id', $feedid);
  49. if (!$feedsub instanceof FeedSub) {
  50. // TRANS: Server exception. %s is a feed ID.
  51. throw new ServerException(sprintf(_m('Unknown WebSub subscription feed id %s'),$feedid), 400);
  52. }
  53. $hmac = '';
  54. if (isset($_SERVER['HTTP_X_HUB_SIGNATURE'])) {
  55. $hmac = $_SERVER['HTTP_X_HUB_SIGNATURE'];
  56. }
  57. $post = file_get_contents('php://input');
  58. // Queue this to a background process; we should return
  59. // as quickly as possible from a distribution POST.
  60. // If queues are disabled this'll process immediately.
  61. $data = array('feedsub_id' => $feedsub->id,
  62. 'post' => $post,
  63. 'hmac' => $hmac);
  64. $qm = QueueManager::get();
  65. $qm->enqueue($data, 'pushin');
  66. }
  67. /**
  68. * Handler for GET verification requests from the hub.
  69. */
  70. public function handleGet()
  71. {
  72. $mode = $this->arg('hub_mode');
  73. $topic = $this->arg('hub_topic');
  74. $challenge = $this->arg('hub_challenge');
  75. $lease_seconds = $this->arg('hub_lease_seconds'); // Must be >0 for PuSH 0.4! And only checked on mode='subscribe' of course
  76. common_log(LOG_INFO, __METHOD__ . ": sub verification mode: $mode topic: $topic challenge: $challenge lease_seconds: $lease_seconds");
  77. if ($mode != 'subscribe' && $mode != 'unsubscribe') {
  78. // TRANS: Client exception. %s is an invalid value for hub.mode.
  79. throw new ClientException(sprintf(_m('Bad hub.mode "$s".',$mode)), 404);
  80. }
  81. $feedsub = FeedSub::getKV('uri', $topic);
  82. if (!$feedsub instanceof FeedSub) {
  83. // TRANS: Client exception. %s is an invalid feed name.
  84. throw new ClientException(sprintf(_m('Bad hub.topic feed "%s".'),$topic), 404);
  85. }
  86. if ($mode == 'subscribe') {
  87. // We may get re-sub requests legitimately.
  88. if ($feedsub->sub_state != 'subscribe' && $feedsub->sub_state != 'active') {
  89. // TRANS: Client exception. %s is an invalid topic.
  90. throw new ClientException(sprintf(_m('Unexpected subscribe request for %s.'),$topic), 404);
  91. }
  92. } else {
  93. if ($feedsub->sub_state != 'unsubscribe') {
  94. // TRANS: Client exception. %s is an invalid topic.
  95. throw new ClientException(sprintf(_m('Unexpected unsubscribe request for %s.'),$topic), 404);
  96. }
  97. }
  98. if ($mode == 'subscribe') {
  99. $renewal = ($feedsub->sub_state == 'active');
  100. if ($renewal) {
  101. common_log(LOG_INFO, __METHOD__ . ': sub update confirmed');
  102. } else {
  103. common_log(LOG_INFO, __METHOD__ . ': sub confirmed');
  104. }
  105. $feedsub->confirmSubscribe($lease_seconds);
  106. if (!$renewal) {
  107. // Kickstart the feed by importing its most recent backlog
  108. // FIXME: Disabled until we can either limit the amount and/or send to background queue handling
  109. //common_log(LOG_INFO, __METHOD__ . ': Confirmed a new subscription, importing backlog...');
  110. //$feedsub->importFeed();
  111. }
  112. } else {
  113. common_log(LOG_INFO, __METHOD__ . ": unsub confirmed; deleting sub record for $topic");
  114. $feedsub->confirmUnsubscribe();
  115. }
  116. print $challenge;
  117. }
  118. }