From df458c931df2d68d4ad9d3e387394b2ddc0f7d09 Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Wed, 20 May 2026 18:44:39 +0930 Subject: [PATCH 1/2] fix: support federation between systems in subdirectories testRemoteUrl was only checking for a responding ownCloud at the provided host. But if the server is installed in a subdirectory then the requests were not sent there. For example: - the cloud server is at http://mydomain.com/cloud - testRemoteUrl checked for a repsonse from http://mydomain.com/status.php Now it checks for a response from http://mydomain.com/cloud/status.php --- apps/files_sharing/lib/External/Manager.php | 8 ++++++ .../tests/External/ManagerTest.php | 25 ++++++++++++++++--- changelog/unreleased/41599 | 10 ++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 changelog/unreleased/41599 diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index 2e5c06200b48..ab796dd78029 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -573,20 +573,28 @@ protected function testUrl(IClientService $clientService, string $remote, bool $ public function testRemoteUrl(IClientService $clientService, string $remote) { $parsed_host = parse_url($remote, PHP_URL_HOST); $parsed_port = parse_url($remote, PHP_URL_PORT); + $parsed_path = parse_url($remote, PHP_URL_PATH); if (\is_string($parsed_host)) { $remote = $parsed_host; if ($parsed_port !== null) { $remote .= ':' . $parsed_port; } + if ($parsed_path !== null) { + $remote .= $parsed_path; + } } else { $string_to_parse = 'http://' . $remote; $parsed_host = parse_url($string_to_parse, PHP_URL_HOST); $parsed_port = parse_url($string_to_parse, PHP_URL_PORT); + $parsed_path = parse_url($string_to_parse, PHP_URL_PATH); if (\is_string($parsed_host)) { $remote = $parsed_host; if ($parsed_port !== null) { $remote .= ':' . $parsed_port; } + if ($parsed_path !== null) { + $remote .= $parsed_path; + } } } try { diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index 3e8f285aabfe..8db7be4373aa 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -434,7 +434,21 @@ public function testRemoveShare(): void { $this->assertArrayHasKey('user', $called[1]); } - public function testRemoteWithValidHttps(): void { + public function providesRemoteAddress() { + return [ + [ + 'owncloud.com', + ], + [ + 'owncloud.com/cloud', + ], + ]; + } + + /** + * @dataProvider providesRemoteAddress + */ + public function testRemoteWithValidHttps($remoteAddress): void { $client = $this->getMockBuilder(IClient::class) ->disableOriginalConstructor()->getMock(); $response = $this->getMockBuilder(IResponse::class) @@ -453,10 +467,13 @@ public function testRemoteWithValidHttps(): void { ->method('newClient') ->willReturn($client); - $this->assertEquals('https', $this->manager->testRemoteUrl($clientService, 'owncloud.com')); + $this->assertEquals('https', $this->manager->testRemoteUrl($clientService, $remoteAddress)); } - public function testRemoteWithWorkingHttp(): void { + /** + * @dataProvider providesRemoteAddress + */ + public function testRemoteWithWorkingHttp($remoteAddress): void { $client = $this->getMockBuilder(IClient::class) ->disableOriginalConstructor()->getMock(); $response = $this->getMockBuilder(IResponse::class) @@ -475,7 +492,7 @@ public function testRemoteWithWorkingHttp(): void { ->method('newClient') ->willReturn($client); - $this->assertEquals('http', $this->manager->testRemoteUrl($clientService, 'owncloud.com')); + $this->assertEquals('http', $this->manager->testRemoteUrl($clientService, $remoteAddress)); } public function testRemoteWithInvalidRemote(): void { diff --git a/changelog/unreleased/41599 b/changelog/unreleased/41599 new file mode 100644 index 000000000000..4bcbd5eb10a2 --- /dev/null +++ b/changelog/unreleased/41599 @@ -0,0 +1,10 @@ +Fix: support federation between systems in subdirectories + +If a federated server was installed in a subdirectory like: + +mydomain.com/cloud + +Then checks to see that the server is up and responding would fail. +This problem has been corrected. + +https://github.com/owncloud/core/pull/41599 From e66f9f0df8a0d0afb391fa95ba8865fd3217526d Mon Sep 17 00:00:00 2001 From: Phillip Davis Date: Mon, 8 Jun 2026 22:44:43 +0930 Subject: [PATCH 2/2] fix: handle case when subdirectory has a trailing slash --- apps/files_sharing/lib/External/Manager.php | 4 ++-- apps/files_sharing/tests/External/ManagerTest.php | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index ab796dd78029..321acfd0e1ad 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -580,7 +580,7 @@ public function testRemoteUrl(IClientService $clientService, string $remote) { $remote .= ':' . $parsed_port; } if ($parsed_path !== null) { - $remote .= $parsed_path; + $remote .= \rtrim($parsed_path, '/'); } } else { $string_to_parse = 'http://' . $remote; @@ -593,7 +593,7 @@ public function testRemoteUrl(IClientService $clientService, string $remote) { $remote .= ':' . $parsed_port; } if ($parsed_path !== null) { - $remote .= $parsed_path; + $remote .= \rtrim($parsed_path, '/'); } } } diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index 8db7be4373aa..02c52e16cfe8 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -442,6 +442,9 @@ public function providesRemoteAddress() { [ 'owncloud.com/cloud', ], + [ + 'owncloud.com/cloud/', + ], ]; }