/**
* @file src/Network/Probe.php
- * @brief Functions for probing URL
+ * Functions for probing URL
*/
use DOMDocument;
use DomXPath;
-use Friendica\Core\Cache;
-use Friendica\Core\Config;
+use Friendica\Core\Cache\Duration;
use Friendica\Core\Logger;
use Friendica\Core\Protocol;
-use Friendica\Core\System;
use Friendica\Database\DBA;
+use Friendica\DI;
use Friendica\Model\Contact;
use Friendica\Model\Profile;
use Friendica\Protocol\ActivityNamespace;
use Friendica\Util\XML;
/**
- * @brief This class contain functions for probing URL
+ * This class contain functions for probing URL
*
*/
class Probe
private static $istimeout;
/**
- * @brief Rearrange the array so that it always has the same order
+ * Rearrange the array so that it always has the same order
*
* @param array $data Unordered data
*
}
/**
- * @brief Check if the hostname belongs to the own server
+ * Check if the hostname belongs to the own server
*
* @param string $host The hostname that is to be checked
*
*/
private static function ownHost($host)
{
- $own_host = \get_app()->getHostName();
+ $own_host = DI::baseUrl()->getHostname();
$parts = parse_url($host);
}
/**
- * @brief Probes for webfinger path via "host-meta"
+ * Probes for webfinger path via "host-meta"
*
* We have to check if the servers in the future still will offer this.
* It seems as if it was dropped from the standard.
$ssl_url = "https://".$host."/.well-known/host-meta";
$url = "http://".$host."/.well-known/host-meta";
- $xrd_timeout = Config::get('system', 'xrd_timeout', 20);
+ $xrd_timeout = DI::config()->get('system', 'xrd_timeout', 20);
Logger::log("Probing for ".$host, Logger::DEBUG);
$xrd = null;
$curlResult = Network::curl($ssl_url, false, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']);
+ $ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0);
if ($curlResult->isSuccess()) {
$xml = $curlResult->getBody();
$xrd = XML::parseString($xml, false);
$host_url = 'https://'.$host;
+ } elseif ($curlResult->isTimeout()) {
+ Logger::info('Probing timeout', ['url' => $ssl_url], Logger::DEBUG);
+ self::$istimeout = true;
+ return false;
}
if (!is_object($xrd)) {
$curlResult = Network::curl($url, false, ['timeout' => $xrd_timeout, 'accept_content' => 'application/xrd+xml']);
+ $connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0);
if ($curlResult->isTimeout()) {
- Logger::log("Probing timeout for " . $url, Logger::DEBUG);
+ Logger::info('Probing timeout', ['url' => $url], Logger::DEBUG);
+ self::$istimeout = true;
+ return false;
+ } elseif ($connection_error && $ssl_connection_error) {
self::$istimeout = true;
return false;
}
+
$xml = $curlResult->getBody();
$xrd = XML::parseString($xml, false);
$host_url = 'http://'.$host;
}
/**
- * @brief Perform Webfinger lookup and return DFRN data
+ * Perform Webfinger lookup and return DFRN data
*
* Given an email style address, perform webfinger lookup and
* return the resulting DFRN profile URL, or if no DFRN profile URL
}
/**
- * @brief Check an URI for LRDD data
+ * Check an URI for LRDD data
*
* this is a replacement for the "lrdd" function.
* It isn't used in this class and has some redundancies in the code.
}
/**
- * @brief Fetch information (protocol endpoints and user information) about a given uri
+ * Fetch information (protocol endpoints and user information) about a given uri
*
* @param string $uri Address that should be probed
* @param string $network Test for this specific network
public static function uri($uri, $network = '', $uid = -1, $cache = true)
{
if ($cache) {
- $result = Cache::get('Probe::uri:' . $network . ':' . $uri);
+ $result = DI::cache()->get('Probe::uri:' . $network . ':' . $uri);
if (!is_null($result)) {
return $result;
}
if (!empty($data['photo']) && !empty($data['baseurl'])) {
$data['baseurl'] = Network::getUrlMatch(Strings::normaliseLink($data['baseurl']), Strings::normaliseLink($data['photo']));
} elseif (empty($data['photo'])) {
- $data['photo'] = System::baseUrl() . '/images/person-300.jpg';
+ $data['photo'] = DI::baseUrl() . '/images/person-300.jpg';
}
if (empty($data['name'])) {
$data['network'] = Protocol::PHANTOM;
}
+ // Ensure that local connections always are DFRN
+ if (($network == '') && ($data['network'] != Protocol::PHANTOM) && (self::ownHost($data['baseurl'] ?? '') || self::ownHost($data['url']))) {
+ $data['network'] = Protocol::DFRN;
+ }
+
if (!isset($data['hide']) && in_array($data['network'], Protocol::FEDERATED)) {
$data['hide'] = self::getHideStatus($data['url']);
}
// Only store into the cache if the value seems to be valid
if (!in_array($data['network'], [Protocol::PHANTOM, Protocol::MAIL])) {
- Cache::set('Probe::uri:' . $network . ':' . $uri, $data, Cache::DAY);
+ DI::cache()->set('Probe::uri:' . $network . ':' . $uri, $data, Duration::DAY);
}
return $data;
}
/**
- * @brief Checks if a profile url should be OStatus but only provides partial information
+ * Checks if a profile url should be OStatus but only provides partial information
*
* @param array $webfinger Webfinger data
* @param string $lrdd Path template for webfinger request
}
/**
- * @brief Fetch information (protocol endpoints and user information) about a given uri
+ * Fetch information (protocol endpoints and user information) about a given uri
*
* This function is only called by the "uri" function that adds caching and rearranging of data.
*
if ((!$result && ($network == "")) || ($network == Protocol::OSTATUS)) {
$result = self::ostatus($webfinger);
}
-// if (in_array($network, ['', Protocol::ZOT])) {
-// $result = self::zot($webfinger, $result);
-// }
+ if (in_array($network, ['', Protocol::ZOT])) {
+ $result = self::zot($webfinger, $result);
+ }
if ((!$result && ($network == "")) || ($network == Protocol::PUMPIO)) {
$result = self::pumpio($webfinger, $addr);
}
if (empty($zot_url) && !empty($data['addr']) && !empty(self::$baseurl)) {
$condition = ['nurl' => Strings::normaliseLink(self::$baseurl), 'platform' => ['hubzilla']];
if (!DBA::exists('gserver', $condition)) {
- exit;
+ return $data;
}
$zot_url = self::$baseurl . '/.well-known/zot-info?address=' . $data['addr'];
}
- if (!empty($zot_url)) {
- $data = self::pollZot($zot_url, $data);
+ if (empty($zot_url)) {
+ return $data;
+ }
+
+ $data = self::pollZot($zot_url, $data);
+
+ if (!empty($data['url']) && !empty($webfinger['aliases']) && is_array($webfinger['aliases'])) {
+ foreach ($webfinger['aliases'] as $alias) {
+ if (!strstr($alias, '@') && Strings::normaliseLink($alias) != Strings::normaliseLink($data['url'])) {
+ $data['alias'] = $alias;
+ }
+ }
}
return $data;
if (!is_array($json)) {
return $data;
}
-//print_r($json);
+
if (empty($data['network'])) {
if (!empty($json['protocols']) && in_array('zot', $json['protocols'])) {
$data['network'] = Protocol::ZOT;
if (!empty($profile['country'])) {
$loc['country-name'] = $profile['country'];
}
- if (!empty($profile['hometown'])) {
- $loc['locality'] = $profile['hometown'];
- }
$location = Profile::formatLocation($loc);
if (!empty($location)) {
$data['location'] = $location;
}
/**
- * @brief Perform a webfinger request.
+ * Perform a webfinger request.
*
* For details see RFC 7033: <https://tools.ietf.org/html/rfc7033>
*
*/
private static function webfinger($url, $type)
{
- $xrd_timeout = Config::get('system', 'xrd_timeout', 20);
+ $xrd_timeout = DI::config()->get('system', 'xrd_timeout', 20);
$curlResult = Network::curl($url, false, ['timeout' => $xrd_timeout, 'accept_content' => $type]);
if ($curlResult->isTimeout()) {
}
/**
- * @brief Poll the Friendica specific noscrape page.
+ * Poll the Friendica specific noscrape page.
*
* "noscrape" is a faster alternative to fetch the data from the hcard.
* This functionality was originally created for the directory.
}
/**
- * @brief Check for valid DFRN data
+ * Check for valid DFRN data
*
* @param array $data DFRN data
*
}
/**
- * @brief Fetch data from a DFRN profile page and via "noscrape"
+ * Fetch data from a DFRN profile page and via "noscrape"
*
* @param string $profile_link Link to the profile page
*
}
/**
- * @brief Check for DFRN contact
+ * Check for DFRN contact
*
* @param array $webfinger Webfinger data
*
}
/**
- * @brief Poll the hcard page (Diaspora and Friendica specific)
+ * Poll the hcard page (Diaspora and Friendica specific)
*
* @param string $hcard_url Link to the hcard page
* @param array $data The already fetched data
}
/**
- * @brief Check for Diaspora contact
+ * Check for Diaspora contact
*
* @param array $webfinger Webfinger data
*
}
if (empty($data["url"]) || empty($hcard_url)) {
- return $data;
+ return false;
}
if (!empty($webfinger["aliases"]) && is_array($webfinger["aliases"])) {
}
/**
- * @brief Check for OStatus contact
+ * Check for OStatus contact
*
* @param array $webfinger Webfinger data
* @param bool $short Short detection mode
return false;
}
$feed = $curlResult->getBody();
- $dummy1 = null;
- $dummy2 = null;
- $dummy2 = null;
- $feed_data = Feed::import($feed, $dummy1, $dummy2, $dummy3, true);
+ $feed_data = Feed::import($feed);
if (!$feed_data) {
return false;
}
}
/**
- * @brief Fetch data from a pump.io profile page
+ * Fetch data from a pump.io profile page
*
* @param string $profile_link Link to the profile page
*
*/
private static function pumpioProfileData($profile_link)
{
+ $curlResult = Network::curl($profile_link);
+ if (!$curlResult->isSuccess()) {
+ return false;
+ }
+
$doc = new DOMDocument();
- if (!@$doc->loadHTMLFile($profile_link)) {
+ if (!@$doc->loadHTML($curlResult->getBody())) {
return false;
}
}
/**
- * @brief Check for pump.io contact
+ * Check for pump.io contact
*
* @param array $webfinger Webfinger data
* @param string $addr
}
/**
- * @brief Check for twitter contact
+ * Check for twitter contact
*
* @param string $uri
*
}
/**
- * @brief Check page for feed link
+ * Check page for feed link
*
* @param string $url Page link
*
*/
private static function getFeedLink($url)
{
- $doc = new DOMDocument();
+ $curlResult = Network::curl($url);
+ if (!$curlResult->isSuccess()) {
+ return false;
+ }
- if (!@$doc->loadHTMLFile($url)) {
+ $doc = new DOMDocument();
+ if (!@$doc->loadHTML($curlResult->getBody())) {
return false;
}
}
/**
- * @brief Check for feed contact
+ * Check for feed contact
*
* @param string $url Profile link
* @param boolean $probe Do a probe if the page contains a feed link
return false;
}
$feed = $curlResult->getBody();
- $dummy1 = $dummy2 = $dummy3 = null;
- $feed_data = Feed::import($feed, $dummy1, $dummy2, $dummy3, true);
+ $feed_data = Feed::import($feed);
if (!$feed_data) {
if (!$probe) {
}
/**
- * @brief Check for mail contact
+ * Check for mail contact
*
* @param string $uri Profile link
* @param integer $uid User ID
}
/**
- * @brief Mix two paths together to possibly fix missing parts
+ * Mix two paths together to possibly fix missing parts
*
* @param string $avatar Path to the avatar
* @param string $base Another path that is hopefully complete