From: Hypolite Petovan <hypolite@mrpetovan.com>
Date: Wed, 4 Jan 2023 16:39:22 +0000 (-0500)
Subject: Drop UpdateGServer worker task if domain is blocked
X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=ee8e70e20e572c97696786d7234234745918873b;p=friendica.git

Drop UpdateGServer worker task if domain is blocked

# Conflicts:
#	src/Model/GServer.php
---

diff --git a/src/Model/GServer.php b/src/Model/GServer.php
index 14fe2011b3..10c1a25e5d 100644
--- a/src/Model/GServer.php
+++ b/src/Model/GServer.php
@@ -44,6 +44,7 @@ use Friendica\Util\Network;
 use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use Friendica\Network\HTTPException;
+use Friendica\Worker\UpdateGServer;
 use GuzzleHttp\Psr7\Uri;
 use Psr\Http\Message\UriInterface;
 
@@ -100,11 +101,11 @@ class GServer
 	 */
 	public static function add(string $url, bool $only_nodeinfo = false)
 	{
-		if (self::getID($url, false)) {
+		if (self::getID($url)) {
 			return;
 		}
 
-		Worker::add(Worker::PRIORITY_LOW, 'UpdateGServer', $url, $only_nodeinfo);
+		UpdateGServer::add(Worker::PRIORITY_LOW, $url, $only_nodeinfo);
 	}
 
 	/**
@@ -165,6 +166,60 @@ class GServer
 		return DI::dba()->toArray($stmt);
 	}
 
+	/**
+	 * Checks if the given server array is unreachable for a long time now
+	 *
+	 * @param integer $gsid
+	 * @return boolean
+	 */
+	private static function isDefunct(array $gserver): bool
+	{
+		return ($gserver['failed'] || in_array($gserver['network'], Protocol::FEDERATED)) &&
+			($gserver['last_contact'] >= $gserver['created']) &&
+			($gserver['last_contact'] < $gserver['last_failure']) &&
+			($gserver['last_contact'] < DateTimeFormat::utc('now - 90 days'));
+	}
+
+	/**
+	 * Checks if the given server id is unreachable for a long time now
+	 *
+	 * @param integer $gsid
+	 * @return boolean
+	 */
+	public static function isDefunctById(int $gsid): bool
+	{
+		$gserver = DBA::selectFirst('gserver', ['url', 'next_contact', 'last_contact', 'last_failure', 'created', 'failed', 'network'], ['id' => $gsid]);
+		if (empty($gserver)) {
+			return false;
+		} else {
+			if (strtotime($gserver['next_contact']) < time()) {
+				UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['url']);
+			}
+
+			return self::isDefunct($gserver);
+		}
+	}
+
+	/**
+	 * Checks if the given server id is reachable
+	 *
+	 * @param integer $gsid
+	 * @return boolean
+	 */
+	public static function isReachableById(int $gsid): bool
+	{
+		$gserver = DBA::selectFirst('gserver', ['url', 'next_contact', 'failed', 'network'], ['id' => $gsid]);
+		if (empty($gserver)) {
+			return true;
+		} else {
+			if (strtotime($gserver['next_contact']) < time()) {
+				UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['url']);
+			}
+
+			return !$gserver['failed'] && in_array($gserver['network'], Protocol::FEDERATED);
+		}
+	}
+
 	/**
 	 * Checks if the given server is reachable
 	 *
@@ -201,7 +256,7 @@ class GServer
 		}
 
 		if (!empty($server) && (empty($gserver) || strtotime($gserver['next_contact']) < time())) {
-			Worker::add(Worker::PRIORITY_LOW, 'UpdateGServer', $server, false);
+			UpdateGServer::add(Worker::PRIORITY_LOW, $server);
 		}
 
 		return $reachable;
@@ -306,6 +361,47 @@ class GServer
 		return self::detect($server_url, $network, $only_nodeinfo);
 	}
 
+	/**
+	 * Reset failed server status by gserver id
+	 *
+	 * @param int    $gsid
+	 * @param string $network
+	 */
+	public static function setReachableById(int $gsid, string $network)
+	{
+		$gserver = DBA::selectFirst('gserver', ['url', 'failed', 'next_contact', 'network'], ['id' => $gsid]);
+		if (DBA::isResult($gserver) && $gserver['failed']) {
+			$fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow()];
+			if (!empty($network) && !in_array($gserver['network'], Protocol::FEDERATED)) {
+				$fields['network'] = $network;
+			}
+			self::update($fields, ['id' => $gsid]);
+			Logger::info('Reset failed status for server', ['url' => $gserver['url']]);
+
+			if (strtotime($gserver['next_contact']) < time()) {
+				UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['url']);
+			}
+		}
+	}
+
+	/**
+	 * Set failed server status by gserver id
+	 *
+	 * @param int $gsid
+	 */
+	public static function setFailureById(int $gsid)
+	{
+		$gserver = DBA::selectFirst('gserver', ['url', 'failed', 'next_contact'], ['id' => $gsid]);
+		if (DBA::isResult($gserver) && !$gserver['failed']) {
+			self::update(['failed' => true, 'last_failure' => DateTimeFormat::utcNow()], ['id' => $gsid]);
+			Logger::info('Set failed status for server', ['url' => $gserver['url']]);
+
+			if (strtotime($gserver['next_contact']) < time()) {
+				UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['url']);
+			}
+		}
+	}
+
 	/**
 	 * Set failed server status
 	 *
diff --git a/src/Worker/UpdateGServer.php b/src/Worker/UpdateGServer.php
index d180f34c45..a17fca81c4 100644
--- a/src/Worker/UpdateGServer.php
+++ b/src/Worker/UpdateGServer.php
@@ -22,9 +22,14 @@
 namespace Friendica\Worker;
 
 use Friendica\Core\Logger;
+use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\GServer;
+use Friendica\Network\HTTPException\InternalServerErrorException;
+use Friendica\Util\Network;
 use Friendica\Util\Strings;
+use GuzzleHttp\Psr7\Uri;
+use Psr\Http\Message\UriInterface;
 
 class UpdateGServer
 {
@@ -34,8 +39,9 @@ class UpdateGServer
 	 * @param string  $server_url    Server URL
 	 * @param boolean $only_nodeinfo Only use nodeinfo for server detection
 	 * @return void
+	 * @throws \Exception
 	 */
