diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index 35a9b8a802dff..56392b7529f51 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -559,9 +559,10 @@ public function free_space(string $path): int|float|false { } private function getDefaultRequestOptions(): array { + $timeout = $this->config->getSystemValueInt('sharing.federation.request_timeout', 10); $options = [ - 'timeout' => 10, - 'connect_timeout' => 10, + 'timeout' => $timeout, + 'connect_timeout' => $timeout, ]; if ($this->config->getSystemValueBool('sharing.federation.allowSelfSignedCertificates')) { $options['verify'] = false; diff --git a/apps/files_sharing/tests/ExternalStorageTest.php b/apps/files_sharing/tests/ExternalStorageTest.php index 660fae06fe764..a9723ef9cf2bd 100644 --- a/apps/files_sharing/tests/ExternalStorageTest.php +++ b/apps/files_sharing/tests/ExternalStorageTest.php @@ -15,6 +15,7 @@ use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; use OCP\ICertificateManager; +use OCP\IConfig; use OCP\IUser; use OCP\OCM\IOCMDiscoveryService; use OCP\OCM\IOCMProvider; @@ -116,6 +117,75 @@ public function testIfTestReturnsTheValue(): void { $result = $storage->test(); $this->assertSame(true, $result); } + + public static function requestTimeoutProvider(): array { + return [ + 'default' => [null, 10], + 'configured' => [25, 25], + ]; + } + + #[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'requestTimeoutProvider')] + public function testGetShareInfoUsesConfiguredRequestTimeout(?int $configured, int $expected): void { + if ($configured !== null) { + $realConfig = Server::get(IConfig::class); + $config = $this->createMock(IConfig::class); + $config->method('getSystemValueInt') + ->willReturnCallback(fn (string $key, int $default = 0): int => $key === 'sharing.federation.request_timeout' + ? $configured + : $realConfig->getSystemValueInt($key, $default)); + $config->method('getSystemValueBool') + ->willReturnCallback(fn (string $key, bool $default = false): bool => $realConfig->getSystemValueBool($key, $default)); + $config->method('getSystemValue') + ->willReturnCallback(fn (string $key, mixed $default = ''): mixed => $realConfig->getSystemValue($key, $default)); + $this->overwriteService(IConfig::class, $config); + } + + $response = $this->createMock(IResponse::class); + $response->method('getBody') + ->willReturn('{"id":1}'); + $client = $this->createMock(IClient::class); + $client->expects($this->once()) + ->method('post') + ->with( + 'https://remoteserver/index.php/apps/files_sharing/shareinfo?t=abcdef', + $this->callback(function (array $options) use ($expected): bool { + $this->assertSame($expected, $options['timeout']); + $this->assertSame($expected, $options['connect_timeout']); + return true; + }), + ) + ->willReturn($response); + $clientService = $this->createMock(IClientService::class); + $clientService->method('newClient') + ->willReturn($client); + $this->overwriteService(IClientService::class, $clientService); + + $uri = 'https://remoteserver'; + $discoveryService = $this->createMock(IOCMDiscoveryService::class); + $discoveryService->method('discover') + ->willReturn($this->createMock(IOCMProvider::class)); + $storage = $this->getMockBuilder(Storage::class) + ->setConstructorArgs([[ + 'cloudId' => new CloudId('testOwner@' . $uri, 'testOwner', $uri), + 'remote' => $uri, + 'owner' => 'testOwner', + 'mountpoint' => 'remoteshare', + 'token' => 'abcdef', + 'password' => '', + 'manager' => $this->createMock(ExternalShareManager::class), + 'certificateManager' => Server::get(ICertificateManager::class), + 'HttpClientService' => $clientService, + 'discoveryService' => $discoveryService, + 'recipient' => $this->createMock(IUser::class), + ]]) + ->onlyMethods(['remoteIsOwnCloud']) + ->getMock(); + $storage->method('remoteIsOwnCloud') + ->willReturn(true); + + $this->assertSame(['id' => 1], $storage->getShareInfo()); + } } /** diff --git a/config/config.sample.php b/config/config.sample.php index 75aafed608686..6ea2d48e79657 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -2308,6 +2308,16 @@ */ 'sharing.federation.allowSelfSignedCertificates' => false, + /** + * The timeout in seconds for requests made to remote servers when accessing + * federated shares, e.g. fetching the share info or checking whether the + * remote server is reachable. Increase it if big federated shares take longer + * to answer than the default. + * + * Defaults to ``10`` seconds. + */ + 'sharing.federation.request_timeout' => 10, + /** * Override the ``apiVersion`` advertised in the local OCM discovery document. * Setting this to a non-empty string also removes the non-standard ``version``