You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

97 lines
3.1 KiB

  1. <?php
  2. function push_error(&$app, $msg) {
  3. $app->response()->status(400);
  4. echo $msg . "\n";
  5. die();
  6. }
  7. ///////////////////////////////////////////////////////////////
  8. // These are just test routes
  9. $app->get('/callback-success', function() use($app) {
  10. $params = $app->request()->params();
  11. $app->response()->status(200);
  12. echo $params['hub_challenge'];
  13. });
  14. $app->get('/callback-fail', function() use($app) {
  15. $params = $app->request()->params();
  16. $app->response()->status(404);
  17. });
  18. ///////////////////////////////////////////////////////////////
  19. $app->post('/', function() use($app) {
  20. $params = $app->request()->params();
  21. switch($mode=k($params, 'hub_mode')) {
  22. case 'subscribe':
  23. case 'unsubscribe':
  24. // Sanity check the request params
  25. $topic = k($params, 'hub_topic');
  26. $callback = k($params, 'hub_callback');
  27. if(!is_valid_push_url($topic)) {
  28. push_error($app, 'Topic URL was invalid');
  29. }
  30. if(!is_valid_push_url($callback)) {
  31. push_error($app, 'Callback URL was invalid');
  32. }
  33. if($mode == 'subscribe') {
  34. // If we've already seen the topic, assume it's valid and don't check it again
  35. if(!db\feed_from_url($topic)) {
  36. $topic_head = request\get_head($topic);
  37. if($topic_head && !request\response_is($topic_head['status'], 2)) {
  38. push_error($app, "The topic URL returned a " . $topic_head['status'] . " status code");
  39. } else {
  40. push_error($app, 'We tried to verify the topic URL exists but it didn\'t respond to a HEAD request.');
  41. }
  42. }
  43. // Find or create the feed given the topic URL
  44. $feed = db\find_or_create('feeds', ['feed_url'=>$topic], [
  45. 'hash' => db\random_hash(),
  46. ], true);
  47. // Find or create the subscription for this callback URL and feed
  48. $subscription = db\find_or_create('subscriptions', ['feed_id'=>$feed->id, 'callback_url'=>$callback], [
  49. 'hash' => db\random_hash()
  50. ], true);
  51. // Always set a new requested date and challenge
  52. $subscription->date_requested = db\now();
  53. $subscription->challenge = db\random_hash();
  54. $subscription->save();
  55. // Queue the worker to validate the subscription
  56. DeferredTask::queue('PushTask', 'verify_subscription', [$subscription->id, 'subscribe']);
  57. } else {
  58. $feed = db\feed_from_url($topic);
  59. if(!$feed) {
  60. push_error($app, 'The topic was not found, so there is no subscription active');
  61. }
  62. $subscription = db\find('subscriptions', ['feed_id'=>$feed->id, 'callback_url'=>$callback]);
  63. if(!$subscription) {
  64. push_error($app, 'There was no subscription found for this callback URL and topic');
  65. }
  66. // Queue the worker to validate the subscription
  67. DeferredTask::queue('PushTask', 'verify_subscription', [$subscription->id, 'unsubscribe']);
  68. }
  69. $app->response()->status(202);
  70. echo "The subscription request is being validated. Check the status here:\n";
  71. echo Config::$base_url . '/subscription/' . $subscription->hash . "\n";
  72. break;
  73. break;
  74. }
  75. });