Merge pull request #14819 from annando/redirected

Handle redirected servers in server detection.
This commit is contained in:
Hypolite Petovan 2025-02-15 19:56:37 -05:00 committed by GitHub
commit c746017cda
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 56 additions and 15 deletions

View file

@ -1,6 +1,6 @@
-- ------------------------------------------
-- Friendica 2025.02-dev (Interrupted Fern)
-- DB_UPDATE_VERSION 1577
-- DB_UPDATE_VERSION 1578
-- ------------------------------------------
@ -41,10 +41,12 @@ CREATE TABLE IF NOT EXISTS `gserver` (
`blocked` boolean COMMENT 'Server is blocked',
`failed` boolean COMMENT 'Connection failed',
`next_contact` datetime DEFAULT '0001-01-01 00:00:00' COMMENT 'Next connection request',
`redirect-gsid` int unsigned COMMENT 'Target Gserver id in case of a redirect',
PRIMARY KEY(`id`),
UNIQUE INDEX `nurl` (`nurl`(190)),
INDEX `next_contact` (`next_contact`),
INDEX `network` (`network`)
INDEX `network` (`network`),
FOREIGN KEY (`redirect-gsid`) REFERENCES `gserver` (`id`) ON UPDATE RESTRICT ON DELETE CASCADE
) DEFAULT COLLATE utf8mb4_general_ci COMMENT='Global servers';
--

View file

@ -41,6 +41,7 @@ Fields
| blocked | Server is blocked | boolean | YES | | NULL | |
| failed | Connection failed | boolean | YES | | NULL | |
| next_contact | Next connection request | datetime | YES | | 0001-01-01 00:00:00 | |
| redirect-gsid | Target Gserver id in case of a redirect | int unsigned | YES | | NULL | |
Indexes
------------
@ -52,5 +53,11 @@ Indexes
| next_contact | next_contact |
| network | network |
Foreign Keys
------------
| Field | Target Table | Target Field |
|-------|--------------|--------------|
| redirect-gsid | [gserver](help/database/db_gserver) | id |
Return to [database documentation](help/database)

View file

@ -650,7 +650,7 @@ class PostUpdate
DBA::update(
'contact',
['gsid' => GServer::getID($contact['baseurl'], true), 'baseurl' => GServer::cleanURL($contact['baseurl'])],
['gsid' => GServer::getRealID($contact['baseurl'], true), 'baseurl' => GServer::cleanURL($contact['baseurl'])],
['id' => $contact['id']]
);
@ -705,7 +705,7 @@ class PostUpdate
DBA::update(
'apcontact',
['gsid' => GServer::getID($apcontact['baseurl'], true), 'baseurl' => GServer::cleanURL($apcontact['baseurl'])],
['gsid' => GServer::getRealID($apcontact['baseurl'], true), 'baseurl' => GServer::cleanURL($apcontact['baseurl'])],
['url' => $apcontact['url']]
);
@ -1243,7 +1243,7 @@ class PostUpdate
DBA::update(
'contact',
['gsid' => GServer::getID($server, true), 'baseurl' => GServer::cleanURL($server)],
['gsid' => GServer::getRealID($server, true), 'baseurl' => GServer::cleanURL($server)],
['id' => $contact['id']]
);

View file

