From fa37967858c3c29000797e510e5f98aca8ab558f Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Wed, 28 Oct 2009 15:29:20 -0400 Subject: Rebuilt HTTPClient class as an extension of PEAR HTTP_Request2 package, adding redirect handling and convenience functions. Caching support will be added in future work after unit tests have been added. * extlib: add PEAR HTTP_Request2 0.4.1 alpha * extlib: update PEAR Net_URL2 to 0.3.0 beta for HTTP_Request2 compatibility * moved direct usage of CURL and file_get_contents to HTTPClient class, excluding external-sourced libraries Note some plugins haven't been tested yet. --- plugins/BlogspamNetPlugin.php | 17 +++--- plugins/LinkbackPlugin.php | 36 ++++++------ plugins/SimpleUrl/SimpleUrlPlugin.php | 11 +--- .../TwitterBridge/daemons/synctwitterfriends.php | 4 +- .../TwitterBridge/daemons/twitterstatusfetcher.php | 45 ++++++++------- plugins/TwitterBridge/twitter.php | 2 +- plugins/TwitterBridge/twitterauthorization.php | 2 +- plugins/TwitterBridge/twitterbasicauthclient.php | 66 +++++----------------- plugins/WikiHashtagsPlugin.php | 12 +--- 9 files changed, 73 insertions(+), 122 deletions(-) (limited to 'plugins') diff --git a/plugins/BlogspamNetPlugin.php b/plugins/BlogspamNetPlugin.php index c14569746..3bdc73556 100644 --- a/plugins/BlogspamNetPlugin.php +++ b/plugins/BlogspamNetPlugin.php @@ -22,6 +22,7 @@ * @category Plugin * @package StatusNet * @author Evan Prodromou + * @author Brion Vibber * @copyright 2009 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 * @link http://status.net/ @@ -69,14 +70,14 @@ class BlogspamNetPlugin extends Plugin { $args = $this->testArgs($notice); common_debug("Blogspamnet args = " . print_r($args, TRUE)); - $request = xmlrpc_encode_request('testComment', array($args)); - $context = stream_context_create(array('http' => array('method' => "POST", - 'header' => - "Content-Type: text/xml\r\n". - "User-Agent: " . $this->userAgent(), - 'content' => $request))); - $file = file_get_contents($this->baseUrl, false, $context); - $response = xmlrpc_decode($file); + $requestBody = xmlrpc_encode_request('testComment', array($args)); + + $request = new HTTPClient($this->baseUrl, HTTP_Request2::METHOD_POST); + $request->addHeader('Content-Type: text/xml'); + $request->setBody($requestBody); + $httpResponse = $request->send(); + + $response = xmlrpc_decode($httpResponse->getBody()); if (xmlrpc_is_fault($response)) { throw new ServerException("$response[faultString] ($response[faultCode])", 500); } else { diff --git a/plugins/LinkbackPlugin.php b/plugins/LinkbackPlugin.php index 60f7a60c7..0513687e9 100644 --- a/plugins/LinkbackPlugin.php +++ b/plugins/LinkbackPlugin.php @@ -129,27 +129,25 @@ class LinkbackPlugin extends Plugin } } - $request = xmlrpc_encode_request('pingback.ping', $args); - $context = stream_context_create(array('http' => array('method' => "POST", - 'header' => - "Content-Type: text/xml\r\n". - "User-Agent: " . $this->userAgent(), - 'content' => $request))); - $file = file_get_contents($endpoint, false, $context); - if (!$file) { + $request = new HTTPClient($endpoint, 'POST'); + $request->setHeader('User-Agent', $this->userAgent()); + $request->setHeader('Content-Type', 'text/xml'); + $request->setBody(xmlrpc_encode_request('pingback.ping', $args)); + try { + $response = $request->send(); + } catch (HTTP_Request2_Exception $e) { common_log(LOG_WARNING, - "Pingback request failed for '$url' ($endpoint)"); + "Pingback request failed for '$url' ($endpoint)"); + } + $response = xmlrpc_decode($response->getBody()); + if (xmlrpc_is_fault($response)) { + common_log(LOG_WARNING, + "Pingback error for '$url' ($endpoint): ". + "$response[faultString] ($response[faultCode])"); } else { - $response = xmlrpc_decode($file); - if (xmlrpc_is_fault($response)) { - common_log(LOG_WARNING, - "Pingback error for '$url' ($endpoint): ". - "$response[faultString] ($response[faultCode])"); - } else { - common_log(LOG_INFO, - "Pingback success for '$url' ($endpoint): ". - "'$response'"); - } + common_log(LOG_INFO, + "Pingback success for '$url' ($endpoint): ". + "'$response'"); } } diff --git a/plugins/SimpleUrl/SimpleUrlPlugin.php b/plugins/SimpleUrl/SimpleUrlPlugin.php index 82d772048..d59d63e47 100644 --- a/plugins/SimpleUrl/SimpleUrlPlugin.php +++ b/plugins/SimpleUrl/SimpleUrlPlugin.php @@ -65,15 +65,6 @@ class SimpleUrlPlugin extends Plugin class SimpleUrl extends ShortUrlApi { protected function shorten_imp($url) { - $curlh = curl_init(); - curl_setopt($curlh, CURLOPT_CONNECTTIMEOUT, 20); // # seconds to wait - curl_setopt($curlh, CURLOPT_USERAGENT, 'StatusNet'); - curl_setopt($curlh, CURLOPT_RETURNTRANSFER, true); - - curl_setopt($curlh, CURLOPT_URL, $this->service_url.urlencode($url)); - $short_url = curl_exec($curlh); - - curl_close($curlh); - return $short_url; + return $this->http_get($url); } } diff --git a/plugins/TwitterBridge/daemons/synctwitterfriends.php b/plugins/TwitterBridge/daemons/synctwitterfriends.php index ed2bf48a2..671e3c7af 100755 --- a/plugins/TwitterBridge/daemons/synctwitterfriends.php +++ b/plugins/TwitterBridge/daemons/synctwitterfriends.php @@ -152,8 +152,8 @@ class SyncTwitterFriendsDaemon extends ParallelizingDaemon $friends_ids = $client->friendsIds(); } catch (Exception $e) { common_log(LOG_WARNING, $this->name() . - ' - cURL error getting friend ids ' . - $e->getCode() . ' - ' . $e->getMessage()); + ' - error getting friend ids: ' . + $e->getMessage()); return $friends; } diff --git a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php index 81bbbc7c5..6c91b2860 100755 --- a/plugins/TwitterBridge/daemons/twitterstatusfetcher.php +++ b/plugins/TwitterBridge/daemons/twitterstatusfetcher.php @@ -109,12 +109,16 @@ class TwitterStatusFetcher extends ParallelizingDaemon $flink->find(); $flinks = array(); + common_log(LOG_INFO, "hello"); while ($flink->fetch()) { if (($flink->noticesync & FOREIGN_NOTICE_RECV) == FOREIGN_NOTICE_RECV) { $flinks[] = clone($flink); + common_log(LOG_INFO, "sync: foreign id $flink->foreign_id"); + } else { + common_log(LOG_INFO, "nothing to sync"); } } @@ -515,31 +519,34 @@ class TwitterStatusFetcher extends ParallelizingDaemon return $id; } + /** + * Fetch a remote avatar image and save to local storage. + * + * @param string $url avatar source URL + * @param string $filename bare local filename for download + * @return bool true on success, false on failure + */ function fetchAvatar($url, $filename) { - $avatarfile = Avatar::path($filename); + common_debug($this->name() . " - Fetching Twitter avatar: $url"); - $out = fopen($avatarfile, 'wb'); - if (!$out) { - common_log(LOG_WARNING, $this->name() . - " - Couldn't open file $filename"); + $request = new HTTPClient($url, 'GET', array( + 'follow_redirects' => true, + )); + $data = $request->get(); + if ($data) { + $avatarfile = Avatar::path($filename); + $ok = file_put_contents($avatarfile, $data); + if (!$ok) { + common_log(LOG_WARNING, $this->name() . + " - Couldn't open file $filename"); + return false; + } + } else { return false; } - common_debug($this->name() . " - Fetching Twitter avatar: $url"); - - $ch = curl_init(); - curl_setopt($ch, CURLOPT_URL, $url); - curl_setopt($ch, CURLOPT_FILE, $out); - curl_setopt($ch, CURLOPT_BINARYTRANSFER, true); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0); - $result = curl_exec($ch); - curl_close($ch); - - fclose($out); - - return $result; + return true; } } diff --git a/plugins/TwitterBridge/twitter.php b/plugins/TwitterBridge/twitter.php index 1a5248a9b..3c6803e49 100644 --- a/plugins/TwitterBridge/twitter.php +++ b/plugins/TwitterBridge/twitter.php @@ -215,7 +215,7 @@ function broadcast_basicauth($notice, $flink) try { $status = $client->statusesUpdate($statustxt); - } catch (BasicAuthCurlException $e) { + } catch (HTTP_Request2_Exception $e) { return process_error($e, $flink); } diff --git a/plugins/TwitterBridge/twitterauthorization.php b/plugins/TwitterBridge/twitterauthorization.php index 2a93ff13e..f1daefab1 100644 --- a/plugins/TwitterBridge/twitterauthorization.php +++ b/plugins/TwitterBridge/twitterauthorization.php @@ -125,7 +125,7 @@ class TwitterauthorizationAction extends Action $auth_link = $client->getAuthorizeLink($req_tok); - } catch (TwitterOAuthClientException $e) { + } catch (OAuthClientException $e) { $msg = sprintf('OAuth client cURL error - code: %1s, msg: %2s', $e->getCode(), $e->getMessage()); $this->serverError(_('Couldn\'t link your Twitter account.')); diff --git a/plugins/TwitterBridge/twitterbasicauthclient.php b/plugins/TwitterBridge/twitterbasicauthclient.php index 1040d72fb..e4cae7373 100644 --- a/plugins/TwitterBridge/twitterbasicauthclient.php +++ b/plugins/TwitterBridge/twitterbasicauthclient.php @@ -31,26 +31,6 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); } -/** - * Exception wrapper for cURL errors - * - * @category Integration - * @package StatusNet - * @author Adrian Lang - * @author Brenda Wallace - * @author Craig Andrews - * @author Dan Moore - * @author Evan Prodromou - * @author mEDI - * @author Sarven Capadisli - * @author Zach Copley * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://status.net/ - * - */ -class BasicAuthCurlException extends Exception -{ -} - /** * Class for talking to the Twitter API with HTTP Basic Auth. * @@ -198,45 +178,27 @@ class TwitterBasicAuthClient */ function httpRequest($url, $params = null, $auth = true) { - $options = array( - CURLOPT_RETURNTRANSFER => true, - CURLOPT_FAILONERROR => true, - CURLOPT_HEADER => false, - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_USERAGENT => 'StatusNet', - CURLOPT_CONNECTTIMEOUT => 120, - CURLOPT_TIMEOUT => 120, - CURLOPT_HTTPAUTH => CURLAUTH_ANY, - CURLOPT_SSL_VERIFYPEER => false, - - // Twitter is strict about accepting invalid "Expect" headers - - CURLOPT_HTTPHEADER => array('Expect:') - ); + $request = new HTTPClient($url, 'GET', array( + 'follow_redirects' => true, + 'connect_timeout' => 120, + 'timeout' => 120, + 'ssl_verifypeer' => false, + )); + + // Twitter is strict about accepting invalid "Expect" headers + $request->setHeader('Expect', ''); if (isset($params)) { - $options[CURLOPT_POST] = true; - $options[CURLOPT_POSTFIELDS] = $params; + $request->setMethod('POST'); + $request->addPostParameter($params); } if ($auth) { - $options[CURLOPT_USERPWD] = $this->screen_name . - ':' . $this->password; + $request->setAuth($this->screen_name, $this->password); } - $ch = curl_init($url); - curl_setopt_array($ch, $options); - $response = curl_exec($ch); - - if ($response === false) { - $msg = curl_error($ch); - $code = curl_errno($ch); - throw new BasicAuthCurlException($msg, $code); - } - - curl_close($ch); - - return $response; + $response = $request->send(); + return $response->getBody(); } } diff --git a/plugins/WikiHashtagsPlugin.php b/plugins/WikiHashtagsPlugin.php index 0c5649aa4..a9e675f5c 100644 --- a/plugins/WikiHashtagsPlugin.php +++ b/plugins/WikiHashtagsPlugin.php @@ -68,10 +68,8 @@ class WikiHashtagsPlugin extends Plugin $editurl = sprintf('http://hashtags.wikia.com/index.php?title=%s&action=edit', urlencode($tag)); - $context = stream_context_create(array('http' => array('method' => "GET", - 'header' => - "User-Agent: " . $this->userAgent()))); - $html = @file_get_contents($url, false, $context); + $request = new HTTPClient($url); + $html = $request->get(); $action->elementStart('div', array('id' => 'wikihashtags', 'class' => 'section')); @@ -100,10 +98,4 @@ class WikiHashtagsPlugin extends Plugin return true; } - - function userAgent() - { - return 'WikiHashtagsPlugin/'.WIKIHASHTAGSPLUGIN_VERSION . - ' StatusNet/' . STATUSNET_VERSION; - } } -- cgit v1.2.3-54-g00ecf