diff --git a/lib/private/Http/Client/Client.php b/lib/private/Http/Client/Client.php index a50722d55416c..9b3b34b99d142 100644 --- a/lib/private/Http/Client/Client.php +++ b/lib/private/Http/Client/Client.php @@ -56,7 +56,10 @@ private function buildRequestOptions(array $options): array { $defaults = [ RequestOptions::VERIFY => $this->getCertBundle(), RequestOptions::TIMEOUT => IClient::DEFAULT_REQUEST_TIMEOUT, + // Prefer HTTP/2 globally (PSR-7 request version) + RequestOptions::VERSION => '2.0', ]; + $defaults['curl'][\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2TLS; $options['nextcloud']['allow_local_address'] = $this->isLocalAddressAllowed($options); if ($options['nextcloud']['allow_local_address'] === false) { @@ -87,8 +90,15 @@ private function buildRequestOptions(array $options): array { $options[RequestOptions::HEADERS]['User-Agent'] = $userAgent; } - if (!isset($options[RequestOptions::HEADERS]['Accept-Encoding'])) { - $options[RequestOptions::HEADERS]['Accept-Encoding'] = 'gzip'; + // Ensure headers array exists and set Accept-Encoding only if not present + $headers = $options[RequestOptions::HEADERS] ?? []; + if (!isset($headers['Accept-Encoding'])) { + $acceptEnc = 'gzip'; + if (function_exists('brotli_uncompress')) { + $acceptEnc = 'br, ' . $acceptEnc; + } + $options[RequestOptions::HEADERS] = $headers; // ensure headers are present + $options[RequestOptions::HEADERS]['Accept-Encoding'] = $acceptEnc; } // Fallback for save_to diff --git a/tests/lib/Http/Client/ClientTest.php b/tests/lib/Http/Client/ClientTest.php index dd0e1b7b82217..c4d1ecc4da944 100644 --- a/tests/lib/Http/Client/ClientTest.php +++ b/tests/lib/Http/Client/ClientTest.php @@ -284,6 +284,7 @@ private function setUpDefaultRequestOptions(): void { $this->serverVersion->method('getVersionString') ->willReturn('123.45.6'); + $acceptEnc = function_exists('brotli_uncompress') ? 'br, gzip' : 'gzip'; $this->defaultRequestOptions = [ 'verify' => '/my/path.crt', 'proxy' => [ @@ -291,13 +292,19 @@ private function setUpDefaultRequestOptions(): void { 'https' => 'foo' ], 'headers' => [ + 'User-Agent' => 'Nextcloud-Server-Crawler/123.45.6', - 'Accept-Encoding' => 'gzip', + 'Accept-Encoding' => $acceptEnc, + ], 'timeout' => 30, 'nextcloud' => [ 'allow_local_address' => true, ], + 'version' => '2.0', + 'curl' => [ + \CURLOPT_HTTP_VERSION => \CURL_HTTP_VERSION_2TLS, + ], ]; } @@ -481,11 +488,13 @@ public function testSetDefaultOptionsWithNotInstalled(): void { $this->serverVersion->method('getVersionString') ->willReturn('123.45.6'); + $acceptEnc = function_exists('brotli_uncompress') ? 'br, gzip' : 'gzip'; + $this->assertEquals([ 'verify' => \OC::$SERVERROOT . '/resources/config/ca-bundle.crt', 'headers' => [ 'User-Agent' => 'Nextcloud-Server-Crawler/123.45.6', - 'Accept-Encoding' => 'gzip', + 'Accept-Encoding' => $acceptEnc, ], 'timeout' => 30, 'nextcloud' => [ @@ -499,6 +508,10 @@ public function testSetDefaultOptionsWithNotInstalled(): void { ): void { }, ], + 'version' => '2.0', + 'curl' => [ + \CURLOPT_HTTP_VERSION => \CURL_HTTP_VERSION_2TLS, + ], ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); } @@ -531,6 +544,8 @@ public function testSetDefaultOptionsWithProxy(): void { $this->serverVersion->method('getVersionString') ->willReturn('123.45.6'); + $acceptEnc = function_exists('brotli_uncompress') ? 'br, gzip' : 'gzip'; + $this->assertEquals([ 'verify' => '/my/path.crt', 'proxy' => [ @@ -539,7 +554,7 @@ public function testSetDefaultOptionsWithProxy(): void { ], 'headers' => [ 'User-Agent' => 'Nextcloud-Server-Crawler/123.45.6', - 'Accept-Encoding' => 'gzip', + 'Accept-Encoding' => $acceptEnc, ], 'timeout' => 30, 'nextcloud' => [ @@ -553,6 +568,10 @@ public function testSetDefaultOptionsWithProxy(): void { ): void { }, ], + 'version' => '2.0', + 'curl' => [ + \CURLOPT_HTTP_VERSION => \CURL_HTTP_VERSION_2TLS, + ], ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); } @@ -585,6 +604,8 @@ public function testSetDefaultOptionsWithProxyAndExclude(): void { $this->serverVersion->method('getVersionString') ->willReturn('123.45.6'); + $acceptEnc = function_exists('brotli_uncompress') ? 'br, gzip' : 'gzip'; + $this->assertEquals([ 'verify' => '/my/path.crt', 'proxy' => [ @@ -594,7 +615,7 @@ public function testSetDefaultOptionsWithProxyAndExclude(): void { ], 'headers' => [ 'User-Agent' => 'Nextcloud-Server-Crawler/123.45.6', - 'Accept-Encoding' => 'gzip', + 'Accept-Encoding' => $acceptEnc, ], 'timeout' => 30, 'nextcloud' => [ @@ -608,6 +629,10 @@ public function testSetDefaultOptionsWithProxyAndExclude(): void { ): void { }, ], + 'version' => '2.0', + 'curl' => [ + \CURLOPT_HTTP_VERSION => \CURL_HTTP_VERSION_2TLS, + ], ], self::invokePrivate($this->client, 'buildRequestOptions', [[]])); } }