Plugin now checks notify handlers before registering subscriptions
This commit is contained in:
parent
4e07d9eeec
commit
61804bb7bb
|
@ -1,5 +1,4 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test class pretends to be an RSS aggregator. It logs notifications
|
* This test class pretends to be an RSS aggregator. It logs notifications
|
||||||
* from the cloud.
|
* from the cloud.
|
||||||
|
@ -78,8 +77,7 @@ class LoggingAggregatorAction extends Action
|
||||||
}
|
}
|
||||||
|
|
||||||
header('Content-Type: text/xml');
|
header('Content-Type: text/xml');
|
||||||
echo "<notifyResult success='true' msg='Thanks for the update.' challenge='" .
|
echo $this->challenge;
|
||||||
$this->challenge . "' />\n";
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
@ -92,7 +90,6 @@ class LoggingAggregatorAction extends Action
|
||||||
|
|
||||||
header('Content-Type: text/xml');
|
header('Content-Type: text/xml');
|
||||||
echo '<notifyResult success=\'true\' msg=\'Thanks for the update.\' />' . "\n";
|
echo '<notifyResult success=\'true\' msg=\'Thanks for the update.\' />' . "\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->ip = $_SERVER['REMOTE_ADDR'];
|
$this->ip = $_SERVER['REMOTE_ADDR'];
|
||||||
|
|
|
@ -33,59 +33,77 @@ if (!defined('STATUSNET')) {
|
||||||
|
|
||||||
class RSSCloudNotifier {
|
class RSSCloudNotifier {
|
||||||
|
|
||||||
function postUpdate($endpoint, $feed) {
|
function challenge($endpoint, $feed)
|
||||||
common_debug("CloudNotifier->notify: $feed");
|
{
|
||||||
|
$code = common_confirmation_code(128);
|
||||||
|
$params = array('url' => $feed, 'challenge' => $code);
|
||||||
|
$url = $endpoint . '?' . http_build_query($params);
|
||||||
|
|
||||||
$params = 'url=' . urlencode($feed);
|
try {
|
||||||
|
$client = new HTTPClient();
|
||||||
$result = $this->httpPost($endpoint, $params);
|
$response = $client->get($url);
|
||||||
|
} catch (HTTP_Request2_Exception $e) {
|
||||||
// XXX: Make all this use CurlClient (lib/curlclient.php)
|
common_log(LOG_INFO, 'RSSCloud plugin - failure testing notify handler ' .
|
||||||
|
$endpoint . ' - ' . $e->getMessage());
|
||||||
if ($result) {
|
return false;
|
||||||
common_debug('RSSCloud plugin - success notifying cloud endpoint!');
|
|
||||||
} else {
|
|
||||||
common_debug('RSSClous plugin - failure notifying cloud endpoint!');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
// Check response is betweet 200 and 299 and body contains challenge data
|
||||||
|
|
||||||
|
$status = $response->getStatus();
|
||||||
|
$body = $response->getBody();
|
||||||
|
|
||||||
|
if ($status >= 200 && $status < 300) {
|
||||||
|
|
||||||
|
if (strpos($body, $code) !== false) {
|
||||||
|
common_log(LOG_INFO, 'RSSCloud plugin - ' .
|
||||||
|
"success testing notify handler: $endpoint");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
common_log(LOG_INFO, 'RSSCloud plugin - ' .
|
||||||
|
'challenge/repsonse failed for notify handler ' .
|
||||||
|
$endpoint);
|
||||||
|
common_debug('body = ' . var_export($body, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
common_log(LOG_INFO, 'RSSCloud plugin - ' .
|
||||||
|
"failure testing notify handler: $endpoint " .
|
||||||
|
' - got HTTP ' . $status);
|
||||||
|
common_debug('body = ' . var_export($body, true));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function userAgent()
|
function postUpdate($endpoint, $feed) {
|
||||||
{
|
|
||||||
return 'rssCloudPlugin/' . RSSCLOUDPLUGIN_VERSION .
|
|
||||||
' StatusNet/' . STATUSNET_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function httpPost($url, $params) {
|
$headers = array();
|
||||||
|
$postdata = array('url' => $feed);
|
||||||
|
|
||||||
$options = array(CURLOPT_URL => $url,
|
try {
|
||||||
CURLOPT_POST => true,
|
$client = new HTTPClient();
|
||||||
CURLOPT_POSTFIELDS => $params,
|
$response = $client->post($endpoint, $headers, $postdata);
|
||||||
CURLOPT_USERAGENT => $this->userAgent(),
|
} catch (HTTP_Request2_Exception $e) {
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
common_log(LOG_INFO, 'RSSCloud plugin - failure notifying ' .
|
||||||
CURLOPT_FAILONERROR => true,
|
$endpoint . ' that feed ' . $feed .
|
||||||
CURLOPT_HEADER => false,
|
' has changed: ' . $e->getMessage());
|
||||||
CURLOPT_FOLLOWLOCATION => true,
|
return false;
|
||||||
CURLOPT_CONNECTTIMEOUT => 5,
|
}
|
||||||
CURLOPT_TIMEOUT => 5);
|
|
||||||
|
|
||||||
$ch = curl_init();
|
$status = $response->getStatus();
|
||||||
curl_setopt_array($ch, $options);
|
|
||||||
|
|
||||||
$response = curl_exec($ch);
|
if ($status >= 200 && $status < 300) {
|
||||||
|
common_log(LOG_INFO, 'RSSCloud plugin - success notifying ' .
|
||||||
$info = curl_getinfo($ch);
|
$endpoint . ' that feed ' . $feed . ' has changed.');
|
||||||
|
|
||||||
curl_close($ch);
|
|
||||||
|
|
||||||
if ($info['http_code'] == 200) {
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
common_log(LOG_INFO, 'RSSCloud plugin - failure notifying ' .
|
||||||
|
$endpoint . ' that feed ' . $feed .
|
||||||
|
' has changed: got HTTP ' . $status);
|
||||||
|
common_debug('body = ' . var_export($response->getBody(), true));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,8 @@ class RSSCloudPlugin extends Plugin
|
||||||
|
|
||||||
function onStartApiRss($action)
|
function onStartApiRss($action)
|
||||||
{
|
{
|
||||||
|
// XXX: Add RSS 1.0 user feeds
|
||||||
|
|
||||||
if (get_class($action) == 'ApiTimelineUserAction') {
|
if (get_class($action) == 'ApiTimelineUserAction') {
|
||||||
|
|
||||||
$attrs = array('domain' => $this->domain,
|
$attrs = array('domain' => $this->domain,
|
||||||
|
|
|
@ -52,7 +52,7 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
$this->protocol = $this->arg('protocol');
|
$this->protocol = $this->arg('protocol');
|
||||||
$this->procedure = $this->arg('notifyProcedure');
|
$this->procedure = $this->arg('notifyProcedure');
|
||||||
$this->domain = $this->arg('domain');
|
$this->domain = $this->arg('domain');
|
||||||
|
|
||||||
$this->feeds = $this->getFeeds();
|
$this->feeds = $this->getFeeds();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -103,29 +103,29 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to validate everything before saving anything.
|
// We have to validate everything before saving anything.
|
||||||
// We only return one success or failure no matter how
|
// We only return one success or failure no matter how
|
||||||
// many feeds the subscriber is trying to subscribe to
|
// many feeds the subscriber is trying to subscribe to
|
||||||
|
|
||||||
foreach ($this->feeds as $feed) {
|
foreach ($this->feeds as $feed) {
|
||||||
|
|
||||||
if (!$this->validateFeed($feed)) {
|
if (!$this->validateFeed($feed)) {
|
||||||
$msg = 'Feed subscription failed - Not a valid feed.';
|
$msg = 'Feed subscription failed - Not a valid feed.';
|
||||||
$this->showResult(false, $msg);
|
$this->showResult(false, $msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->testNotificationHandler($feed)) {
|
if (!$this->testNotificationHandler($feed)) {
|
||||||
$msg = 'Feed subscription failed - ' .
|
$msg = 'Feed subscription failed - ' .
|
||||||
'notification handler doesn\'t respond correctly.';
|
'notification handler doesn\'t respond correctly.';
|
||||||
$this->showResult(false, $msg);
|
$this->showResult(false, $msg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->feeds as $feed) {
|
foreach ($this->feeds as $feed) {
|
||||||
$this->saveSubscription($feed);
|
$this->saveSubscription($feed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: What to do about deleting stale subscriptions? 25 hours seems harsh.
|
// XXX: What to do about deleting stale subscriptions? 25 hours seems harsh.
|
||||||
// WordPress doesn't ever remove subscriptions.
|
// WordPress doesn't ever remove subscriptions.
|
||||||
|
@ -133,7 +133,7 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
$msg = 'Thanks for the registration. It worked. When the feed(s) update(s) we\'ll notify you. ' .
|
$msg = 'Thanks for the registration. It worked. When the feed(s) update(s) we\'ll notify you. ' .
|
||||||
' Don\'t forget to re-register after 24 hours, your subscription will expire in 25.';
|
' Don\'t forget to re-register after 24 hours, your subscription will expire in 25.';
|
||||||
|
|
||||||
$this->showResult(true, $msg);
|
$this->showResult(true, $msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateFeed($feed)
|
function validateFeed($feed)
|
||||||
|
@ -147,45 +147,45 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getFeeds()
|
function getFeeds()
|
||||||
{
|
{
|
||||||
$feeds = array();
|
$feeds = array();
|
||||||
|
|
||||||
while (list($key, $feed) = each ($this->args)) {
|
while (list($key, $feed) = each ($this->args)) {
|
||||||
if (preg_match('/^url\d*$/', $key)) {
|
if (preg_match('/^url\d*$/', $key)) {
|
||||||
$feeds[] = $feed;
|
$feeds[] = $feed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $feeds;
|
return $feeds;
|
||||||
}
|
}
|
||||||
|
|
||||||
function testNotificationHandler($feed)
|
function testNotificationHandler($feed)
|
||||||
{
|
{
|
||||||
common_debug("RSSCloudPlugin - testNotificationHandler()");
|
common_debug("RSSCloudPlugin - testNotificationHandler()");
|
||||||
|
|
||||||
$notifier = new RSSCloudNotifier();
|
$notifier = new RSSCloudNotifier();
|
||||||
|
|
||||||
if (isset($this->domain)) {
|
if (isset($this->domain)) {
|
||||||
|
|
||||||
//get
|
// 'domain' param set, so we have to use GET and send a challenge
|
||||||
|
|
||||||
$this->url = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path;
|
$endpoint = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path;
|
||||||
|
|
||||||
common_debug('domain set need to send challenge');
|
common_log(LOG_INFO, 'Testing notification handler with challenge: ' .
|
||||||
|
$endpoint);
|
||||||
|
|
||||||
|
return $notifier->challenge($endpoint, $feed);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
//post
|
|
||||||
|
|
||||||
$this->url = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path;
|
|
||||||
|
|
||||||
//return $notifier->postUpdate($endpoint, $feed);
|
|
||||||
|
|
||||||
}
|
$endpoint = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path;
|
||||||
|
|
||||||
return true;
|
common_log(LOG_INFO, 'Testing notification handler: ' .
|
||||||
|
$endpoint);
|
||||||
|
|
||||||
|
return $notifier->postUpdate($endpoint, $feed);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,6 +193,8 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
{
|
{
|
||||||
// We only do profile feeds
|
// We only do profile feeds
|
||||||
|
|
||||||
|
// XXX: Add cloud element to RSS 1.0 feeds
|
||||||
|
|
||||||
$path = common_path('api/statuses/user_timeline/');
|
$path = common_path('api/statuses/user_timeline/');
|
||||||
$valid = '%^' . $path . '(?<nickname>.*)\.rss$%';
|
$valid = '%^' . $path . '(?<nickname>.*)\.rss$%';
|
||||||
|
|
||||||
|
@ -209,37 +211,31 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
function saveSubscription($feed)
|
function saveSubscription($feed)
|
||||||
{
|
{
|
||||||
$user = $this->userFromFeed($feed);
|
$user = $this->userFromFeed($feed);
|
||||||
|
|
||||||
common_debug('user = ' . $user->id);
|
|
||||||
|
|
||||||
$sub = RSSCloudSubscription::getSubscription($user->id, $this->url);
|
$sub = RSSCloudSubscription::getSubscription($user->id, $this->url);
|
||||||
|
|
||||||
if ($sub) {
|
if ($sub) {
|
||||||
common_debug("already subscribed to that!");
|
common_debug("Already subscribed to that!");
|
||||||
} else {
|
} else {
|
||||||
common_debug('No feed for user ' . $user->id . ' notify: ' . $this->url);
|
|
||||||
|
$sub = new RSSCloudSubscription();
|
||||||
|
|
||||||
|
$sub->subscribed = $user->id;
|
||||||
|
$sub->url = $this->url;
|
||||||
|
$sub->created = common_sql_now();
|
||||||
|
|
||||||
|
// auto timestamp doesn't seem to work for me
|
||||||
|
|
||||||
|
// $sub->modified = common_sql_now();
|
||||||
|
|
||||||
|
if (!$sub->insert()) {
|
||||||
|
common_log_db_error($sub, 'INSERT', __FILE__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DB_DataObject::debugLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
common_debug('RSSPlugin - saveSubscription');
|
|
||||||
// turn debugging high
|
|
||||||
DB_DataObject::debugLevel(5);
|
|
||||||
|
|
||||||
$sub = new RSSCloudSubscription();
|
|
||||||
|
|
||||||
$sub->subscribed = $user->id;
|
|
||||||
$sub->url = $this->url;
|
|
||||||
$sub->created = common_sql_now();
|
|
||||||
|
|
||||||
// auto timestamp doesn't seem to work for me
|
|
||||||
|
|
||||||
$sub->modified = common_sql_now();
|
|
||||||
|
|
||||||
if (!$sub->insert()) {
|
|
||||||
common_log_db_error($sub, 'INSERT', __FILE__);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
DB_DataObject::debugLevel();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,5 +249,3 @@ class RSSCloudRequestNotifyAction extends Action
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user