<?php
-
/**
* This test class pretends to be an RSS aggregator. It logs notifications
* from the cloud.
}
header('Content-Type: text/xml');
- echo "<notifyResult success='true' msg='Thanks for the update.' challenge='" .
- $this->challenge . "' />\n";
+ echo $this->challenge;
} else {
header('Content-Type: text/xml');
echo '<notifyResult success=\'true\' msg=\'Thanks for the update.\' />' . "\n";
-
}
$this->ip = $_SERVER['REMOTE_ADDR'];
class RSSCloudNotifier {
- function postUpdate($endpoint, $feed) {
- common_debug("CloudNotifier->notify: $feed");
+ function challenge($endpoint, $feed)
+ {
+ $code = common_confirmation_code(128);
+ $params = array('url' => $feed, 'challenge' => $code);
+ $url = $endpoint . '?' . http_build_query($params);
+
+ try {
+ $client = new HTTPClient();
+ $response = $client->get($url);
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_INFO, 'RSSCloud plugin - failure testing notify handler ' .
+ $endpoint . ' - ' . $e->getMessage());
+ return false;
+ }
- $params = 'url=' . urlencode($feed);
+ // Check response is betweet 200 and 299 and body contains challenge data
- $result = $this->httpPost($endpoint, $params);
+ $status = $response->getStatus();
+ $body = $response->getBody();
- // XXX: Make all this use CurlClient (lib/curlclient.php)
+ if ($status >= 200 && $status < 300) {
- if ($result) {
- common_debug('RSSCloud plugin - success notifying cloud endpoint!');
+ 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_debug('RSSClous plugin - failure notifying cloud endpoint!');
+ common_log(LOG_INFO, 'RSSCloud plugin - ' .
+ "failure testing notify handler: $endpoint " .
+ ' - got HTTP ' . $status);
+ common_debug('body = ' . var_export($body, true));
+ return false;
}
-
- return $result;
}
- function userAgent()
- {
- return 'rssCloudPlugin/' . RSSCLOUDPLUGIN_VERSION .
- ' StatusNet/' . STATUSNET_VERSION;
- }
-
- private function httpPost($url, $params) {
-
- $options = array(CURLOPT_URL => $url,
- CURLOPT_POST => true,
- CURLOPT_POSTFIELDS => $params,
- CURLOPT_USERAGENT => $this->userAgent(),
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FAILONERROR => true,
- CURLOPT_HEADER => false,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_CONNECTTIMEOUT => 5,
- CURLOPT_TIMEOUT => 5);
-
- $ch = curl_init();
- curl_setopt_array($ch, $options);
+ function postUpdate($endpoint, $feed) {
- $response = curl_exec($ch);
+ $headers = array();
+ $postdata = array('url' => $feed);
- $info = curl_getinfo($ch);
+ try {
+ $client = new HTTPClient();
+ $response = $client->post($endpoint, $headers, $postdata);
+ } catch (HTTP_Request2_Exception $e) {
+ common_log(LOG_INFO, 'RSSCloud plugin - failure notifying ' .
+ $endpoint . ' that feed ' . $feed .
+ ' has changed: ' . $e->getMessage());
+ return false;
+ }
- curl_close($ch);
+ $status = $response->getStatus();
- if ($info['http_code'] == 200) {
+ if ($status >= 200 && $status < 300) {
+ common_log(LOG_INFO, 'RSSCloud plugin - success notifying ' .
+ $endpoint . ' that feed ' . $feed . ' has changed.');
return true;
} 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;
}
}
}
-
function onStartApiRss($action)
{
+ // XXX: Add RSS 1.0 user feeds
+
if (get_class($action) == 'ApiTimelineUserAction') {
$attrs = array('domain' => $this->domain,
$this->protocol = $this->arg('protocol');
$this->procedure = $this->arg('notifyProcedure');
$this->domain = $this->arg('domain');
-
+
$this->feeds = $this->getFeeds();
return true;
}
// 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
foreach ($this->feeds as $feed) {
-
+
if (!$this->validateFeed($feed)) {
$msg = 'Feed subscription failed - Not a valid feed.';
$this->showResult(false, $msg);
return;
}
-
+
if (!$this->testNotificationHandler($feed)) {
$msg = 'Feed subscription failed - ' .
'notification handler doesn\'t respond correctly.';
$this->showResult(false, $msg);
- return;
+ return;
}
-
+
}
foreach ($this->feeds as $feed) {
$this->saveSubscription($feed);
- }
+ }
// XXX: What to do about deleting stale subscriptions? 25 hours seems harsh.
// WordPress doesn't ever remove subscriptions.
$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.';
- $this->showResult(true, $msg);
+ $this->showResult(true, $msg);
}
function validateFeed($feed)
return true;
}
-
function getFeeds()
{
$feeds = array();
-
- while (list($key, $feed) = each ($this->args)) {
+
+ while (list($key, $feed) = each ($this->args)) {
if (preg_match('/^url\d*$/', $key)) {
$feeds[] = $feed;
- }
+ }
}
return $feeds;
}
function testNotificationHandler($feed)
- {
+ {
common_debug("RSSCloudPlugin - testNotificationHandler()");
-
+
$notifier = new RSSCloudNotifier();
-
+
if (isset($this->domain)) {
-
- //get
-
- $this->url = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path;
-
- common_debug('domain set need to send challenge');
-
+
+ // 'domain' param set, so we have to use GET and send a challenge
+
+ $endpoint = 'http://' . $this->domain . ':' . $this->port . '/' . $this->path;
+
+ common_log(LOG_INFO, 'Testing notification handler with challenge: ' .
+ $endpoint);
+
+ return $notifier->challenge($endpoint, $feed);
+
} 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);
+ }
}
{
// We only do profile feeds
+ // XXX: Add cloud element to RSS 1.0 feeds
+
$path = common_path('api/statuses/user_timeline/');
$valid = '%^' . $path . '(?<nickname>.*)\.rss$%';
function saveSubscription($feed)
{
$user = $this->userFromFeed($feed);
-
- common_debug('user = ' . $user->id);
-
+
$sub = RSSCloudSubscription::getSubscription($user->id, $this->url);
-
+
if ($sub) {
- common_debug("already subscribed to that!");
+ common_debug("Already subscribed to that!");
} else {
- common_debug('No feed for user ' . $user->id . ' notify: ' . $this->url);
- }
-
- 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;
+
+ $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();
}
- DB_DataObject::debugLevel();
-
+
return true;
}
}
-
-