From 2dec8895a99070281c2a13991b484c96c6e0cbed Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Wed, 10 Oct 2018 21:08:43 +0200 Subject: [PATCH 1/5] Curl Response Refactoring - extended Curl to parse Curl Response - refactored Network::curl() - replaced every Network::curl() execution with the new Curl container --- mod/admin.php | 3 +- mod/feedtest.php | 3 +- mod/ostatus_subscribe.php | 10 +- mod/parse_url.php | 6 +- src/Core/ACL.php | 6 +- src/Model/APContact.php | 6 +- src/Model/GContact.php | 6 +- src/Model/Profile.php | 2 +- src/Module/Magic.php | 6 +- src/Network/Curl.php | 280 +++++++++++++++++++++++++++---- src/Network/Probe.php | 50 +++--- src/Protocol/ActivityPub.php | 6 +- src/Protocol/DFRN.php | 24 +-- src/Protocol/OStatus.php | 56 +++---- src/Protocol/PortableContact.php | 166 +++++++++--------- src/Util/ExAuth.php | 8 +- src/Util/Network.php | 177 +++---------------- src/Util/ParseUrl.php | 12 +- src/Worker/DiscoverPoCo.php | 6 +- src/Worker/OnePoll.php | 15 +- 20 files changed, 466 insertions(+), 382 deletions(-) diff --git a/mod/admin.php b/mod/admin.php index bd5e9ecea..372210c40 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -2567,6 +2567,5 @@ function admin_page_features(App $a) function admin_page_server_vital() { // Fetch the host-meta to check if this really is a vital server - $serverret = Network::curl(System::baseUrl() . '/.well-known/host-meta'); - return $serverret["success"]; + return Network::curl(System::baseUrl() . '/.well-known/host-meta')->isSuccess(); } diff --git a/mod/feedtest.php b/mod/feedtest.php index d9a9abb91..e75e7a1b8 100644 --- a/mod/feedtest.php +++ b/mod/feedtest.php @@ -32,8 +32,7 @@ function feedtest_content(App $a) $contact = DBA::selectFirst('contact', [], ['id' => $contact_id]); - $ret = Network::curl($contact['poll']); - $xml = $ret['body']; + $xml = Network::fetchUrl($contact['poll']); $dummy = null; $import_result = Feed::import($xml, $importer, $contact, $dummy, true); diff --git a/mod/ostatus_subscribe.php b/mod/ostatus_subscribe.php index ffaa6791f..7012ecd4b 100644 --- a/mod/ostatus_subscribe.php +++ b/mod/ostatus_subscribe.php @@ -44,14 +44,14 @@ function ostatus_subscribe_content(App $a) { $api = $contact["baseurl"]."/api/"; // Fetching friends - $data = Network::curl($api."statuses/friends.json?screen_name=".$contact["nick"]); + $curlResult = Network::curl($api."statuses/friends.json?screen_name=".$contact["nick"]); - if (!$data["success"]) { + if (!$curlResult->isSuccess()) { PConfig::delete($uid, "ostatus", "legacy_contact"); return $o.L10n::t("Couldn't fetch friends for contact."); } - PConfig::set($uid, "ostatus", "legacy_friends", $data["body"]); + PConfig::set($uid, "ostatus", "legacy_friends", $curlResult->getBody()); } $friends = json_decode(PConfig::get($uid, "ostatus", "legacy_friends")); @@ -72,8 +72,8 @@ function ostatus_subscribe_content(App $a) { $o .= "

".$counter."/".$total.": ".$url; - $data = Probe::uri($url); - if ($data["network"] == Protocol::OSTATUS) { + $curlResult = Probe::uri($url); + if ($curlResult["network"] == Protocol::OSTATUS) { $result = Contact::createFromProbe($uid, $url, true, Protocol::OSTATUS); if ($result["success"]) { $o .= " - ".L10n::t("success"); diff --git a/mod/parse_url.php b/mod/parse_url.php index ebe34875b..40eddc3bd 100644 --- a/mod/parse_url.php +++ b/mod/parse_url.php @@ -60,12 +60,12 @@ function parse_url_content(App $a) // the URL with the corresponding BBCode media tag $redirects = 0; // Fetch the header of the URL - $result = Network::curl($url, false, $redirects, ['novalidate' => true, 'nobody' => true]); + $curlResponse = Network::curl($url, false, $redirects, ['novalidate' => true, 'nobody' => true]); - if ($result['success']) { + if ($curlResponse->isSuccess()) { // Convert the header fields into an array $hdrs = []; - $h = explode("\n", $result['header']); + $h = explode("\n", $curlResponse->getHeader()); foreach ($h as $l) { $header = array_map('trim', explode(':', trim($l), 2)); if (count($header) == 2) { diff --git a/src/Core/ACL.php b/src/Core/ACL.php index 0b48895d6..8f630409f 100644 --- a/src/Core/ACL.php +++ b/src/Core/ACL.php @@ -344,9 +344,9 @@ class ACL extends BaseObject $a = self::getApp(); $p = $a->pager['page'] != 1 ? '&p=' . $a->pager['page'] : ''; - $response = Network::curl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search)); - if ($response['success']) { - $lsearch = json_decode($response['body'], true); + $curlResult = Network::curl(get_server() . '/lsearch?f=' . $p . '&search=' . urlencode($search)); + if ($curlResult->isSuccess()) { + $lsearch = json_decode($curlResult->getBody(), true); if (!empty($lsearch['results'])) { $return = $lsearch['results']; } diff --git a/src/Model/APContact.php b/src/Model/APContact.php index ce66ec4c6..4593e0377 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -33,12 +33,12 @@ class APContact extends BaseObject $webfinger = 'https://' . $addr_parts[1] . '/.well-known/webfinger?resource=acct:' . urlencode($addr); - $ret = Network::curl($webfinger, false, $redirects, ['accept_content' => 'application/jrd+json,application/json']); - if (!$ret['success'] || empty($ret['body'])) { + $curlResult = Network::curl($webfinger, false, $redirects, ['accept_content' => 'application/jrd+json,application/json']); + if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { return false; } - $data = json_decode($ret['body'], true); + $data = json_decode($curlResult->getBody(), true); if (empty($data['links'])) { return false; diff --git a/src/Model/GContact.php b/src/Model/GContact.php index f979abef5..26cb11175 100644 --- a/src/Model/GContact.php +++ b/src/Model/GContact.php @@ -957,12 +957,12 @@ class GContact $url = $server."/main/statistics"; - $result = Network::curl($url); - if (!$result["success"]) { + $curlResult = Network::curl($url); + if (!$curlResult->isSuccess()) { return false; } - $statistics = json_decode($result["body"]); + $statistics = json_decode($curlResult->getBody()); if (!empty($statistics->config)) { if ($statistics->config->instance_with_ssl) { diff --git a/src/Model/Profile.php b/src/Model/Profile.php index a1274c1ae..28736750b 100644 --- a/src/Model/Profile.php +++ b/src/Model/Profile.php @@ -1056,7 +1056,7 @@ class Profile if ($basepath != System::baseUrl() && !strstr($dest, '/magic') && !strstr($dest, '/rmagic')) { $magic_path = $basepath . '/magic' . '?f=&owa=1&dest=' . $dest; $serverret = Network::curl($magic_path); - if (!empty($serverret['success'])) { + if ($serverret->isSuccess()) { goaway($magic_path); } } diff --git a/src/Module/Magic.php b/src/Module/Magic.php index 042a9581d..768fe69eb 100644 --- a/src/Module/Magic.php +++ b/src/Module/Magic.php @@ -82,10 +82,10 @@ class Magic extends BaseModule ); // Try to get an authentication token from the other instance. - $x = Network::curl($basepath . '/owa', false, $redirects, ['headers' => $headers]); + $curlResult = Network::curl($basepath . '/owa', false, $redirects, ['headers' => $headers]); - if ($x['success']) { - $j = json_decode($x['body'], true); + if ($curlResult->isSuccess()) { + $j = json_decode($curlResult->getBody(), true); if ($j['success']) { $token = ''; diff --git a/src/Network/Curl.php b/src/Network/Curl.php index bc04f6b4e..f67104bc0 100644 --- a/src/Network/Curl.php +++ b/src/Network/Curl.php @@ -3,15 +3,17 @@ namespace Friendica\Network; +use Friendica\Network\HTTPException\InternalServerErrorException; + /** * A content class for Curl call results */ class Curl { /** - * @var string the Code of the Curl call + * @var int HTTP return code or 0 if timeout or failure */ - private $code; + private $returnCode; /** * @var string the content type of the Curl call @@ -19,25 +21,179 @@ class Curl private $contentType; /** - * @var string the headers of the Curl call + * @var string the HTTP headers of the Curl call */ - private $headers; + private $header; - public function __construct($code = '', $contentType = '', $headers = '') + /** + * @var boolean true (if HTTP 2xx result) or false + */ + private $isSuccess; + + /** + * @var string the URL which was called + */ + private $url; + + /** + * @var string in case of redirect, content was finally retrieved from this URL + */ + private $redirectUrl; + + /** + * @var string fetched content + */ + private $body; + + /** + * @var array some informations about the fetched data + */ + private $info; + + /** + * @var boolean true if the URL has a redirect + */ + private $isRedirectUrl; + + /** + * @var boolean true if the curl request timed out + */ + private $isTimeout; + + /** + * @var int optional error numer + */ + private $errorNumber; + + /** + * @var string optional error message + */ + private $error; + + /** + * Creates an errored CURL response + * + * @param string $url optional URL + * + * @return Curl a CURL with error response + */ + public static function createErrorCurl($url = '') { - $this->code = $code; - $this->contentType = $contentType; - $this->headers = $headers; + return new Curl( + $url, + '', + ['http_code' => 0] + ); } /** - * Sets the Curl Code + * Curl constructor. + * @param string $url the URL which was called + * @param string $result the result of the curl execution + * @param array $info an additional info array + * @param int $errorNumber the error number or 0 (zero) if no error + * @param string $error the error message or '' (the empty string) if no * - * @param string $code The Curl Code + * @throws InternalServerErrorException when HTTP code of the CURL response is missing */ - public function setCode($code) + public function __construct($url, $result, $info, $errorNumber = 0, $error = '') { - $this->code = $code; + if (empty($info['http_code'])) { + throw new InternalServerErrorException('CURL response doesn\'t contains a response HTTP code'); + } + + $this->returnCode = $info['http_code']; + $this->url = $url; + $this->info = $info; + $this->errorNumber = $errorNumber; + $this->error = $error; + + logger($url . ': ' . $this->returnCode . " " . $result, LOGGER_DATA); + + $this->parseBodyHeader($result); + $this->checkSuccess(); + $this->checkRedirect(); + $this->checkInfo(); + } + + private function parseBodyHeader($result) + { + // Pull out multiple headers, e.g. proxy and continuation headers + // allow for HTTP/2.x without fixing code + + $header = ''; + $base = $result; + while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) { + $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); + $header .= $chunk; + $base = substr($base, strlen($chunk)); + } + + $this->body = substr($result, strlen($header)); + $this->header = $header; + } + + private function checkSuccess() + { + $this->isSuccess = ((($this->returnCode >= 200 && $this->returnCode <= 299) || !empty($this->errorNumber)) ? true : false); + + if (!$this->isSuccess) { + logger('error: ' . $this->url . ': ' . $this->returnCode . ' - ' . $this->error, LOGGER_DEBUG); + logger('debug: ' . print_r($this->info, true), LOGGER_DATA); + } + + if (!$this->isSuccess && $this->errorNumber == CURLE_OPERATION_TIMEDOUT) { + $this->isTimeout = true; + } else { + $this->isTimeout = false; + } + } + + private function checkRedirect() + { + if (empty($this->info['url'])) { + $this->redirectUrl = ''; + } else { + $this->redirectUrl = $this->info['url']; + } + + if ($this->returnCode == 301 || $this->returnCode == 302 || $this->returnCode == 303 || $this->returnCode== 307) { + $new_location_info = (empty($this->info['redirect_url']) ? '' : @parse_url($this->info['redirect_url'])); + $old_location_info = (empty($this->info['url'] ? '' : @parse_url($this->info['url'])); + + $this->redirectUrl = $new_location_info; + + if (empty($new_location_info['path']) && !empty($new_location_info['host'])) { + $this->redirectUrl = $new_location_info['scheme'] . '://' . $new_location_info['host'] . $old_location_info['path']; + } + + $matches = []; + + if (preg_match('/(Location:|URI:)(.*?)\n/i', $this->header, $matches)) { + $this->redirectUrl = trim(array_pop($matches)); + } + if (strpos($this->redirectUrl, '/') === 0) { + $this->redirectUrl = $old_location_info["scheme"] . "://" . $old_location_info["host"] . $this->redirectUrl; + } + $old_location_query = @parse_url($this->url, PHP_URL_QUERY); + + if ($old_location_query != '') { + $this->redirectUrl .= '?' . $old_location_query; + } + + $this->isRedirectUrl = filter_var($this->redirectUrl, FILTER_VALIDATE_URL); + } else { + $this->isRedirectUrl = false; + } + } + + private function checkInfo() + { + if (isset($this->info['content_type'])) { + $this->contentType = $this->info['content_type']; + } else { + $this->contentType = ''; + } } /** @@ -45,19 +201,9 @@ class Curl * * @return string The Curl Code */ - public function getCode() + public function getReturnCode() { - return $this->code; - } - - /** - * Sets the Curl Content Type - * - * @param string $content_type The Curl Content Type - */ - public function setContentType($content_type) - { - $this->contentType = $content_type; + return $this->returnCode; } /** @@ -70,23 +216,85 @@ class Curl return $this->contentType; } - /** - * Sets the Curl headers - * - * @param string $headers the Curl headers - */ - public function setHeaders($headers) - { - $this->headers = $headers; - } - /** * Returns the Curl headers * * @return string the Curl headers */ - public function getHeaders() + public function getHeader() { - return $this->headers; + return $this->header; + } + + /** + * @return bool + */ + public function isSuccess() + { + return $this->isSuccess; + } + + /** + * @return string + */ + public function getUrl() + { + return $this->url; + } + + /** + * @return string + */ + public function getRedirectUrl() + { + return $this->redirectUrl; + } + + /** + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * @return array + */ + public function getInfo() + { + return $this->info; + } + + /** + * @return bool + */ + public function isRedirectUrl() + { + return $this->isRedirectUrl; + } + + /** + * @return int + */ + public function getErrorNumber() + { + return $this->errorNumber; + } + + /** + * @return string + */ + public function getError() + { + return $this->error; + } + + /** + * @return bool + */ + public function isTimeout() + { + return $this->isTimeout; } } diff --git a/src/Network/Probe.php b/src/Network/Probe.php index 5a03a71f7..7f80be4e4 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -112,20 +112,20 @@ class Probe logger("Probing for ".$host, LOGGER_DEBUG); $xrd = null; - $ret = Network::curl($ssl_url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); - if ($ret['success']) { - $xml = $ret['body']; + $curlResult = Network::curl($ssl_url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); + if ($curlResult->isSuccess()) { + $xml = $curlResult->getBody(); $xrd = XML::parseString($xml, false); $host_url = 'https://'.$host; } if (!is_object($xrd)) { - $ret = Network::curl($url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { - logger("Probing timeout for ".$url, LOGGER_DEBUG); + $curlResult = Network::curl($url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); + if ($curlResult->isTimeout()) { + logger("Probing timeout for " . $url, LOGGER_DEBUG); return false; } - $xml = $ret['body']; + $xml = $curlResult->getBody(); $xrd = XML::parseString($xml, false); $host_url = 'http://'.$host; } @@ -742,11 +742,11 @@ class Probe $xrd_timeout = Config::get('system', 'xrd_timeout', 20); $redirects = 0; - $ret = Network::curl($url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => $type]); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($url, false, $redirects, ['timeout' => $xrd_timeout, 'accept_content' => $type]); + if ($curlResult->isTimeout()) { return false; } - $data = $ret['body']; + $data = $curlResult->getBody(); $webfinger = json_decode($data, true); if (is_array($webfinger)) { @@ -809,11 +809,11 @@ class Probe */ private static function pollNoscrape($noscrape_url, $data) { - $ret = Network::curl($noscrape_url); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($noscrape_url); + if ($curlResult->isTimeout()) { return false; } - $content = $ret['body']; + $content = $curlResult->getBody(); if (!$content) { logger("Empty body for ".$noscrape_url, LOGGER_DEBUG); return false; @@ -1054,11 +1054,11 @@ class Probe */ private static function pollHcard($hcard_url, $data, $dfrn = false) { - $ret = Network::curl($hcard_url); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($hcard_url); + if ($curlResult->isTimeout()) { return false; } - $content = $ret['body']; + $content = $curlResult->getBody(); if (!$content) { return false; } @@ -1301,11 +1301,11 @@ class Probe $pubkey = substr($pubkey, 5); } } elseif (normalise_link($pubkey) == 'http://') { - $ret = Network::curl($pubkey); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($pubkey); + if ($curlResult->isTimeout()) { return false; } - $pubkey = $ret['body']; + $pubkey = $curlResult['body']; } $key = explode(".", $pubkey); @@ -1333,11 +1333,11 @@ class Probe } // Fetch all additional data from the feed - $ret = Network::curl($data["poll"]); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($data["poll"]); + if (!empty($curlResult["errno"]) && ($curlResult['errno'] == CURLE_OPERATION_TIMEDOUT)) { return false; } - $feed = $ret['body']; + $feed = $curlResult['body']; $dummy1 = null; $dummy2 = null; $dummy2 = null; @@ -1543,11 +1543,11 @@ class Probe */ private static function feed($url, $probe = true) { - $ret = Network::curl($url); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + $curlResult = Network::curl($url); + if ($curlResult->isTimeout()) { return false; } - $feed = $ret['body']; + $feed = $curlResult->getBody(); $dummy1 = $dummy2 = $dummy3 = null; $feed_data = Feed::import($feed, $dummy1, $dummy2, $dummy3, true); diff --git a/src/Protocol/ActivityPub.php b/src/Protocol/ActivityPub.php index b4668e915..0af8ee5e3 100644 --- a/src/Protocol/ActivityPub.php +++ b/src/Protocol/ActivityPub.php @@ -58,12 +58,12 @@ class ActivityPub */ public static function fetchContent($url) { - $ret = Network::curl($url, false, $redirects, ['accept_content' => 'application/activity+json, application/ld+json']); - if (!$ret['success'] || empty($ret['body'])) { + $curlResult = Network::curl($url, false, $redirects, ['accept_content' => 'application/activity+json, application/ld+json']); + if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { return false; } - return json_decode($ret['body'], true); + return json_decode($curlResult->getBody(), true); } /** diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index ff468fb2c..3a001de04 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1170,10 +1170,10 @@ class DFRN // At first try the Diaspora transport layer if (!$dissolve && !$legacy_transport) { - $ret = self::transmit($owner, $contact, $atom); - if ($ret >= 200) { - logger('Delivery via Diaspora transport layer was successful with status ' . $ret); - return $ret; + $curlResult = self::transmit($owner, $contact, $atom); + if ($curlResult >= 200) { + logger('Delivery via Diaspora transport layer was successful with status ' . $curlResult); + return $curlResult; } } @@ -1211,16 +1211,16 @@ class DFRN logger('dfrn_deliver: ' . $url); - $ret = Network::curl($url); + $curlResult = Network::curl($url); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + if ($curlResult->isTimeout()) { Contact::markForArchival($contact); return -2; // timed out } - $xml = $ret['body']; + $xml = $curlResult->getBody(); - $curl_stat = Network::getCurl()->getCode(); + $curl_stat = $curlResult->getReturnCode(); if (empty($curl_stat)) { Contact::markForArchival($contact); return -3; // timed out @@ -1368,17 +1368,19 @@ class DFRN logger('dfrn_deliver: ' . "SENDING: " . print_r($postvars, true), LOGGER_DATA); - $xml = Network::post($contact['notify'], $postvars); + $postResult = Network::post($contact['notify'], $postvars); + + $xml = $postResult->getBody(); logger('dfrn_deliver: ' . "RECEIVED: " . $xml, LOGGER_DATA); - $curl_stat = Network::getCurl()->getCode(); + $curl_stat = $postResult->getReturnCode(); if (empty($curl_stat) || empty($xml)) { Contact::markForArchival($contact); return -9; // timed out } - if (($curl_stat == 503) && stristr(Network::getCurl()->getHeaders(), 'retry-after')) { + if (($curl_stat == 503) && stristr($postResult->getHeader(), 'retry-after')) { Contact::markForArchival($contact); return -10; } diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index b9090d0e4..f589d3827 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -736,21 +736,21 @@ class OStatus self::$conv_list[$conversation] = true; - $conversation_data = Network::curl($conversation, false, $redirects, ['accept_content' => 'application/atom+xml, text/html']); + $curlResult = Network::curl($conversation, false, $redirects, ['accept_content' => 'application/atom+xml, text/html']); - if (!$conversation_data['success']) { + if (!$curlResult->isSuccess()) { return; } $xml = ''; - if (stristr($conversation_data['header'], 'Content-Type: application/atom+xml')) { - $xml = $conversation_data['body']; + if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { + $xml = $curlResult->getBody(); } if ($xml == '') { $doc = new DOMDocument(); - if (!@$doc->loadHTML($conversation_data['body'])) { + if (!@$doc->loadHTML($curlResult->getBody())) { return; } $xpath = new DOMXPath($doc); @@ -767,8 +767,8 @@ class OStatus if ($file != '') { $conversation_atom = Network::curl($attribute['href']); - if ($conversation_atom['success']) { - $xml = $conversation_atom['body']; + if ($conversation_atom->isSuccess()) { + $xml = $conversation_atom->getBody(); } } } @@ -880,15 +880,15 @@ class OStatus return; } - $self_data = Network::curl($self); + $curlResult = Network::curl($self); - if (!$self_data['success']) { + if (!$curlResult->isSuccess()) { return; } // We reformat the XML to make it better readable $doc = new DOMDocument(); - $doc->loadXML($self_data['body']); + $doc->loadXML($curlResult->getBody()); $doc->preserveWhiteSpace = false; $doc->formatOutput = true; $xml = $doc->saveXML(); @@ -925,22 +925,22 @@ class OStatus } $stored = false; - $related_data = Network::curl($related, false, $redirects, ['accept_content' => 'application/atom+xml, text/html']); + $curlResult = Network::curl($related, false, $redirects, ['accept_content' => 'application/atom+xml, text/html']); - if (!$related_data['success']) { + if (!$curlResult->isSuccess()) { return; } $xml = ''; - if (stristr($related_data['header'], 'Content-Type: application/atom+xml')) { - logger('Directly fetched XML for URI '.$related_uri, LOGGER_DEBUG); - $xml = $related_data['body']; + if (stristr($curlResult->getHeader(), 'Content-Type: application/atom+xml')) { + logger('Directly fetched XML for URI ' . $related_uri, LOGGER_DEBUG); + $xml = $curlResult->getBody(); } if ($xml == '') { $doc = new DOMDocument(); - if (!@$doc->loadHTML($related_data['body'])) { + if (!@$doc->loadHTML($curlResult->getBody())) { return; } $xpath = new DOMXPath($doc); @@ -956,11 +956,11 @@ class OStatus } } if ($atom_file != '') { - $related_atom = Network::curl($atom_file); + $curlResult = Network::curl($atom_file); - if ($related_atom['success']) { - logger('Fetched XML for URI '.$related_uri, LOGGER_DEBUG); - $xml = $related_atom['body']; + if ($curlResult->isSuccess()) { + logger('Fetched XML for URI ' . $related_uri, LOGGER_DEBUG); + $xml = $curlResult->getBody(); } } } @@ -968,22 +968,22 @@ class OStatus // Workaround for older GNU Social servers if (($xml == '') && strstr($related, '/notice/')) { - $related_atom = Network::curl(str_replace('/notice/', '/api/statuses/show/', $related).'.atom'); + $curlResult = Network::curl(str_replace('/notice/', '/api/statuses/show/', $related).'.atom'); - if ($related_atom['success']) { - logger('GNU Social workaround to fetch XML for URI '.$related_uri, LOGGER_DEBUG); - $xml = $related_atom['body']; + if ($curlResult->isSuccess()) { + logger('GNU Social workaround to fetch XML for URI ' . $related_uri, LOGGER_DEBUG); + $xml = $curlResult->getBody(); } } // Even more worse workaround for GNU Social ;-) if ($xml == '') { $related_guess = OStatus::convertHref($related_uri); - $related_atom = Network::curl(str_replace('/notice/', '/api/statuses/show/', $related_guess).'.atom'); + $curlResult = Network::curl(str_replace('/notice/', '/api/statuses/show/', $related_guess).'.atom'); - if ($related_atom['success']) { - logger('GNU Social workaround 2 to fetch XML for URI '.$related_uri, LOGGER_DEBUG); - $xml = $related_atom['body']; + if ($curlResult->isSuccess()) { + logger('GNU Social workaround 2 to fetch XML for URI ' . $related_uri, LOGGER_DEBUG); + $xml = $curlResult->getBody(); } } diff --git a/src/Protocol/PortableContact.php b/src/Protocol/PortableContact.php index a5932e158..8ce732bfc 100644 --- a/src/Protocol/PortableContact.php +++ b/src/Protocol/PortableContact.php @@ -290,8 +290,8 @@ class PortableContact } // Fetch the host-meta to check if this really is a server - $serverret = Network::curl($server_url."/.well-known/host-meta"); - if (!$serverret["success"]) { + $curlResult = Network::curl($server_url."/.well-known/host-meta"); + if (!$curlResult->isSuccess()) { return ""; } @@ -370,10 +370,10 @@ class PortableContact $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", DBA::escape(normalise_link($server_url))); if ($server) { - $noscraperet = Network::curl($server[0]["noscrape"]."/".$gcontacts[0]["nick"]); + $curlResult = Network::curl($server[0]["noscrape"]."/".$gcontacts[0]["nick"]); - if ($noscraperet["success"] && ($noscraperet["body"] != "")) { - $noscrape = json_decode($noscraperet["body"], true); + if ($curlResult->isSuccess() && ($curlResult->getBody() != "")) { + $noscrape = json_decode($curlResult->getBody(), true); if (is_array($noscrape)) { $contact["network"] = $server[0]["network"]; @@ -484,9 +484,9 @@ class PortableContact GContact::update($contact); - $feedret = Network::curl($data["poll"]); + $curlResult = Network::curl($data["poll"]); - if (!$feedret["success"]) { + if (!$curlResult->isSuccess()) { $fields = ['last_failure' => DateTimeFormat::utcNow()]; DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); @@ -496,7 +496,7 @@ class PortableContact $doc = new DOMDocument(); /// @TODO Avoid error supression here - @$doc->loadXML($feedret["body"]); + @$doc->loadXML($curlResult->getBody()); $xpath = new DOMXPath($doc); $xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom"); @@ -645,12 +645,12 @@ class PortableContact */ private static function fetchNodeinfo($server_url) { - $serverret = Network::curl($server_url."/.well-known/nodeinfo"); - if (!$serverret["success"]) { + $curlResult = Network::curl($server_url."/.well-known/nodeinfo"); + if (!$curlResult->isSuccess()) { return false; } - $nodeinfo = json_decode($serverret['body'], true); + $nodeinfo = json_decode($curlResult->getBody(), true); if (!is_array($nodeinfo) || !isset($nodeinfo['links'])) { return false; @@ -698,13 +698,13 @@ class PortableContact */ private static function parseNodeinfo1($nodeinfo_url) { - $serverret = Network::curl($nodeinfo_url); + $curlResult = Network::curl($nodeinfo_url); - if (!$serverret["success"]) { + if (!$curlResult->isSuccess()) { return false; } - $nodeinfo = json_decode($serverret['body'], true); + $nodeinfo = json_decode($curlResult->getBody(), true); if (!is_array($nodeinfo)) { return false; @@ -782,12 +782,12 @@ class PortableContact */ private static function parseNodeinfo2($nodeinfo_url) { - $serverret = Network::curl($nodeinfo_url); - if (!$serverret["success"]) { + $curlResult = Network::curl($nodeinfo_url); + if (!$curlResult->isSuccess()) { return false; } - $nodeinfo = json_decode($serverret['body'], true); + $nodeinfo = json_decode($curlResult->getBody(), true); if (!is_array($nodeinfo)) { return false; @@ -997,38 +997,38 @@ class PortableContact $server_url = str_replace("http://", "https://", $server_url); // We set the timeout to 20 seconds since this operation should be done in no time if the server was vital - $serverret = Network::curl($server_url."/.well-known/host-meta", false, $redirects, ['timeout' => 20]); + $curlResult = Network::curl($server_url."/.well-known/host-meta", false, $redirects, ['timeout' => 20]); // Quit if there is a timeout. // But we want to make sure to only quit if we are mostly sure that this server url fits. if (DBA::isResult($gserver) && ($orig_server_url == $server_url) && - (!empty($serverret["errno"]) && ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT))) { + ($curlResult->isTimeout())) { logger("Connection to server ".$server_url." timed out.", LOGGER_DEBUG); DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => normalise_link($server_url)]); return false; } // Maybe the page is unencrypted only? - $xmlobj = @simplexml_load_string($serverret["body"], 'SimpleXMLElement', 0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); - if (!$serverret["success"] || ($serverret["body"] == "") || empty($xmlobj) || !is_object($xmlobj)) { + $xmlobj = @simplexml_load_string($curlResult->getBody(), 'SimpleXMLElement', 0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); + if (!$curlResult->isSuccess() || ($curlResult->getBody() == "") || empty($xmlobj) || !is_object($xmlobj)) { $server_url = str_replace("https://", "http://", $server_url); // We set the timeout to 20 seconds since this operation should be done in no time if the server was vital - $serverret = Network::curl($server_url."/.well-known/host-meta", false, $redirects, ['timeout' => 20]); + $curlResult = Network::curl($server_url."/.well-known/host-meta", false, $redirects, ['timeout' => 20]); // Quit if there is a timeout - if (!empty($serverret["errno"]) && ($serverret['errno'] == CURLE_OPERATION_TIMEDOUT)) { - logger("Connection to server ".$server_url." timed out.", LOGGER_DEBUG); + if ($curlResult->isTimeout()) { + logger("Connection to server " . $server_url . " timed out.", LOGGER_DEBUG); DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => normalise_link($server_url)]); return false; } - $xmlobj = @simplexml_load_string($serverret["body"], 'SimpleXMLElement', 0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); + $xmlobj = @simplexml_load_string($curlResult->getBody(), 'SimpleXMLElement', 0, "http://docs.oasis-open.org/ns/xri/xrd-1.0"); } - if (!$serverret["success"] || ($serverret["body"] == "") || empty($xmlobj) || !is_object($xmlobj)) { + if (!$curlResult->isSuccess() || ($curlResult->getBody() == "") || empty($xmlobj) || !is_object($xmlobj)) { // Workaround for bad configured servers (known nginx problem) - if (!empty($serverret["debug"]) && !in_array($serverret["debug"]["http_code"], ["403", "404"])) { + if (!empty($curlResult->getInfo()) && !in_array($curlResult->getInfo()["http_code"], ["403", "404"])) { $failure = true; } @@ -1051,10 +1051,10 @@ class PortableContact // Look for poco if (!$failure) { - $serverret = Network::curl($server_url."/poco"); + $curlResult = Network::curl($server_url."/poco"); - if ($serverret["success"]) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['totalResults'])) { $registered_users = $data['totalResults']; @@ -1083,12 +1083,12 @@ class PortableContact if (!$failure) { // Test for Diaspora, Hubzilla, Mastodon or older Friendica servers - $serverret = Network::curl($server_url); + $curlResult = Network::curl($server_url); - if (!$serverret["success"] || ($serverret["body"] == "")) { + if (!$curlResult->isSuccess() || ($curlResult->getBody() == "")) { $failure = true; } else { - $server = self::detectServerType($serverret["body"]); + $server = self::detectServerType($curlResult->getBody()); if (!empty($server)) { $platform = $server['platform']; @@ -1097,7 +1097,7 @@ class PortableContact $site_name = $server['site_name']; } - $lines = explode("\n", $serverret["header"]); + $lines = explode("\n", $curlResult->getHeader()); if (count($lines)) { foreach ($lines as $line) { @@ -1125,35 +1125,35 @@ class PortableContact // Test for Statusnet // Will also return data for Friendica and GNU Social - but it will be overwritten later // The "not implemented" is a special treatment for really, really old Friendica versions - $serverret = Network::curl($server_url."/api/statusnet/version.json"); + $curlResult = Network::curl($server_url."/api/statusnet/version.json"); - if ($serverret["success"] && ($serverret["body"] != '{"error":"not implemented"}') && - ($serverret["body"] != '') && (strlen($serverret["body"]) < 30)) { + if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && + ($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { $platform = "StatusNet"; // Remove junk that some GNU Social servers return - $version = str_replace(chr(239).chr(187).chr(191), "", $serverret["body"]); + $version = str_replace(chr(239).chr(187).chr(191), "", $curlResult->getBody()); $version = trim($version, '"'); $network = Protocol::OSTATUS; } // Test for GNU Social - $serverret = Network::curl($server_url."/api/gnusocial/version.json"); + $curlResult = Network::curl($server_url."/api/gnusocial/version.json"); - if ($serverret["success"] && ($serverret["body"] != '{"error":"not implemented"}') && - ($serverret["body"] != '') && (strlen($serverret["body"]) < 30)) { + if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && + ($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { $platform = "GNU Social"; // Remove junk that some GNU Social servers return - $version = str_replace(chr(239) . chr(187) . chr(191), "", $serverret["body"]); + $version = str_replace(chr(239) . chr(187) . chr(191), "", $curlResult->getBody()); $version = trim($version, '"'); $network = Protocol::OSTATUS; } // Test for Mastodon $orig_version = $version; - $serverret = Network::curl($server_url . "/api/v1/instance"); + $curlResult = Network::curl($server_url . "/api/v1/instance"); - if ($serverret["success"] && ($serverret["body"] != '')) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess() && ($curlResult->getBody() != '')) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['version'])) { $platform = "Mastodon"; @@ -1176,10 +1176,10 @@ class PortableContact if (!$failure) { // Test for Hubzilla and Red - $serverret = Network::curl($server_url . "/siteinfo.json"); + $curlResult = Network::curl($server_url . "/siteinfo.json"); - if ($serverret["success"]) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['url'])) { $platform = $data['platform']; @@ -1213,10 +1213,10 @@ class PortableContact } } else { // Test for Hubzilla, Redmatrix or Friendica - $serverret = Network::curl($server_url."/api/statusnet/config.json"); + $curlResult = Network::curl($server_url."/api/statusnet/config.json"); - if ($serverret["success"]) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['site']['server'])) { if (isset($data['site']['platform'])) { @@ -1286,10 +1286,10 @@ class PortableContact // Query statistics.json. Optional package for Diaspora, Friendica and Redmatrix if (!$failure) { - $serverret = Network::curl($server_url . "/statistics.json"); + $curlResult = Network::curl($server_url . "/statistics.json"); - if ($serverret["success"]) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['version'])) { $version = $data['version']; @@ -1350,14 +1350,14 @@ class PortableContact // Check for noscrape // Friendica servers could be detected as OStatus servers if (!$failure && in_array($network, [Protocol::DFRN, Protocol::OSTATUS])) { - $serverret = Network::curl($server_url . "/friendica/json"); + $curlResult = Network::curl($server_url . "/friendica/json"); - if (!$serverret["success"]) { - $serverret = Network::curl($server_url . "/friendika/json"); + if (!$curlResult->isSuccess()) { + $curlResult = Network::curl($server_url . "/friendika/json"); } - if ($serverret["success"]) { - $data = json_decode($serverret["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult->getBody(), true); if (isset($data['version'])) { $network = Protocol::DFRN; @@ -1442,13 +1442,13 @@ class PortableContact { logger("Discover relay data for server " . $server_url, LOGGER_DEBUG); - $serverret = Network::curl($server_url . "/.well-known/x-social-relay"); + $curlResult = Network::curl($server_url . "/.well-known/x-social-relay"); - if (!$serverret["success"]) { + if (!$curlResult->isSuccess()) { return; } - $data = json_decode($serverret['body'], true); + $data = json_decode($curlResult->getBody(), true); if (!is_array($data)) { return; @@ -1538,13 +1538,13 @@ class PortableContact */ private static function fetchServerlist($poco) { - $serverret = Network::curl($poco . "/@server"); + $curlResult = Network::curl($poco . "/@server"); - if (!$serverret["success"]) { + if (!$curlResult->isSuccess()) { return; } - $serverlist = json_decode($serverret['body'], true); + $serverlist = json_decode($curlResult->getBody(), true); if (!is_array($serverlist)) { return; @@ -1575,10 +1575,10 @@ class PortableContact } // Discover Friendica, Hubzilla and Diaspora servers - $serverdata = Network::fetchUrl("http://the-federation.info/pods.json"); + $curlResult = Network::fetchUrl("http://the-federation.info/pods.json"); - if (!empty($serverdata)) { - $servers = json_decode($serverdata, true); + if (!empty($curlResult)) { + $servers = json_decode($curlResult, true); if (!empty($servers['pods'])) { foreach ($servers['pods'] as $server) { @@ -1594,10 +1594,10 @@ class PortableContact if (!empty($accesstoken)) { $api = 'https://instances.social/api/1.0/instances/list?count=0'; $header = ['Authorization: Bearer '.$accesstoken]; - $serverdata = Network::curl($api, false, $redirects, ['headers' => $header]); + $curlResult = Network::curl($api, false, $redirects, ['headers' => $header]); - if ($serverdata['success']) { - $servers = json_decode($serverdata['body'], true); + if ($curlResult->isSuccess()) { + $servers = json_decode($curlResult->getBody(), true); foreach ($servers['instances'] as $server) { $url = (is_null($server['https_score']) ? 'http' : 'https') . '://' . $server['name']; @@ -1613,9 +1613,9 @@ class PortableContact //if (!Config::get('system','ostatus_disabled')) { // $serverdata = "http://gstools.org/api/get_open_instances/"; - // $result = Network::curl($serverdata); - // if ($result["success"]) { - // $servers = json_decode($result["body"], true); + // $curlResult = Network::curl($serverdata); + // if ($curlResult->isSuccess()) { + // $servers = json_decode($result->getBody(), true); // foreach($servers['data'] as $server) // self::checkServer($server['instance_address']); @@ -1643,10 +1643,10 @@ class PortableContact logger("Fetch all users from the server " . $server["url"], LOGGER_DEBUG); - $retdata = Network::curl($url); + $curlResult = Network::curl($url); - if ($retdata["success"] && !empty($retdata["body"])) { - $data = json_decode($retdata["body"], true); + if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { + $data = json_decode($curlResult->getBody(), true); if (!empty($data)) { self::discoverServer($data, 2); @@ -1666,11 +1666,11 @@ class PortableContact $success = false; - $retdata = Network::curl($url); + $curlResult = Network::curl($url); - if ($retdata["success"] && !empty($retdata["body"])) { + if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { logger("Fetch all global contacts from the server " . $server["nurl"], LOGGER_DEBUG); - $data = json_decode($retdata["body"], true); + $data = json_decode($curlResult->getBody(), true); if (!empty($data)) { $success = self::discoverServer($data); @@ -1766,10 +1766,10 @@ class PortableContact // Fetch all contacts from a given user from the other server $url = $server['poco'] . '/' . $username . '/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation'; - $retdata = Network::curl($url); + $curlResult = Network::curl($url); - if (!empty($retdata['success'])) { - $data = json_decode($retdata["body"], true); + if ($curlResult->isSuccess()) { + $data = json_decode($curlResult["body"], true); if (!empty($data)) { self::discoverServer($data, 3); diff --git a/src/Util/ExAuth.php b/src/Util/ExAuth.php index de5d52d89..8d38b3366 100644 --- a/src/Util/ExAuth.php +++ b/src/Util/ExAuth.php @@ -179,17 +179,17 @@ class ExAuth $url = ($ssl ? 'https' : 'http') . '://' . $host . '/noscrape/' . $user; - $data = Network::curl($url); + $curlResult = Network::curl($url); - if (!is_array($data)) { + if (!$curlResult->isSuccess()) { return false; } - if ($data['return_code'] != '200') { + if ($curlResult->getReturnCode() != 200) { return false; } - $json = @json_decode($data['body']); + $json = @json_decode($curlResult->getBody()); if (!is_object($json)) { return false; } diff --git a/src/Util/Network.php b/src/Util/Network.php index 163be21d3..f8e4ee9e5 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -13,25 +13,6 @@ use DomXPath; class Network { - /** - * @var Curl The latest Curl output - */ - private static $curl; - - /** - * Returns the latest Curl output - * - * @return Curl The latest Curl output - */ - public static function getCurl() - { - if (empty(self::$curl)) { - self::$curl = new Curl(); - } - - return self::$curl; - } - /** * Curl wrapper * @@ -54,7 +35,7 @@ class Network { $ret = self::fetchUrlFull($url, $binary, $redirects, $timeout, $accept_content, $cookiejar); - return $ret['body']; + return $ret->getBody(); } /** @@ -72,7 +53,7 @@ class Network * @param string $accept_content supply Accept: header with 'accept_content' as the value * @param string $cookiejar Path to cookie jar file * - * @return array With all relevant information, 'body' contains the actual fetched content. + * @return Curl With all relevant information, 'body' contains the actual fetched content. */ public static function fetchUrlFull($url, $binary = false, &$redirects = 0, $timeout = 0, $accept_content = null, $cookiejar = '') { @@ -102,12 +83,7 @@ class Network * 'nobody' => only return the header * 'cookiejar' => path to cookie jar file * - * @return array an assoziative array with: - * int 'return_code' => HTTP return code or 0 if timeout or failure - * boolean 'success' => boolean true (if HTTP 2xx result) or false - * string 'redirect_url' => in case of redirect, content was finally retrieved from this URL - * string 'header' => HTTP headers - * string 'body' => fetched content + * @return Curl */ public static function curl($url, $binary = false, &$redirects = 0, $opts = []) { @@ -120,24 +96,24 @@ class Network $parts = parse_url($url); $path_parts = explode('/', defaults($parts, 'path', '')); foreach ($path_parts as $part) { - if (strlen($part) <> mb_strlen($part)) { + if (strlen($part) <> mb_strlen($part)) { $parts2[] = rawurlencode($part); - } else { - $parts2[] = $part; - } + } else { + $parts2[] = $part; + } } - $parts['path'] = implode('/', $parts2); + $parts['path'] = implode('/', $parts2); $url = self::unparseURL($parts); if (self::isUrlBlocked($url)) { logger('domain of ' . $url . ' is blocked', LOGGER_DATA); - return $ret; + return Curl::createErrorCurl($url); } $ch = @curl_init($url); if (($redirects > 8) || (!$ch)) { - return $ret; + return Curl::createErrorCurl($url); } @curl_setopt($ch, CURLOPT_HEADER, true); @@ -236,87 +212,20 @@ class Network logger('error fetching ' . $url . ': ' . curl_error($ch), LOGGER_INFO); } - $ret['errno'] = curl_errno($ch); + $curlResponse = new Curl($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); - $base = $s; - $ret['info'] = $curl_info; - - $http_code = $curl_info['http_code']; - - logger($url . ': ' . $http_code . " " . $s, LOGGER_DATA); - $header = ''; - - // Pull out multiple headers, e.g. proxy and continuation headers - // allow for HTTP/2.x without fixing code - - while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) { - $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); - $header .= $chunk; - $base = substr($base, strlen($chunk)); - } - - self::$curl = new Curl($http_code, (isset($curl_info['content_type']) ? $curl_info['content_type'] : ''), $header); - - if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) { - $new_location_info = @parse_url($curl_info['redirect_url']); - $old_location_info = @parse_url($curl_info['url']); - - $newurl = $curl_info['redirect_url']; - - if (empty($new_location_info['path']) && !empty($new_location_info['host'])) { - $newurl = $new_location_info['scheme'] . '://' . $new_location_info['host'] . $old_location_info['path']; - } - - $matches = []; - - if (preg_match('/(Location:|URI:)(.*?)\n/i', $header, $matches)) { - $newurl = trim(array_pop($matches)); - } - if (strpos($newurl, '/') === 0) { - $newurl = $old_location_info["scheme"]."://".$old_location_info["host"].$newurl; - } - $old_location_query = @parse_url($url, PHP_URL_QUERY); - - if ($old_location_query != '') { - $newurl .= '?' . $old_location_query; - } - - if (filter_var($newurl, FILTER_VALIDATE_URL)) { - $redirects++; - @curl_close($ch); - return self::curl($newurl, $binary, $redirects, $opts); - } - } - - self::$curl->setCode($http_code); - if (isset($curl_info['content_type'])) { - self::$curl->setContentType($curl_info['content_type']); - } - - $rc = intval($http_code); - $ret['return_code'] = $rc; - $ret['success'] = (($rc >= 200 && $rc <= 299) ? true : false); - $ret['redirect_url'] = $url; - - if (!$ret['success']) { - $ret['error'] = curl_error($ch); - $ret['debug'] = $curl_info; - logger('error: '.$url.': '.$ret['return_code'].' - '.$ret['error'], LOGGER_DEBUG); - logger('debug: '.print_r($curl_info, true), LOGGER_DATA); - } - - $ret['body'] = substr($s, strlen($header)); - $ret['header'] = $header; - - if (x($opts, 'debug')) { - $ret['debug'] = $curl_info; + if ($curlResponse->isRedirectUrl()) { + $redirects++; + logger('curl: redirect ' . $url . ' to ' . $curlResponse->getRedirectUrl()); + @curl_close($ch); + return self::curl($curlResponse->getRedirectUrl(), $binary, $redirects, $opts); } @curl_close($ch); $a->saveTimestamp($stamp1, 'network'); - return($ret); + return $curlResponse; } /** @@ -328,7 +237,7 @@ class Network * @param integer $redirects Recursion counter for internal use - default = 0 * @param integer $timeout The timeout in seconds, default system config value or 60 seconds * - * @return string The content + * @return Curl The content */ public static function post($url, $params, $headers = null, &$redirects = 0, $timeout = 0) { @@ -336,14 +245,14 @@ class Network if (self::isUrlBlocked($url)) { logger('post_url: domain of ' . $url . ' is blocked', LOGGER_DATA); - return false; + return Curl::createErrorCurl($url); } $a = get_app(); $ch = curl_init($url); if (($redirects > 8) || (!$ch)) { - return false; + return Curl::createErrorCurl($url); } logger('post_url: start ' . $url, LOGGER_DATA); @@ -397,8 +306,6 @@ class Network } } - self::getCurl()->setCode(0); - // don't let curl abort the entire application // if it throws any errors. @@ -406,53 +313,23 @@ class Network $base = $s; $curl_info = curl_getinfo($ch); - $http_code = $curl_info['http_code']; - logger('post_url: result ' . $http_code . ' - ' . $url, LOGGER_DATA); + $curlResponse = new Curl($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); - $header = ''; - - // Pull out multiple headers, e.g. proxy and continuation headers - // allow for HTTP/2.x without fixing code - - while (preg_match('/^HTTP\/[1-2].+? [1-5][0-9][0-9]/', $base)) { - $chunk = substr($base, 0, strpos($base, "\r\n\r\n") + 4); - $header .= $chunk; - $base = substr($base, strlen($chunk)); + if ($curlResponse->isRedirectUrl()) { + $redirects++; + logger('post_url: redirect ' . $url . ' to ' . $curlResponse->getRedirectUrl()); + curl_close($ch); + return self::post($curlResponse->getRedirectUrl(), $params, $headers, $redirects, $timeout); } - if ($http_code == 301 || $http_code == 302 || $http_code == 303 || $http_code == 307) { - $matches = []; - $new_location_info = @parse_url($curl_info['redirect_url']); - $old_location_info = @parse_url($curl_info['url']); - - preg_match('/(Location:|URI:)(.*?)\n/', $header, $matches); - $newurl = trim(array_pop($matches)); - - if (strpos($newurl, '/') === 0) { - $newurl = $old_location_info["scheme"] . "://" . $old_location_info["host"] . $newurl; - } - - if (filter_var($newurl, FILTER_VALIDATE_URL)) { - $redirects++; - logger('post_url: redirect ' . $url . ' to ' . $newurl); - return self::post($newurl, $params, $headers, $redirects, $timeout); - } - } - - self::getCurl()->setCode($http_code); - - $body = substr($s, strlen($header)); - - self::getCurl()->setHeaders($header); - curl_close($ch); $a->saveTimestamp($stamp1, 'network'); logger('post_url: end ' . $url, LOGGER_DATA); - return $body; + return $curlResponse; } /** diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 00eac1390..f2a5eccd3 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -135,23 +135,23 @@ class ParseUrl $siteinfo['url'] = $url; $siteinfo['type'] = 'link'; - $data = Network::curl($url); - if (!$data['success']) { + $curlResult = Network::curl($url); + if (!$curlResult->isSuccess()) { return $siteinfo; } // If the file is too large then exit - if ($data['info']['download_content_length'] > 1000000) { + if ($curlResult->getInfo()['download_content_length'] > 1000000) { return $siteinfo; } // If it isn't a HTML file then exit - if (($data['info']['content_type'] != '') && !strstr(strtolower($data['info']['content_type']), 'html')) { + if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return $siteinfo; } - $header = $data['header']; - $body = $data['body']; + $header = $curlResult->getHeader(); + $body = $curlResult->getBody(); if ($do_oembed) { $oembed_data = OEmbed::fetchURL($url); diff --git a/src/Worker/DiscoverPoCo.php b/src/Worker/DiscoverPoCo.php index e6fc8391f..497684497 100644 --- a/src/Worker/DiscoverPoCo.php +++ b/src/Worker/DiscoverPoCo.php @@ -274,12 +274,12 @@ class DiscoverPoCo $url = "http://gstools.org/api/users_search/".urlencode($search); - $result = Network::curl($url); - if (!$result["success"]) { + $curlResult = Network::curl($url); + if (!$curlResult->isSuccess()) { return false; } - $contacts = json_decode($result["body"]); + $contacts = json_decode($curlResult->getBody()); if ($contacts->status == 'ERROR') { return false; diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index 21e3b44b3..ab8a30549 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -185,18 +185,17 @@ class OnePoll . '&type=data&last_update=' . $last_update . '&perm=' . $perm ; - $ret = Network::curl($url); + $curlResult = Network::curl($url); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + if (!$curlResult->isSuccess() && ($curlResult->getErrorNumber() == CURLE_OPERATION_TIMEDOUT)) { // set the last-update so we don't keep polling DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]); Contact::markForArchival($contact); return; } - $handshake_xml = $ret['body']; - - $html_code = Network::getCurl()->getCode(); + $handshake_xml = $curlResult->getBody(); + $html_code = $curlResult->getReturnCode(); logger('handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA); @@ -319,17 +318,17 @@ class OnePoll } $cookiejar = tempnam(get_temppath(), 'cookiejar-onepoll-'); - $ret = Network::curl($contact['poll'], false, $redirects, ['cookiejar' => $cookiejar]); + $curlResult = Network::curl($contact['poll'], false, $redirects, ['cookiejar' => $cookiejar]); unlink($cookiejar); - if (!empty($ret["errno"]) && ($ret['errno'] == CURLE_OPERATION_TIMEDOUT)) { + if (!$curlResult->isTimeout()) { // set the last-update so we don't keep polling DBA::update('contact', ['last-update' => DateTimeFormat::utcNow()], ['id' => $contact['id']]); Contact::markForArchival($contact); return; } - $xml = $ret['body']; + $xml = $curlResult->getBody(); } elseif ($contact['network'] === Protocol::MAIL) { logger("Mail: Fetching for ".$contact['addr'], LOGGER_DEBUG); From 7c73e8634c954cc2bd0d1138729459d7d5090f62 Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Wed, 10 Oct 2018 21:15:26 +0200 Subject: [PATCH 2/5] Curl Response Refactoring - refactored Network::post() - replaced every Network::post() execution with the new Curl container --- include/items.php | 4 ++-- mod/dfrn_confirm.php | 2 +- mod/dfrn_poll.php | 2 +- mod/match.php | 4 ++-- src/Protocol/DFRN.php | 7 ++++--- src/Protocol/Diaspora.php | 6 +++--- src/Protocol/Salmon.php | 13 ++++++------- src/Util/HTTPSignature.php | 5 ++--- src/Worker/OnePoll.php | 2 +- src/Worker/PubSubPublish.php | 4 ++-- 10 files changed, 24 insertions(+), 25 deletions(-) diff --git a/include/items.php b/include/items.php index 236e63dd2..27a7db767 100644 --- a/include/items.php +++ b/include/items.php @@ -316,9 +316,9 @@ function subscribe_to_hub($url, array $importer, array $contact, $hubmode = 'sub DBA::update('contact', ['hub-verify' => $verify_token], ['id' => $contact['id']]); } - Network::post($url, $params); + $postResult = Network::post($url, $params); - logger('subscribe_to_hub: returns: ' . Network::getCurl()->getCode(), LOGGER_DEBUG); + logger('subscribe_to_hub: returns: ' . $postResult->getReturnCode(), LOGGER_DEBUG); return; diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php index d3fa45d36..969e2286c 100644 --- a/mod/dfrn_confirm.php +++ b/mod/dfrn_confirm.php @@ -221,7 +221,7 @@ function dfrn_confirm_post(App $a, $handsfree = null) * */ - $res = Network::post($dfrn_confirm, $params, null, $redirects, 120); + $res = Network::post($dfrn_confirm, $params, null, $redirects, 120)->getBody(); logger(' Confirm: received data: ' . $res, LOGGER_DATA); diff --git a/mod/dfrn_poll.php b/mod/dfrn_poll.php index 54539ee03..af597d76f 100644 --- a/mod/dfrn_poll.php +++ b/mod/dfrn_poll.php @@ -502,7 +502,7 @@ function dfrn_poll_content(App $a) 'dfrn_version' => DFRN_PROTOCOL_VERSION, 'challenge' => $challenge, 'sec' => $sec - ]); + ])->getBody(); } $profile = ((DBA::isResult($r) && $r[0]['nickname']) ? $r[0]['nickname'] : $nickname); diff --git a/mod/match.php b/mod/match.php index bb1e4542a..7e805d5ba 100644 --- a/mod/match.php +++ b/mod/match.php @@ -59,9 +59,9 @@ function match_content(App $a) } if (strlen(Config::get('system', 'directory'))) { - $x = Network::post(get_server().'/msearch', $params); + $x = Network::post(get_server().'/msearch', $params)->getBody(); } else { - $x = Network::post(System::baseUrl() . '/msearch', $params); + $x = Network::post(System::baseUrl() . '/msearch', $params)->getBody(); } $j = json_decode($x); diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index 3a001de04..f92d1401d 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1469,16 +1469,17 @@ class DFRN $content_type = ($public_batch ? "application/magic-envelope+xml" : "application/json"); - $xml = Network::post($dest_url, $envelope, ["Content-Type: ".$content_type]); + $postResult = Network::post($dest_url, $envelope, ["Content-Type: ".$content_type]); + $xml = $postResult->getBody(); - $curl_stat = Network::getCurl()->getCode(); + $curl_stat = $postResult->getReturnCode(); if (empty($curl_stat) || empty($xml)) { logger('Empty answer from ' . $contact['id'] . ' - ' . $dest_url); Contact::markForArchival($contact); return -9; // timed out } - if (($curl_stat == 503) && (stristr(Network::getCurl()->getHeaders(), 'retry-after'))) { + if (($curl_stat == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { Contact::markForArchival($contact); return -10; } diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index ebdc84ce7..d3cda6c2d 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -3079,8 +3079,8 @@ class Diaspora if (!intval(Config::get("system", "diaspora_test"))) { $content_type = (($public_batch) ? "application/magic-envelope+xml" : "application/json"); - Network::post($dest_url."/", $envelope, ["Content-Type: ".$content_type]); - $return_code = Network::getCurl()->getCode(); + $postResult = Network::post($dest_url."/", $envelope, ["Content-Type: ".$content_type]); + $return_code = $postResult->getReturnCode(); } else { logger("test_mode"); return 200; @@ -3089,7 +3089,7 @@ class Diaspora logger("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code); - if (!$return_code || (($return_code == 503) && (stristr(Network::getCurl()->getHeaders(), "retry-after")))) { + if (!$return_code || (($return_code == 503) && (stristr($postResult->getHeaders(), "retry-after")))) { if (!$no_queue && !empty($contact['contact-type']) && ($contact['contact-type'] != Contact::ACCOUNT_TYPE_RELAY)) { logger("queue message"); // queue message for redelivery diff --git a/src/Protocol/Salmon.php b/src/Protocol/Salmon.php index b71be6e2f..02d08c3d4 100644 --- a/src/Protocol/Salmon.php +++ b/src/Protocol/Salmon.php @@ -133,13 +133,12 @@ class Salmon $salmon = XML::fromArray($xmldata, $xml, false, $namespaces); // slap them - Network::post($url, $salmon, [ + $postResult = Network::post($url, $salmon, [ 'Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon) ]); - $a = get_app(); - $return_code = Network::getCurl()->getCode(); + $return_code = $postResult->getReturnCode(); // check for success, e.g. 2xx @@ -159,11 +158,11 @@ class Salmon $salmon = XML::fromArray($xmldata, $xml, false, $namespaces); // slap them - Network::post($url, $salmon, [ + $postResult = Network::post($url, $salmon, [ 'Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon) ]); - $return_code = Network::getCurl()->getCode(); + $return_code = $postResult->getReturnCode(); } if ($return_code > 299) { @@ -182,10 +181,10 @@ class Salmon $salmon = XML::fromArray($xmldata, $xml, false, $namespaces); // slap them - Network::post($url, $salmon, [ + $postResult = Network::post($url, $salmon, [ 'Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon)]); - $return_code = Network::getCurl()->getCode(); + $return_code = $postResult->getReturnCode(); } logger('slapper for '.$url.' returned ' . $return_code); diff --git a/src/Util/HTTPSignature.php b/src/Util/HTTPSignature.php index 247e554f0..503cbff0a 100644 --- a/src/Util/HTTPSignature.php +++ b/src/Util/HTTPSignature.php @@ -302,10 +302,9 @@ class HTTPSignature $headers[] = 'Content-Type: application/activity+json'; - Network::post($target, $content, $headers); - $return_code = Network::getCurl()->getCode(); + $postResult = Network::post($target, $content, $headers); - logger('Transmit to ' . $target . ' returned ' . $return_code); + logger('Transmit to ' . $target . ' returned ' . $postResult->getReturnCode()); } /** diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index ab8a30549..a68ad1336 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -287,7 +287,7 @@ class OnePoll $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION; $postvars['perm'] = 'rw'; - $xml = Network::post($contact['poll'], $postvars); + $xml = Network::post($contact['poll'], $postvars)->getBody(); } elseif (($contact['network'] === Protocol::OSTATUS) || ($contact['network'] === Protocol::DIASPORA) diff --git a/src/Worker/PubSubPublish.php b/src/Worker/PubSubPublish.php index 07023e824..38d9c0786 100644 --- a/src/Worker/PubSubPublish.php +++ b/src/Worker/PubSubPublish.php @@ -56,8 +56,8 @@ class PubSubPublish logger('POST ' . print_r($headers, true) . "\n" . $params, LOGGER_DATA); - Network::post($subscriber['callback_url'], $params, $headers); - $ret = Network::getCurl()->getCode(); + $postResult = Network::post($subscriber['callback_url'], $params, $headers); + $ret = $postResult->getReturnCode(); $condition = ['id' => $subscriber['id']]; From ffbc6887977c34072e2a3043486a1b0e768a9844 Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Wed, 10 Oct 2018 21:20:30 +0200 Subject: [PATCH 3/5] Curl Response Refactoring - refactored Network::getCurl() - replaced every Network::getCur() execution with a Curl Response --- mod/pubsubhubbub.php | 5 +++-- src/Core/Install.php | 12 ++++++------ src/Module/Proxy.php | 5 +++-- src/Network/Curl.php | 18 +++++++++--------- src/Object/Image.php | 5 +++-- src/Protocol/Diaspora.php | 2 +- src/Protocol/PortableContact.php | 7 ++++--- src/Protocol/Salmon.php | 2 +- src/Util/Network.php | 4 ---- 9 files changed, 30 insertions(+), 30 deletions(-) diff --git a/mod/pubsubhubbub.php b/mod/pubsubhubbub.php index 5697be830..d7b204e89 100644 --- a/mod/pubsubhubbub.php +++ b/mod/pubsubhubbub.php @@ -104,8 +104,9 @@ function pubsubhubbub_init(App $a) { // we don't actually enforce the lease time because GNU // Social/StatusNet doesn't honour it (yet) - $body = Network::fetchUrl($hub_callback . "?" . $params); - $ret = Network::getCurl()->getCode(); + $fetchResult = Network::fetchUrlFull($hub_callback . "?" . $params); + $body = $fetchResult->getBody(); + $ret = $fetchResult->getReturnCode(); // give up if the HTTP return code wasn't a success (2xx) if ($ret < 200 || $ret > 299) { diff --git a/src/Core/Install.php b/src/Core/Install.php index ba767f3f9..3ba683a56 100644 --- a/src/Core/Install.php +++ b/src/Core/Install.php @@ -345,20 +345,20 @@ class Install extends BaseObject $help = ""; $error_msg = ""; if (function_exists('curl_init')) { - $test = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite"); + $fetchResult = Network::fetchUrlFull(System::baseUrl() . "/install/testrewrite"); $url = normalise_link(System::baseUrl() . "/install/testrewrite"); - if ($test['body'] != "ok") { - $test = Network::fetchUrlFull($url); + if ($fetchResult->getBody() != "ok") { + $fetchResult = Network::fetchUrlFull($url); } - if ($test['body'] != "ok") { + if ($fetchResult->getBody() != "ok") { $status = false; $help = L10n::t('Url rewrite in .htaccess is not working. Check your server configuration.'); $error_msg = []; $error_msg['head'] = L10n::t('Error message from Curl when fetching'); - $error_msg['url'] = $test['redirect_url']; - $error_msg['msg'] = defaults($test, 'error', ''); + $error_msg['url'] = $fetchResult->getRedirectUrl(); + $error_msg['msg'] = $fetchResult->getError(); } self::addCheck($checks, L10n::t('Url rewrite is working'), $status, true, $help, $error_msg); } else { diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index 14e842562..776dcccb3 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -188,7 +188,8 @@ class Proxy extends BaseModule // It shouldn't happen but it does - spaces in URL $_REQUEST['url'] = str_replace(' ', '+', $_REQUEST['url']); $redirects = 0; - $img_str = Network::fetchUrl($_REQUEST['url'], true, $redirects, 10); + $fetchResult = Network::fetchUrlFull($_REQUEST['url'], true, $redirects, 10); + $img_str = $fetchResult->getBody(); $tempfile = tempnam(get_temppath(), 'cache'); file_put_contents($tempfile, $img_str); @@ -196,7 +197,7 @@ class Proxy extends BaseModule unlink($tempfile); // If there is an error then return a blank image - if ((substr(Network::getCurl()->getCode(), 0, 1) == '4') || (!$img_str)) { + if ((substr($fetchResult->getReturnCode(), 0, 1) == '4') || (!$img_str)) { $img_str = file_get_contents('images/blank.png'); $mime = 'image/png'; $cachefile = ''; // Clear the cachefile so that the dummy isn't stored diff --git a/src/Network/Curl.php b/src/Network/Curl.php index f67104bc0..7cab25ee8 100644 --- a/src/Network/Curl.php +++ b/src/Network/Curl.php @@ -61,12 +61,12 @@ class Curl private $isTimeout; /** - * @var int optional error numer + * @var int the error number or 0 (zero) if no error */ private $errorNumber; /** - * @var string optional error message + * @var string the error message or '' (the empty string) if no */ private $error; @@ -82,7 +82,7 @@ class Curl return new Curl( $url, '', - ['http_code' => 0] + [ 'http_code' => 0 ] ); } @@ -98,7 +98,7 @@ class Curl */ public function __construct($url, $result, $info, $errorNumber = 0, $error = '') { - if (empty($info['http_code'])) { + if (!array_key_exists('http_code', $info)) { throw new InternalServerErrorException('CURL response doesn\'t contains a response HTTP code'); } @@ -135,10 +135,10 @@ class Curl private function checkSuccess() { - $this->isSuccess = ((($this->returnCode >= 200 && $this->returnCode <= 299) || !empty($this->errorNumber)) ? true : false); + $this->isSuccess = ($this->returnCode >= 200 && $this->returnCode <= 299) || $this->errorNumber == 0; if (!$this->isSuccess) { - logger('error: ' . $this->url . ': ' . $this->returnCode . ' - ' . $this->error, LOGGER_DEBUG); + logger('error: ' . $this->url . ': ' . $this->returnCode . ' - ' . $this->error, LOGGER_INFO); logger('debug: ' . print_r($this->info, true), LOGGER_DATA); } @@ -151,15 +151,15 @@ class Curl private function checkRedirect() { - if (empty($this->info['url'])) { + if (!array_key_exists('url', $this->info)) { $this->redirectUrl = ''; } else { $this->redirectUrl = $this->info['url']; } if ($this->returnCode == 301 || $this->returnCode == 302 || $this->returnCode == 303 || $this->returnCode== 307) { - $new_location_info = (empty($this->info['redirect_url']) ? '' : @parse_url($this->info['redirect_url'])); - $old_location_info = (empty($this->info['url'] ? '' : @parse_url($this->info['url'])); + $new_location_info = (!array_key_exists('redirect_url', $this->info) ? '' : @parse_url($this->info['redirect_url'])); + $old_location_info = (!array_key_exists('url', $this->info) ? '' : @parse_url($this->info['url'])); $this->redirectUrl = $new_location_info; diff --git a/src/Object/Image.php b/src/Object/Image.php index 166e150bf..a76599223 100644 --- a/src/Object/Image.php +++ b/src/Object/Image.php @@ -720,17 +720,18 @@ class Image * * @param string $filename Image filename * @param boolean $fromcurl Check Content-Type header from curl request + * @param string $header passed headers to take into account * * @return object */ - public static function guessType($filename, $fromcurl = false) + public static function guessType($filename, $fromcurl = false, $header = '') { logger('Image: guessType: '.$filename . ($fromcurl?' from curl headers':''), LOGGER_DEBUG); $type = null; if ($fromcurl) { $a = get_app(); $headers=[]; - $h = explode("\n", Network::getCurl()->getHeaders()); + $h = explode("\n", $header); foreach ($h as $l) { $data = array_map("trim", explode(":", trim($l), 2)); if (count($data) > 1) { diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index d3cda6c2d..eb52c0503 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -3089,7 +3089,7 @@ class Diaspora logger("transmit: ".$logid."-".$guid." to ".$dest_url." returns: ".$return_code); - if (!$return_code || (($return_code == 503) && (stristr($postResult->getHeaders(), "retry-after")))) { + if (!$return_code || (($return_code == 503) && (stristr($postResult->getHeader(), "retry-after")))) { if (!$no_queue && !empty($contact['contact-type']) && ($contact['contact-type'] != Contact::ACCOUNT_TYPE_RELAY)) { logger("queue message"); // queue message for redelivery diff --git a/src/Protocol/PortableContact.php b/src/Protocol/PortableContact.php index 8ce732bfc..0e4d58d1c 100644 --- a/src/Protocol/PortableContact.php +++ b/src/Protocol/PortableContact.php @@ -86,13 +86,14 @@ class PortableContact logger('load: ' . $url, LOGGER_DEBUG); - $s = Network::fetchUrl($url); + $fetchresult = Network::fetchUrlFull($url); + $s = $fetchresult->getBody(); logger('load: returns ' . $s, LOGGER_DATA); - logger('load: return code: ' . Network::getCurl()->getCode(), LOGGER_DEBUG); + logger('load: return code: ' . $fetchresult->getReturnCode(), LOGGER_DEBUG); - if ((Network::getCurl()->getCode() > 299) || (! $s)) { + if (($fetchresult->getReturnCode() > 299) || (! $s)) { return; } diff --git a/src/Protocol/Salmon.php b/src/Protocol/Salmon.php index 02d08c3d4..e3407844a 100644 --- a/src/Protocol/Salmon.php +++ b/src/Protocol/Salmon.php @@ -193,7 +193,7 @@ class Salmon return -1; } - if (($return_code == 503) && (stristr(Network::getCurl()->getHeaders(), 'retry-after'))) { + if (($return_code == 503) && (stristr($postResult->getHeader(), 'retry-after'))) { return -1; } diff --git a/src/Util/Network.php b/src/Util/Network.php index f8e4ee9e5..00eaa80fa 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -208,10 +208,6 @@ class Network $curl_info = @curl_getinfo($ch); } - if (curl_errno($ch) !== CURLE_OK) { - logger('error fetching ' . $url . ': ' . curl_error($ch), LOGGER_INFO); - } - $curlResponse = new Curl($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); if ($curlResponse->isRedirectUrl()) { From b2e7ce47b31cbc79dbba2bac91a425f4df63cad8 Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Wed, 10 Oct 2018 22:08:13 +0200 Subject: [PATCH 4/5] Renaming Curl to CurlResult --- src/Network/{Curl.php => CurlResult.php} | 10 +++------- src/Util/Network.php | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 17 deletions(-) rename src/Network/{Curl.php => CurlResult.php} (98%) diff --git a/src/Network/Curl.php b/src/Network/CurlResult.php similarity index 98% rename from src/Network/Curl.php rename to src/Network/CurlResult.php index 7cab25ee8..d100361e2 100644 --- a/src/Network/Curl.php +++ b/src/Network/CurlResult.php @@ -8,7 +8,7 @@ use Friendica\Network\HTTPException\InternalServerErrorException; /** * A content class for Curl call results */ -class Curl +class CurlResult { /** * @var int HTTP return code or 0 if timeout or failure @@ -75,15 +75,11 @@ class Curl * * @param string $url optional URL * - * @return Curl a CURL with error response + * @return CurlResult a CURL with error response */ public static function createErrorCurl($url = '') { - return new Curl( - $url, - '', - [ 'http_code' => 0 ] - ); + return new CurlResult($url,'', [ 'http_code' => 0 ]); } /** diff --git a/src/Util/Network.php b/src/Util/Network.php index 00eaa80fa..1038fa3f0 100644 --- a/src/Util/Network.php +++ b/src/Util/Network.php @@ -7,7 +7,7 @@ namespace Friendica\Util; use Friendica\Core\Addon; use Friendica\Core\System; use Friendica\Core\Config; -use Friendica\Network\Curl; +use Friendica\Network\CurlResult; use DOMDocument; use DomXPath; @@ -53,7 +53,7 @@ class Network * @param string $accept_content supply Accept: header with 'accept_content' as the value * @param string $cookiejar Path to cookie jar file * - * @return Curl With all relevant information, 'body' contains the actual fetched content. + * @return CurlResult With all relevant information, 'body' contains the actual fetched content. */ public static function fetchUrlFull($url, $binary = false, &$redirects = 0, $timeout = 0, $accept_content = null, $cookiejar = '') { @@ -83,7 +83,7 @@ class Network * 'nobody' => only return the header * 'cookiejar' => path to cookie jar file * - * @return Curl + * @return CurlResult */ public static function curl($url, $binary = false, &$redirects = 0, $opts = []) { @@ -107,13 +107,13 @@ class Network if (self::isUrlBlocked($url)) { logger('domain of ' . $url . ' is blocked', LOGGER_DATA); - return Curl::createErrorCurl($url); + return CurlResult::createErrorCurl($url); } $ch = @curl_init($url); if (($redirects > 8) || (!$ch)) { - return Curl::createErrorCurl($url); + return CurlResult::createErrorCurl($url); } @curl_setopt($ch, CURLOPT_HEADER, true); @@ -208,7 +208,7 @@ class Network $curl_info = @curl_getinfo($ch); } - $curlResponse = new Curl($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); + $curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); if ($curlResponse->isRedirectUrl()) { $redirects++; @@ -233,7 +233,7 @@ class Network * @param integer $redirects Recursion counter for internal use - default = 0 * @param integer $timeout The timeout in seconds, default system config value or 60 seconds * - * @return Curl The content + * @return CurlResult The content */ public static function post($url, $params, $headers = null, &$redirects = 0, $timeout = 0) { @@ -241,14 +241,14 @@ class Network if (self::isUrlBlocked($url)) { logger('post_url: domain of ' . $url . ' is blocked', LOGGER_DATA); - return Curl::createErrorCurl($url); + return CurlResult::createErrorCurl($url); } $a = get_app(); $ch = curl_init($url); if (($redirects > 8) || (!$ch)) { - return Curl::createErrorCurl($url); + return CurlResult::createErrorCurl($url); } logger('post_url: start ' . $url, LOGGER_DATA); @@ -310,7 +310,7 @@ class Network $base = $s; $curl_info = curl_getinfo($ch); - $curlResponse = new Curl($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); + $curlResponse = new CurlResult($url, $s, $curl_info, curl_errno($ch), curl_error($ch)); if ($curlResponse->isRedirectUrl()) { $redirects++; From 9711581d4972f3418f3246c84c5310053df8d2f4 Mon Sep 17 00:00:00 2001 From: Philipp Holzer Date: Wed, 10 Oct 2018 22:51:26 +0200 Subject: [PATCH 5/5] Code standard --- src/Network/CurlResult.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Network/CurlResult.php b/src/Network/CurlResult.php index d100361e2..dc83182a6 100644 --- a/src/Network/CurlResult.php +++ b/src/Network/CurlResult.php @@ -79,7 +79,7 @@ class CurlResult */ public static function createErrorCurl($url = '') { - return new CurlResult($url,'', [ 'http_code' => 0 ]); + return new CurlResult($url, '', ['http_code' => 0]); } /**