From 2a8a5a6d880e087df3127b5fe36f6090a489b5a6 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 26 Feb 2017 18:19:20 +0000 Subject: [PATCH] Improved server vitality detection --- include/socgraph.php | 80 +++++++++++++++++++++++++++++++++++++++++--- mod/admin.php | 6 ++-- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/include/socgraph.php b/include/socgraph.php index a0dd88df2d..ff9467748f 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -680,6 +680,43 @@ function poco_to_boolean($val) { return ($val); } +function poco_detect_friendica_server($body) { + $server = false; + + $doc = new \DOMDocument(); + @$doc->loadHTML($body); + $xpath = new \DomXPath($doc); + + $list = $xpath->query("//meta[@name]"); + + foreach ($list as $node) { + $attr = array(); + if ($node->attributes->length) { + foreach ($node->attributes as $attribute) { + $attr[$attribute->name] = $attribute->value; + } + } + if ($attr['name'] == 'generator') { + $version_part = explode(" ", $attr['content']); + if (count($version_part) == 2) { + if (in_array($version_part[0], array("Friendika", "Friendica"))) { + $server = array(); + $server["platform"] = $version_part[0]; + $server["version"] = $version_part[1]; + $server["network"] = NETWORK_DFRN; + } + } + } + } + + if (!$server) { + return false; + } + + $server["site_name"] = $xpath->evaluate($element."//head/title/text()", $context)->item(0)->nodeValue; + return $server; +} + function poco_check_server($server_url, $network = "", $force = false) { // Unify the server address @@ -729,7 +766,9 @@ function poco_check_server($server_url, $network = "", $force = false) { logger("Server ".$server_url." is outdated or unknown. Start discovery. Force: ".$force." Created: ".$servers[0]["created"]." Failure: ".$last_failure." Contact: ".$last_contact, LOGGER_DEBUG); $failure = false; + $possible_failure = false; $orig_last_failure = $last_failure; + $orig_last_contact = $last_contact; // Check if the page is accessible via SSL. $server_url = str_replace("http://", "https://", $server_url); @@ -750,6 +789,7 @@ function poco_check_server($server_url, $network = "", $force = false) { $last_failure = datetime_convert(); $failure = true; } + $possible_failure = true; } elseif ($network == NETWORK_DIASPORA) $last_contact = datetime_convert(); @@ -757,11 +797,12 @@ function poco_check_server($server_url, $network = "", $force = false) { // Test for Diaspora $serverret = z_fetch_url($server_url); - if (!$serverret["success"] OR ($serverret["body"] == "")) + if (!$serverret["success"] OR ($serverret["body"] == "")) { + $last_failure = datetime_convert(); $failure = true; - else { + } else { $lines = explode("\n",$serverret["header"]); - if(count($lines)) + if(count($lines)) { foreach($lines as $line) { $line = trim($line); if(stristr($line,'X-Diaspora-Version:')) { @@ -771,6 +812,7 @@ function poco_check_server($server_url, $network = "", $force = false) { $network = NETWORK_DIASPORA; $versionparts = explode("-", $version); $version = $versionparts[0]; + $last_contact = datetime_convert(); } if(stristr($line,'Server: Mastodon')) { @@ -778,8 +820,19 @@ function poco_check_server($server_url, $network = "", $force = false) { $network = NETWORK_OSTATUS; // Mastodon doesn't reveal version numbers $version = ""; + $last_contact = datetime_convert(); } } + } + + $friendica_server = poco_detect_friendica_server($serverret["body"]); + if ($friendica_server) { + $platform = $friendica_server['platform']; + $network = $friendica_server['network']; + $version = $friendica_server['version']; + $site_name = $friendica_server['site_name']; + $last_contact = datetime_convert(); + } } } @@ -793,6 +846,7 @@ function poco_check_server($server_url, $network = "", $force = false) { $platform = "StatusNet"; $version = trim($serverret["body"], '"'); $network = NETWORK_OSTATUS; + $last_contact = datetime_convert(); } // Test for GNU Social @@ -802,12 +856,12 @@ function poco_check_server($server_url, $network = "", $force = false) { $platform = "GNU Social"; $version = trim($serverret["body"], '"'); $network = NETWORK_OSTATUS; + $last_contact = datetime_convert(); } $serverret = z_fetch_url($server_url."/api/statusnet/config.json"); if ($serverret["success"]) { $data = json_decode($serverret["body"]); - if (isset($data->site->server)) { $last_contact = datetime_convert(); @@ -847,6 +901,7 @@ function poco_check_server($server_url, $network = "", $force = false) { } } + // Query statistics.json. Optional package for Diaspora, Friendica and Redmatrix if (!$failure) { $serverret = z_fetch_url($server_url."/statistics.json"); @@ -922,6 +977,23 @@ function poco_check_server($server_url, $network = "", $force = false) { } } + if ($possible_failure AND !$failure) { + $last_failure = datetime_convert(); + $failure = true; + } + + if ($failure) { + $last_contact = $orig_last_contact; + } else { + $last_failure = $orig_last_failure; + } + + if (($last_contact <= $last_failure) AND !$failure) { + logger("Server ".$server_url." seems to be alive, but last contact wasn't set - could be a bug", LOGGER_DEBUG); + } else if (($last_contact >= $last_failure) AND $failure) { + logger("Server ".$server_url." seems to be dead, but last failure wasn't set - could be a bug", LOGGER_DEBUG); + } + // Check again if the server exists $servers = q("SELECT `nurl` FROM `gserver` WHERE `nurl` = '%s'", dbesc(normalise_link($server_url))); diff --git a/mod/admin.php b/mod/admin.php index 1475130834..fffc8bf818 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -270,8 +270,8 @@ function admin_page_federation(App $a) { // off one % two of them are needed in the query // Add more platforms if you like, when one returns 0 known nodes it is not // displayed on the stats page. - $platforms = array('Friendica', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon'); - $colors = array('Friendica' => '#ffc018', // orange from the logo + $platforms = array('Friendi%%a', 'Diaspora', '%%red%%', 'Hubzilla', 'BlaBlaNet', 'GNU Social', 'StatusNet', 'Mastodon'); + $colors = array('Friendi%%a' => '#ffc018', // orange from the logo 'Diaspora' => '#a1a1a1', // logo is black and white, makes a gray '%%red%%' => '#c50001', // fire red from the logo 'Hubzilla' => '#43488a', // blue from the logo @@ -333,7 +333,7 @@ function admin_page_federation(App $a) { // early friendica versions have the format x.x.xxxx where xxxx is the // DB version stamp; those should be operated out and versions be // conbined - if($p=='Friendica') { + if($p=='Friendi%%a') { $newV = array(); $newVv = array(); foreach ($v as $vv) { -- 2.39.5