-	public static function execute(string $server_url, bool $only_nodeinfo = false)
+	public static function execute(string $server_url, bool $only_nodeinfo)
 	{
 		if (empty($server_url)) {
 			return;
@@ -47,6 +53,11 @@ class UpdateGServer
 			return;
 		}
 
+		// Silently dropping the worker task if the server domain is blocked
+		if (Network::isUrlBlocked($filtered)) {
+			return;
+		}
+
 		if (($filtered != $server_url) && DBA::exists('gserver', ['nurl' => Strings::normaliseLink($server_url)])) {
 			GServer::setFailure($server_url);
 			return;
@@ -61,4 +72,23 @@ class UpdateGServer
 		$ret = GServer::check($filtered, '', true, $only_nodeinfo);
 		Logger::info('Updated gserver', ['url' => $filtered, 'result' => $ret]);
 	}
+
+	/**
+	 * @param array|int $run_parameters Priority constant or array of options described in Worker::add
+	 * @param string    $serverUrl
+	 * @param bool      $onlyNodeInfo   Only use NodeInfo for server detection
+	 * @return int
+	 * @throws InternalServerErrorException
+	 */
+	public static function add($run_parameters, string $serverUrl, bool $onlyNodeInfo = false): int
+	{
+		// Dropping the worker task if the server domain is blocked
+		if (Network::isUrlBlocked($serverUrl)) {
+			return 0;
+		}
+
+		// We have to convert the Uri back to string because worker parameters are saved in JSON format which
+		// doesn't allow for structured objects.
+		return Worker::add($run_parameters, 'UpdateGServer', $serverUrl, $onlyNodeInfo);
+	}
 }
diff --git a/src/Worker/UpdateGServers.php b/src/Worker/UpdateGServers.php
index 25a2db16e0..fca3bccb7a 100644
--- a/src/Worker/UpdateGServers.php
+++ b/src/Worker/UpdateGServers.php
@@ -27,6 +27,7 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
+use GuzzleHttp\Psr7\Uri;
 
 class UpdateGServers
 {
@@ -63,12 +64,12 @@ class UpdateGServers
 			// There are duplicated "url" but not "nurl". So we check both addresses instead of just overwriting them,
 			// since that would mean loosing data.
 			if (!empty($gserver['url'])) {
-				if (Worker::add(Worker::PRIORITY_LOW, 'UpdateGServer', $gserver['url'])) {
+				if (UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['url'])) {
 					$count++;
 				}
 			}
 			if (!empty($gserver['nurl']) && ($gserver['nurl'] != Strings::normaliseLink($gserver['url']))) {
-				if (Worker::add(Worker::PRIORITY_LOW, 'UpdateGServer', $gserver['nurl'])) {
+				if (UpdateGServer::add(Worker::PRIORITY_LOW, $gserver['nurl'])) {
 					$count++;
 				}
 			}