X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FNetwork%2FProbe.php;h=a6987d0a64c4a2e4b3ef5f8ede319dcbb57acaa9;hb=15bc1ac8a18924551c8af772c07e5fed9c75023b;hp=ef899b6c1a2b4727d66265c6f85d01ecc7896732;hpb=803c1d71de9e6d13da9576660c9ab8b8bb2c19f3;p=friendica.git diff --git a/src/Network/Probe.php b/src/Network/Probe.php index ef899b6c1a..a6987d0a64 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -1,6 +1,6 @@ getScheme()) { + return $uri->__toString(); } // Remove the URL fragment, since these shouldn't be part of any profile URL - unset($parts['fragment']); - - $URI = Network::unparseURL($parts); + $uri = $uri->withFragment(''); - return $URI; + return $uri->__toString(); } /** @@ -101,7 +100,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)) { @@ -170,7 +169,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(); @@ -187,7 +186,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]); @@ -231,6 +230,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]); @@ -424,13 +428,13 @@ class Probe */ private static function getHideStatus($url) { - $curlResult = DI::httpRequest()->get($url, false, ['content_length' => 1000000]); + $curlResult = DI::httpClient()->get($url, [HttpClientOptions::CONTENT_LENGTH => 1000000]); if (!$curlResult->isSuccess()) { return false; } // If it isn't a HTML file then exit - if (!in_array('html', $curlResult->getContentType())) { + if (($curlResult->getContentType() != '') && !strstr(strtolower($curlResult->getContentType()), 'html')) { return false; } @@ -502,16 +506,17 @@ class Probe * Get webfinger data from a given URI * * @param string $uri - * @return array Webfinger array + * @return array + * @throws HTTPException\InternalServerErrorException */ - private static function getWebfingerArray(string $uri) + private static function getWebfingerArray(string $uri): array { $parts = parse_url($uri); if (!empty($parts['scheme']) && !empty($parts['host'])) { $host = $parts['host']; if (!empty($parts['port'])) { - $host .= ':'.$parts['port']; + $host .= ':' . $parts['port']; } $baseurl = $parts['scheme'] . '://' . $host; @@ -519,15 +524,10 @@ class Probe $nick = ''; $addr = ''; - $path_parts = explode("/", trim($parts['path'] ?? '', "/")); + $path_parts = explode('/', trim($parts['path'] ?? '', '/')); if (!empty($path_parts)) { $nick = ltrim(end($path_parts), '@'); - // When the last part of the URI is numeric then it is most likely an ID and not a nick name - if (!is_numeric($nick)) { - $addr = $nick."@".$host; - } else { - $nick = ''; - } + $addr = $nick . '@' . $host; } $webfinger = self::getWebfinger($parts['scheme'] . '://' . $host . self::WEBFINGER, 'application/jrd+json', $uri, $addr); @@ -537,11 +537,11 @@ class Probe if (empty($webfinger) && empty($lrdd)) { while (empty($lrdd) && empty($webfinger) && (sizeof($path_parts) > 1)) { - $host .= "/".array_shift($path_parts); + $host .= '/' . array_shift($path_parts); $baseurl = $parts['scheme'] . '://' . $host; if (!empty($nick)) { - $addr = $nick."@".$host; + $addr = $nick . '@' . $host; } $webfinger = self::getWebfinger($parts['scheme'] . '://' . $host . self::WEBFINGER, 'application/jrd+json', $uri, $addr); @@ -625,6 +625,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; @@ -671,46 +676,31 @@ class Probe 'uri' => $uri, 'network' => $network, 'uid' => $uid, - 'result' => [], + 'result' => null, ]; Hook::callAll('probe_detect', $hookData); - if ($hookData['result']) { - if (!is_array($hookData['result'])) { - return []; - } else { - return $hookData['result']; - } + if (isset($hookData['result'])) { + return is_array($hookData['result']) ? $hookData['result'] : []; } $parts = parse_url($uri); - - if (!empty($parts['scheme']) && !empty($parts['host'])) { - if (in_array($parts['host'], ['twitter.com', 'mobile.twitter.com'])) { - return self::twitter($uri); - } - } elseif (strstr($uri, '@')) { - // If the URI starts with "mailto:" then jump directly to the mail detection - if (strpos($uri, 'mailto:') !== false) { - $uri = str_replace('mailto:', '', $uri); - return self::mail($uri, $uid); - } - - if ($network == Protocol::MAIL) { - return self::mail($uri, $uid); - } - - if (Strings::endsWith($uri, '@twitter.com') - || Strings::endsWith($uri, '@mobile.twitter.com') - ) { - return self::twitter($uri); - } - } else { + if (empty($parts['scheme']) && empty($parts['host']) && !strstr($parts['path'], '@')) { Logger::info('URI was not detectable', ['uri' => $uri]); return []; } + // If the URI starts with "mailto:" then jump directly to the mail detection + if (strpos($uri, 'mailto:') !== false) { + $uri = str_replace('mailto:', '', $uri); + return self::mail($uri, $uid); + } + + if ($network == Protocol::MAIL) { + return self::mail($uri, $uid); + } + Logger::info('Probing start', ['uri' => $uri]); if (!empty($ap_profile['addr']) && ($ap_profile['addr'] != $uri)) { @@ -843,7 +833,7 @@ class Probe public static function pollZot($url, $data) { - $curlResult = DI::httpRequest()->get($url); + $curlResult = DI::httpClient()->get($url); if ($curlResult->isTimeout()) { return $data; } @@ -940,7 +930,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 []; @@ -1009,7 +999,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; @@ -1275,7 +1265,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 []; @@ -1536,7 +1526,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 : []; @@ -1570,7 +1560,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 []; @@ -1622,7 +1612,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 []; } @@ -1731,33 +1721,6 @@ class Probe return $data; } - /** - * Check for twitter contact - * - * @param string $uri - * - * @return array twitter data - */ - private static function twitter($uri) - { - if (preg_match('=([^@]+)@(?:mobile\.)?twitter\.com$=i', $uri, $matches)) { - $nick = $matches[1]; - } elseif (preg_match('=^https?://(?:mobile\.)?twitter\.com/(.+)=i', $uri, $matches)) { - $nick = $matches[1]; - } else { - return []; - } - - $data = []; - $data['url'] = 'https://twitter.com/' . $nick; - $data['addr'] = $nick . '@twitter.com'; - $data['nick'] = $data['name'] = $nick; - $data['network'] = Protocol::TWITTER; - $data['baseurl'] = 'https://twitter.com'; - - return $data; - } - /** * Checks HTML page for RSS feed link * @@ -1862,7 +1825,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 []; @@ -1985,8 +1948,6 @@ class Probe $data["name"] .= $perspart->text; } } - - $data["name"] = Strings::escapeTags($data["name"]); } } } @@ -2037,7 +1998,7 @@ class Probe /** * Fetch the last date that the contact had posted something (publically) * - * @param string $data probing result + * @param array $data probing result * @return string last activity */ public static function getLastUpdate(array $data) @@ -2086,7 +2047,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); @@ -2161,7 +2122,7 @@ class Probe private static function updateFromFeed(array $data) { // Search for the newest entry in the feed - $curlResult = DI::httpRequest()->get($data['poll']); + $curlResult = DI::httpClient()->get($data['poll']); if (!$curlResult->isSuccess() || !$curlResult->getBody()) { return ''; } @@ -2219,29 +2180,29 @@ class Probe throw new HTTPException\NotFoundException('User not found.'); } - $profile = User::getOwnerDataById($uid); + $owner = User::getOwnerDataById($uid); $approfile = ActivityPub\Transmitter::getProfile($uid); - if (empty($profile['gsid'])) { - $profile['gsid'] = GServer::getID($approfile['generator']['url']); + if (empty($owner['gsid'])) { + $owner['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' => Contact::getAvatarUrlForId($profile['id'], '', $profile['updated']), - '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'], + 'name' => $owner['name'], 'nick' => $owner['nick'], 'guid' => $approfile['diaspora:guid'] ?? '', + 'url' => $owner['url'], 'addr' => $owner['addr'], 'alias' => $owner['alias'], + 'photo' => User::getAvatarUrl($owner), + 'header' => $owner['header'] ? Contact::getHeaderUrlForId($owner['id'], $owner['updated']) : '', + 'account-type' => $owner['contact-type'], 'community' => ($owner['contact-type'] == User::ACCOUNT_TYPE_COMMUNITY), + 'keywords' => $owner['keywords'], 'location' => $owner['location'], 'about' => $owner['about'], + 'xmpp' => $owner['xmpp'], 'matrix' => $owner['matrix'], + 'hide' => !$owner['net-publish'], 'batch' => '', 'notify' => $owner['notify'], + 'poll' => $owner['poll'], 'request' => $owner['request'], 'confirm' => $owner['confirm'], + 'subscribe' => $approfile['generator']['url'] . '/follow?url={uri}', 'poco' => $owner['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]) + 'pubkey' => $owner['upubkey'], 'baseurl' => $approfile['generator']['url'], 'gsid' => $owner['gsid'], + 'manually-approve' => in_array($owner['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP]) ]; } catch (Exception $e) { // Default values for non existing targets