From 4474fdd4f91ed7c5c24367485eafc5042b4a16d4 Mon Sep 17 00:00:00 2001 From: Mario Date: Wed, 4 Mar 2026 08:34:45 +0000 Subject: [PATCH] introduce parse_webbie() with basic tests --- include/network.php | 60 +++++++++++++++++++---------- tests/unit/includes/NetworkTest.php | 24 ++++++++++++ 2 files changed, 63 insertions(+), 21 deletions(-) diff --git a/include/network.php b/include/network.php index 41edd84da..823b751b6 100644 --- a/include/network.php +++ b/include/network.php @@ -1232,39 +1232,57 @@ function discover_by_webbie($webbie, $protocol = '') { * @return boolean|string false or associative array from result JSON */ function webfinger_rfc7033($webbie, $zot = false) { + $parsed = parse_webbie($webbie); - if(filter_var($webbie, FILTER_VALIDATE_EMAIL)) { - $lhs = substr($webbie,0,strpos($webbie,'@')); - $rhs = substr($webbie,strpos($webbie,'@')+1); - $resource = urlencode('acct:' . $webbie); - } - elseif(filter_var($webbie, FILTER_VALIDATE_URL)) { - $m = parse_url($webbie); - if($m) { - if($m['scheme'] !== 'https') - return false; - - $rhs = $m['host'] . (array_key_exists('port', $m) ? ':' . $m['port'] : ''); - $resource = urlencode($webbie); - } - } - else + if (!$parsed) { return false; + } - logger('fetching url from resource: ' . $rhs . ':' . $webbie); + logger('fetching url from resource: ' . $parsed['host'] . ':' . $parsed['resource']); - $counter = 0; - $s = z_fetch_url('https://' . $rhs . '/.well-known/webfinger?f=&resource=' . $resource . (($zot) ? '&zot=1' : ''), - false, $counter, [ 'headers' => [ 'Accept: application/jrd+json, application/json, */*' ] ]); + $s = z_fetch_url('https://' . $parsed['host'] . '/.well-known/webfinger?f=&resource=' . $parsed['resource'] . (($zot) ? '&zot=1' : ''), + false, 0, [ 'headers' => [ 'Accept: application/jrd+json, application/json, */*' ] ]); if($s['success']) { $j = json_decode($s['body'], true); - return($j); + return $j; } return false; } +function parse_webbie($webbie) { + $parsed = parse_url($webbie); + + if (!$parsed) { + return false; + } + + if (!isset($parsed['scheme'])) { + $parsed['scheme'] = 'acct'; + } + + if (in_array($parsed['scheme'], ['http', 'https'])) { + $result['host'] = $parsed['host'] . ((isset($parsed['port'])) ? ':' . $parsed['port'] : ''); + $result['resource'] = urlencode($webbie); + } + elseif ($parsed['scheme'] === 'acct') { + $parts = explode('@', $parsed['path']); + $result['host'] = $parts[1]; + $result['resource'] = urlencode('acct:' . $parts[0] . '@' . $parts[1]); + } + else { + return false; + } + + if (isset($result['host'], $result['resource'])) { + return $result; + } + + return false; +} + + function old_webfinger($webbie) { $host = ''; diff --git a/tests/unit/includes/NetworkTest.php b/tests/unit/includes/NetworkTest.php index 0d99fc9c3..668bc7b22 100644 --- a/tests/unit/includes/NetworkTest.php +++ b/tests/unit/includes/NetworkTest.php @@ -119,4 +119,28 @@ class NetworkTest extends Zotlabs\Tests\Unit\UnitTestCase { { $this->assertEquals('', unparse_url([])); } + + + /** + * Test that the parse_webbie function. + * + * @dataProvider parse_webbie_provider + */ + public function test_parse_webbie(string $webbie, array $expected) : void { + $this->assertEquals($expected, parse_webbie($webbie)); + } + + public static function parse_webbie_provider() : array { + return [ + // test valid webfinger address + ['test@example.net', ['host' => 'example.net', 'resource' => 'acct:test@example.net']], + + // test valid webfinger address with scheme + ['acct:test@example.net', ['host' => 'example.net', 'resource' => 'acct:test@example.net']], + + // test URL + ['https://example.net/channel/test', ['host' => 'example.net', 'resource' => 'https://example.net/channel/test']], + ]; + } + }