X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2FProbe.php;h=4aa50b4be5a71b91438ab7025192a106314e6349;hb=865006682a3952565035207898b80dfbd6d390b1;hp=d6ae415d30b13aee085a22de4e7572c8e99d15af;hpb=fe07dc828b62c9d1e6a75939d6cbb537d5196912;p=friendica.git diff --git a/src/Network/Probe.php b/src/Network/Probe.php index d6ae415d30..4aa50b4be5 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -23,6 +23,7 @@ namespace Friendica\Network; use DOMDocument; use DomXPath; +use Exception; use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\Core\Protocol; @@ -88,8 +89,8 @@ class Probe private static function rearrangeData($data) { $fields = ["name", "nick", "guid", "url", "addr", "alias", "photo", "header", - "account-type", "community", "keywords", "location", "about", "hide", - "batch", "notify", "poll", "request", "confirm", "subscribe", "poco", + "account-type", "community", "keywords", "location", "about", "xmpp", "matrix", + "hide", "batch", "notify", "poll", "request", "confirm", "subscribe", "poco", "following", "followers", "inbox", "outbox", "sharedinbox", "priority", "network", "pubkey", "manually-approve", "baseurl", "gsid"]; @@ -100,7 +101,7 @@ class Probe if (isset($data[$field])) { if (in_array($field, $numeric_fields)) { $newdata[$field] = (int)$data[$field]; - } else { + } else { $newdata[$field] = $data[$field]; } } elseif (!in_array($field, $numeric_fields)) { @@ -169,7 +170,7 @@ class Probe Logger::info('Probing', ['host' => $host, 'ssl_url' => $ssl_url, 'url' => $url, 'callstack' => System::callstack(20)]); $xrd = null; - $curlResult = DI::httpRequest()->get($ssl_url, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); + $curlResult = DI::httpClient()->get($ssl_url, [HTTPClientOptions::TIMEOUT => $xrd_timeout, HTTPClientOptions::ACCEPT_CONTENT => ['application/xrd+xml']]); $ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0); if ($curlResult->isSuccess()) { $xml = $curlResult->getBody(); @@ -186,7 +187,7 @@ class Probe } if (!is_object($xrd) && !empty($url)) { - $curlResult = DI::httpRequest()->get($url, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']); + $curlResult = DI::httpClient()->get($url, [HTTPClientOptions::TIMEOUT => $xrd_timeout, HTTPClientOptions::ACCEPT_CONTENT => ['application/xrd+xml']]); $connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0); if ($curlResult->isTimeout()) { Logger::info('Probing timeout', ['url' => $url]); @@ -230,6 +231,11 @@ class Probe } } + if (Network::isUrlBlocked($host_url)) { + Logger::info('Domain is blocked', ['url' => $host]); + return []; + } + self::$baseurl = $host_url; Logger::info('Probing successful', ['host' => $host]); @@ -333,7 +339,7 @@ class Probe public static function uri($uri, $network = '', $uid = -1) { // Local profiles aren't probed via network - if (empty($network) && strpos($uri, DI::baseUrl()->getHostname())) { + if (empty($network) && Contact::isLocal($uri)) { $data = self::localProbe($uri); if (!empty($data)) { return $data; @@ -423,16 +429,11 @@ class Probe */ private static function getHideStatus($url) { - $curlResult = DI::httpRequest()->get($url); + $curlResult = DI::httpClient()->get($url, [HTTPClientOptions::CONTENT_LENGTH => 1000000]); if (!$curlResult->isSuccess()) { return false; } - // If the file is too large then exit - if (($curlResult->getInfo()['download_content_length'] ?? 0) > 1000000) { - return false; - } - // If it isn't a HTML file then exit if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return false; @@ -629,6 +630,11 @@ class Probe */ private static function getWebfinger(string $template, string $type, string $uri, string $addr) { + if (Network::isUrlBlocked($template)) { + Logger::info('Domain is blocked', ['url' => $template]); + return []; + } + // First try the address because this is the primary purpose of webfinger if (!empty($addr)) { $detected = $addr; @@ -847,7 +853,7 @@ class Probe public static function pollZot($url, $data) { - $curlResult = DI::httpRequest()->get($url); + $curlResult = DI::httpClient()->get($url); if ($curlResult->isTimeout()) { return $data; } @@ -944,7 +950,7 @@ class Probe { $xrd_timeout = DI::config()->get('system', 'xrd_timeout', 20); - $curlResult = DI::httpRequest()->get($url, ['timeout' => $xrd_timeout, 'accept_content' => $type]); + $curlResult = DI::httpClient()->get($url, [HTTPClientOptions::TIMEOUT => $xrd_timeout, HTTPClientOptions::ACCEPT_CONTENT => [$type]]); if ($curlResult->isTimeout()) { self::$istimeout = true; return []; @@ -1013,7 +1019,7 @@ class Probe */ private static function pollNoscrape($noscrape_url, $data) { - $curlResult = DI::httpRequest()->get($noscrape_url); + $curlResult = DI::httpClient()->get($noscrape_url); if ($curlResult->isTimeout()) { self::$istimeout = true; return $data; @@ -1066,6 +1072,14 @@ class Probe $data["about"] = $json["about"]; } + if (!empty($json["xmpp"])) { + $data["xmpp"] = $json["xmpp"]; + } + + if (!empty($json["matrix"])) { + $data["matrix"] = $json["matrix"]; + } + if (!empty($json["key"])) { $data["pubkey"] = $json["key"]; } @@ -1271,7 +1285,7 @@ class Probe */ private static function pollHcard($hcard_url, $data, $dfrn = false) { - $curlResult = DI::httpRequest()->get($hcard_url); + $curlResult = DI::httpClient()->get($hcard_url); if ($curlResult->isTimeout()) { self::$istimeout = true; return []; @@ -1411,6 +1425,8 @@ class Probe $data["guid"] = $link["href"]; } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && (($link["type"] ?? "") == "text/html") && !empty($link["href"])) { $data["url"] = $link["href"]; + } elseif (($link["rel"] == "http://webfinger.net/rel/profile-page") && empty($link["type"]) && !empty($link["href"])) { + $profile_url = $link["href"]; } elseif (($link["rel"] == ActivityNamespace::FEED) && !empty($link["href"])) { $data["poll"] = $link["href"]; } elseif (($link["rel"] == ActivityNamespace::POCO) && !empty($link["href"])) { @@ -1427,6 +1443,10 @@ class Probe } } + if (empty($data["url"]) && !empty($profile_url)) { + $data["url"] = $profile_url; + } + if (empty($data["url"]) || empty($hcard_url)) { return []; } @@ -1526,7 +1546,7 @@ class Probe $pubkey = substr($pubkey, 5); } } elseif (Strings::normaliseLink($pubkey) == 'http://') { - $curlResult = DI::httpRequest()->get($pubkey); + $curlResult = DI::httpClient()->get($pubkey); if ($curlResult->isTimeout()) { self::$istimeout = true; return $short ? false : []; @@ -1560,7 +1580,7 @@ class Probe } // Fetch all additional data from the feed - $curlResult = DI::httpRequest()->get($data["poll"]); + $curlResult = DI::httpClient()->get($data["poll"]); if ($curlResult->isTimeout()) { self::$istimeout = true; return []; @@ -1612,7 +1632,7 @@ class Probe */ private static function pumpioProfileData($profile_link) { - $curlResult = DI::httpRequest()->get($profile_link); + $curlResult = DI::httpClient()->get($profile_link); if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { return []; } @@ -1852,7 +1872,7 @@ class Probe */ private static function feed($url, $probe = true) { - $curlResult = DI::httpRequest()->get($url); + $curlResult = DI::httpClient()->get($url); if ($curlResult->isTimeout()) { self::$istimeout = true; return []; @@ -2076,7 +2096,7 @@ class Probe return ''; } - $curlResult = DI::httpRequest()->get($gserver['noscrape'] . '/' . $data['nick']); + $curlResult = DI::httpClient()->get($gserver['noscrape'] . '/' . $data['nick']); if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { $noscrape = json_decode($curlResult->getBody(), true); @@ -2151,8 +2171,8 @@ class Probe private static function updateFromFeed(array $data) { // Search for the newest entry in the feed - $curlResult = DI::httpRequest()->get($data['poll']); - if (!$curlResult->isSuccess()) { + $curlResult = DI::httpClient()->get($data['poll']); + if (!$curlResult->isSuccess() || !$curlResult->getBody()) { return ''; } @@ -2198,41 +2218,49 @@ class Probe * * @param string $url * @return array probed data + * @throws HTTPException\InternalServerErrorException + * @throws HTTPException\NotFoundException */ - private static function localProbe(string $url) + private static function localProbe(string $url): array { - $uid = User::getIdForURL($url); - if (empty($uid)) { - return []; + try { + $uid = User::getIdForURL($url); + if (!$uid) { + throw new HTTPException\NotFoundException('User not found.'); + } + + $profile = User::getOwnerDataById($uid); + $approfile = ActivityPub\Transmitter::getProfile($uid); + + if (empty($profile['gsid'])) { + $profile['gsid'] = GServer::getID($approfile['generator']['url']); + } + + $data = [ + 'name' => $profile['name'], 'nick' => $profile['nick'], 'guid' => $approfile['diaspora:guid'] ?? '', + 'url' => $profile['url'], 'addr' => $profile['addr'], 'alias' => $profile['alias'], + 'photo' => User::getAvatarUrlForId($uid), + 'header' => $profile['header'] ? Contact::getHeaderUrlForId($profile['id'], $profile['updated']) : '', + 'account-type' => $profile['contact-type'], 'community' => ($profile['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY), + 'keywords' => $profile['keywords'], 'location' => $profile['location'], 'about' => $profile['about'], + 'xmpp' => $profile['xmpp'], 'matrix' => $profile['matrix'], + 'hide' => !$profile['net-publish'], 'batch' => '', 'notify' => $profile['notify'], + 'poll' => $profile['poll'], 'request' => $profile['request'], 'confirm' => $profile['confirm'], + 'subscribe' => $approfile['generator']['url'] . '/follow?url={uri}', 'poco' => $profile['poco'], + 'following' => $approfile['following'], 'followers' => $approfile['followers'], + 'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'], + 'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN, + 'pubkey' => $profile['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $profile['gsid'], + 'manually-approve' => in_array($profile['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]) + ]; + } catch (Exception $e) { + // Default values for non existing targets + $data = [ + 'name' => $url, 'nick' => $url, 'url' => $url, 'network' => Protocol::PHANTOM, + 'photo' => DI::baseUrl() . Contact::DEFAULT_AVATAR_PHOTO + ]; } - $profile = User::getOwnerDataById($uid); - if (empty($profile)) { - return []; - } - - $approfile = ActivityPub\Transmitter::getProfile($uid); - if (empty($approfile)) { - return []; - } - - if (empty($profile['gsid'])) { - $profile['gsid'] = GServer::getID($approfile['generator']['url']); - } - - $data = ['name' => $profile['name'], 'nick' => $profile['nick'], 'guid' => $approfile['diaspora:guid'] ?? '', - 'url' => $profile['url'], 'addr' => $profile['addr'], 'alias' => $profile['alias'], - 'photo' => $profile['photo'], 'header' => $profile['header'], 'account-type' => $profile['contact-type'], - 'community' => ($profile['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY), - 'keywords' => $profile['keywords'], 'location' => $profile['location'], 'about' => $profile['about'], - 'hide' => !$profile['net-publish'], 'batch' => '', 'notify' => $profile['notify'], - 'poll' => $profile['poll'], 'request' => $profile['request'], 'confirm' => $profile['confirm'], - 'subscribe' => $approfile['generator']['url'] . '/follow?url={uri}', 'poco' => $profile['poco'], - 'following' => $approfile['following'], 'followers' => $approfile['followers'], - 'inbox' => $approfile['inbox'], 'outbox' => $approfile['outbox'], - 'sharedinbox' => $approfile['endpoints']['sharedInbox'], 'network' => Protocol::DFRN, - 'pubkey' => $profile['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $profile['gsid'], - 'manually-approve' => in_array($profile['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP])]; - return self::rearrangeData($data); + return self::rearrangeData($data); } }