aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Updater/ReleaseMetadata.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Updater/ReleaseMetadata.php')
-rw-r--r--lib/private/Updater/ReleaseMetadata.php79
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/private/Updater/ReleaseMetadata.php b/lib/private/Updater/ReleaseMetadata.php
new file mode 100644
index 00000000000..665847037e7
--- /dev/null
+++ b/lib/private/Updater/ReleaseMetadata.php
@@ -0,0 +1,79 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OC\Updater;
+
+use Exception;
+use JsonException;
+use OC\Updater\Exceptions\ReleaseMetadataException;
+use OCP\Http\Client\IClientService;
+
+/** retrieve releases metadata from official servers
+ *
+ * @since 30.0.0
+ */
+class ReleaseMetadata {
+ public function __construct(
+ private readonly IClientService $clientService,
+ ) {
+ }
+
+ /**
+ * returns metadata based on release version
+ *
+ * - version is a stable release, metadata is downloaded from official releases folder
+ * - version is not a table release, metadata is downloaded from official prereleases folder
+ * - version is a major version (30, 31, 32, ...), latest metadata are downloaded
+ *
+ * @param string $version
+ *
+ * @return array
+ * @throws ReleaseMetadataException
+ * @since 30.0.0
+ */
+ public function getMetadata(string $version): array {
+ if (!str_contains($version, '.')) {
+ $url = 'https://download.nextcloud.com/server/releases/latest-' . $version . '.metadata';
+ } else {
+ [,,$minor] = explode('.', $version);
+ if (ctype_digit($minor)) {
+ $url = 'https://download.nextcloud.com/server/releases/nextcloud-' . $version . '.metadata';
+ } else {
+ $url = 'https://download.nextcloud.com/server/prereleases/nextcloud-' . $version . '.metadata';
+ }
+ }
+ return $this->downloadMetadata($url);
+ }
+
+ /**
+ * download Metadata from a link
+ *
+ * @param string $url
+ *
+ * @return array
+ * @throws ReleaseMetadataException
+ * @since 30.0.0
+ */
+ public function downloadMetadata(string $url): array {
+ $client = $this->clientService->newClient();
+ try {
+ $response = $client->get($url, [
+ 'timeout' => 10,
+ 'connect_timeout' => 10
+ ]);
+ } catch (Exception $e) {
+ throw new ReleaseMetadataException('could not reach metadata at ' . $url, previous: $e);
+ }
+
+ try {
+ return json_decode($response->getBody(), true, flags: JSON_THROW_ON_ERROR);
+ } catch (JsonException) {
+ throw new ReleaseMetadataException('remote document is not valid');
+ }
+ }
+}