Plugin now checks notify handlers before registering subscriptions

This commit is contained in:
Zach Copley 2009-12-07 09:10:04 +00:00
parent 4e07d9eeec
commit 61804bb7bb
4 changed files with 113 additions and 102 deletions

View File

@ -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'];

View File

@ -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;
} }
} }
} }

View File

@ -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,

View File

@ -147,7 +147,6 @@ class RSSCloudRequestNotifyAction extends Action
return true; return true;
} }
function getFeeds() function getFeeds()
{ {
$feeds = array(); $feeds = array();
@ -169,30 +168,33 @@ class RSSCloudRequestNotifyAction extends Action
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 $endpoint = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path;
$this->url = 'http://' . $this->ip . ':' . $this->port . '/' . $this->path; common_log(LOG_INFO, 'Testing notification handler: ' .
$endpoint);
//return $notifier->postUpdate($endpoint, $feed);
return $notifier->postUpdate($endpoint, $feed);
} }
return true;
} }
function userFromFeed($feed) function userFromFeed($feed)
{ {
// 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$%';
@ -210,36 +212,30 @@ class RSSCloudRequestNotifyAction extends Action
{ {
$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
} }