@ -426,7 +426,7 @@ class APContact
}
if (!empty($apcontact['baseurl']) && empty($fetched_contact['gsid'])) {
$apcontact['gsid'] = GServer::getID($apcontact['baseurl']);
$apcontact['gsid'] = GServer::getRealID($apcontact['baseurl']);
} elseif (!empty($fetched_contact['gsid'])) {
$apcontact['gsid'] = $fetched_contact['gsid'];
} else {

View file

@ -167,7 +167,7 @@ class Contact
public static function insert(array $fields, int $duplicate_mode = Database::INSERT_DEFAULT): int
{
if (!empty($fields['baseurl']) && empty($fields['gsid'])) {
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
$fields['gsid'] = GServer::getRealID($fields['baseurl'], true);
}
$fields['uri-id'] = ItemURI::getIdByURI($fields['url']);
@ -913,7 +913,7 @@ class Contact
$fields['unsearchable'] = !$profile['net-publish'];
$fields['manually-approve'] = in_array($user['page-flags'], [User::PAGE_FLAGS_NORMAL, User::PAGE_FLAGS_PRVGROUP, User::PAGE_FLAGS_COMM_MAN]);
$fields['baseurl'] = DI::baseUrl();
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
$fields['gsid'] = GServer::getRealID($fields['baseurl'], true);
$update = false;

View file

@ -131,6 +131,32 @@ class GServer
return self::getID($url, true);
}
/**
* Get the real ID for the given server URL, follows redirects.
*
* @param string $url
* @param boolean $no_check Don't check if the server hadn't been found
*
* @return int|null gserver id or NULL on empty URL or failed check
*/
public static function getRealID(string $url, bool $no_check = false): ?int
{
$gsid = self::getID($url, $no_check);
if (empty($gsid)) {
return $gsid;
}
$gserver = DBA::selectFirst('gserver', ['redirect-gsid'], ['id' => $gsid]);
if (!empty($gserver['redirect-gsid'])) {
$redirect = DBA::selectFirst('gserver', ['failed'], ['id' => $gserver['redirect-gsid']]);
if (isset($redirect['failed']) && !$redirect['failed']) {
return $gserver['redirect-gsid'];
}
}
return $gsid;
}
/**
* Retrieves all the servers which base domain are matching the provided domain pattern
*
@ -569,8 +595,13 @@ class GServer
(((parse_url($url, PHP_URL_HOST) != parse_url($valid_url, PHP_URL_HOST)) || (parse_url($url, PHP_URL_PATH) != parse_url($valid_url, PHP_URL_PATH))) && empty(parse_url($valid_url, PHP_URL_PATH)))) {
DI::logger()->debug('Found redirect. Mark old entry as failure', ['old' => $url, 'new' => $valid_url]);
self::setFailureByUrl($url);
if (!self::getID($valid_url, true) && !Network::isUrlBlocked($valid_url)) {
$target_id = self::getID($valid_url, true);
if (!$target_id && !Network::isUrlBlocked($valid_url)) {
self::detect($valid_url, $network, $only_nodeinfo);
$target_id = self::getID($valid_url, true);
}
if ($target_id) {
self::update(['redirect-gsid' => $target_id], ['nurl' => Strings::normaliseLink($url)]);
}
return false;
}

View file

@ -241,7 +241,7 @@ class User
$system['thumb'] = Contact::getDefaultAvatar($system, Proxy::SIZE_THUMB);
$system['micro'] = Contact::getDefaultAvatar($system, Proxy::SIZE_MICRO);
$system['nurl'] = Strings::normaliseLink($system['url']);
$system['gsid'] = GServer::getID($system['baseurl']);
$system['gsid'] = GServer::getRealID($system['baseurl']);
Contact::insert($system);
}

View file

@ -147,7 +147,7 @@ class Probe
$newdata['baseurl'] = $data['networks'][$network]['baseurl'];
}
if (!empty($newdata['baseurl'])) {
$newdata['gsid'] = $data['networks'][$network]['gsid'] = GServer::getID($newdata['baseurl']);
$newdata['gsid'] = $data['networks'][$network]['gsid'] = GServer::getRealID($newdata['baseurl']);
} else {
$newdata['gsid'] = $data['networks'][$network]['gsid'] = null;
}
@ -436,7 +436,7 @@ class Probe
}
if (!empty($data['baseurl']) && empty($data['gsid'])) {
$data['gsid'] = GServer::getID($data['baseurl']);
$data['gsid'] = GServer::getRealID($data['baseurl']);
}
// Ensure that local connections always are DFRN
@ -2164,7 +2164,7 @@ class Probe
$split_name = Diaspora::splitName($owner['name']);
if (empty($owner['gsid'])) {
$owner['gsid'] = GServer::getID($approfile['generator']['url']);
$owner['gsid'] = GServer::getRealID($approfile['generator']['url']);
}
$data = [

View file

@ -142,7 +142,7 @@ class Actor
if (!empty($fields['baseurl'])) {
GServer::check($fields['baseurl'], Protocol::BLUESKY);
$fields['gsid'] = GServer::getID($fields['baseurl'], true);
$fields['gsid'] = GServer::getRealID($fields['baseurl'], true);
}
foreach ($directory->verificationMethod as $method) {

View file

@ -44,7 +44,7 @@ use Friendica\Database\DBA;
// This file is required several times during the test in DbaDefinition which justifies this condition
if (!defined('DB_UPDATE_VERSION')) {
define('DB_UPDATE_VERSION', 1577);
define('DB_UPDATE_VERSION', 1578);
}
return [
@ -85,6 +85,7 @@ return [
"blocked" => ["type" => "boolean", "comment" => "Server is blocked"],
"failed" => ["type" => "boolean", "comment" => "Connection failed"],
"next_contact" => ["type" => "datetime", "default" => DBA::NULL_DATETIME, "comment" => "Next connection request"],
"redirect-gsid" => ["type" => "int unsigned", "foreign" => ["gserver" => "id"], "comment" => "Target Gserver id in case of a redirect"],
],
"indexes" => [
"PRIMARY" => ["id"],