Skip to content

Commit

Permalink
feat(files): Expose chunked upload config via capabilities
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <[email protected]>
  • Loading branch information
provokateurin committed Oct 21, 2024
1 parent 4d8d11d commit 51e971b
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 4 deletions.
8 changes: 7 additions & 1 deletion apps/files/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<name>Files</name>
<summary>File Management</summary>
<description>File Management</description>
<version>2.3.0</version>
<version>2.3.1</version>
<licence>agpl</licence>
<author>John Molakvoæ</author>
<author>Robin Appelman</author>
Expand All @@ -35,6 +35,12 @@
<job>OCA\Files\BackgroundJob\DeleteExpiredOpenLocalEditor</job>
</background-jobs>

<repair-steps>
<post-migration>
<step>OCA\Files\Migration\ChunkedUploadConfigRepairStep</step>
</post-migration>
</repair-steps>

<commands>
<command>OCA\Files\Command\Scan</command>
<command>OCA\Files\Command\DeleteOrphanedFiles</command>
Expand Down
2 changes: 2 additions & 0 deletions apps/files/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@
'OCA\\Files\\Listener\\LoadSidebarListener' => $baseDir . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files\\Listener\\RenderReferenceEventListener' => $baseDir . '/../lib/Listener/RenderReferenceEventListener.php',
'OCA\\Files\\Listener\\SyncLivePhotosListener' => $baseDir . '/../lib/Listener/SyncLivePhotosListener.php',
'OCA\\Files\\Migration\\ChunkedUploadConfigRepairStep' => $baseDir . '/../lib/Migration/ChunkedUploadConfigRepairStep.php',
'OCA\\Files\\Migration\\Version11301Date20191205150729' => $baseDir . '/../lib/Migration/Version11301Date20191205150729.php',
'OCA\\Files\\Migration\\Version12101Date20221011153334' => $baseDir . '/../lib/Migration/Version12101Date20221011153334.php',
'OCA\\Files\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
'OCA\\Files\\ResponseDefinitions' => $baseDir . '/../lib/ResponseDefinitions.php',
'OCA\\Files\\Search\\FilesSearchProvider' => $baseDir . '/../lib/Search/FilesSearchProvider.php',
'OCA\\Files\\Service\\ChunkedUploadConfig' => $baseDir . '/../lib/Service/ChunkedUploadConfig.php',
'OCA\\Files\\Service\\DirectEditingService' => $baseDir . '/../lib/Service/DirectEditingService.php',
'OCA\\Files\\Service\\LivePhotosService' => $baseDir . '/../lib/Service/LivePhotosService.php',
'OCA\\Files\\Service\\OwnershipTransferService' => $baseDir . '/../lib/Service/OwnershipTransferService.php',
Expand Down
2 changes: 2 additions & 0 deletions apps/files/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,13 @@ class ComposerStaticInitFiles
'OCA\\Files\\Listener\\LoadSidebarListener' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarListener.php',
'OCA\\Files\\Listener\\RenderReferenceEventListener' => __DIR__ . '/..' . '/../lib/Listener/RenderReferenceEventListener.php',
'OCA\\Files\\Listener\\SyncLivePhotosListener' => __DIR__ . '/..' . '/../lib/Listener/SyncLivePhotosListener.php',
'OCA\\Files\\Migration\\ChunkedUploadConfigRepairStep' => __DIR__ . '/..' . '/../lib/Migration/ChunkedUploadConfigRepairStep.php',
'OCA\\Files\\Migration\\Version11301Date20191205150729' => __DIR__ . '/..' . '/../lib/Migration/Version11301Date20191205150729.php',
'OCA\\Files\\Migration\\Version12101Date20221011153334' => __DIR__ . '/..' . '/../lib/Migration/Version12101Date20221011153334.php',
'OCA\\Files\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
'OCA\\Files\\ResponseDefinitions' => __DIR__ . '/..' . '/../lib/ResponseDefinitions.php',
'OCA\\Files\\Search\\FilesSearchProvider' => __DIR__ . '/..' . '/../lib/Search/FilesSearchProvider.php',
'OCA\\Files\\Service\\ChunkedUploadConfig' => __DIR__ . '/..' . '/../lib/Service/ChunkedUploadConfig.php',
'OCA\\Files\\Service\\DirectEditingService' => __DIR__ . '/..' . '/../lib/Service/DirectEditingService.php',
'OCA\\Files\\Service\\LivePhotosService' => __DIR__ . '/..' . '/../lib/Service/LivePhotosService.php',
'OCA\\Files\\Service\\OwnershipTransferService' => __DIR__ . '/..' . '/../lib/Service/OwnershipTransferService.php',
Expand Down
4 changes: 2 additions & 2 deletions apps/files/lib/App.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Files;

use OC\NavigationManager;
use OCA\Files\Service\ChunkedUploadConfig;
use OCP\App\IAppManager;
use OCP\IConfig;
use OCP\IGroupManager;
Expand Down Expand Up @@ -44,9 +45,8 @@ public static function getNavigationManager(): INavigationManager {
public static function extendJsConfig($settings): void {
$appConfig = json_decode($settings['array']['oc_appconfig'], true);

$maxChunkSize = (int)Server::get(IConfig::class)->getAppValue('files', 'max_chunk_size', (string)(100 * 1024 * 1024));
$appConfig['files'] = [
'max_chunk_size' => $maxChunkSize
'max_chunk_size' => ChunkedUploadConfig::getMaxChunkSize(),
];

$settings['array']['oc_appconfig'] = json_encode($appConfig);
Expand Down
7 changes: 6 additions & 1 deletion apps/files/lib/Capabilities.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
namespace OCA\Files;

use OC\Files\FilenameValidator;
use OCA\Files\Service\ChunkedUploadConfig;
use OCP\Capabilities\ICapability;

class Capabilities implements ICapability {
Expand All @@ -20,7 +21,7 @@ public function __construct(
/**
* Return this classes capabilities
*
* @return array{files: array{'$comment': ?string, bigfilechunking: bool, blacklisted_files: array<mixed>, forbidden_filenames: list<string>, forbidden_filename_basenames: list<string>, forbidden_filename_characters: list<string>, forbidden_filename_extensions: list<string>}}
* @return array{files: array{'$comment': ?string, bigfilechunking: bool, blacklisted_files: array<mixed>, forbidden_filenames: list<string>, forbidden_filename_basenames: list<string>, forbidden_filename_characters: list<string>, forbidden_filename_extensions: list<string>, chunked_upload: array{max_size: int, max_parallel_count: int}}}
*/
public function getCapabilities(): array {
return [
Expand All @@ -33,6 +34,10 @@ public function getCapabilities(): array {
'forbidden_filename_extensions' => $this->filenameValidator->getForbiddenExtensions(),

'bigfilechunking' => true,
'chunked_upload' => [
'max_size' => ChunkedUploadConfig::getMaxChunkSize(),
'max_parallel_count' => ChunkedUploadConfig::getMaxParallelCount(),
],
],
];
}
Expand Down
26 changes: 26 additions & 0 deletions apps/files/lib/Migration/ChunkedUploadConfigRepairStep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace OCA\Files\Migration;

use OCA\Files\Service\ChunkedUploadConfig;
use OCP\IConfig;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use OCP\Server;

class ChunkedUploadConfigRepairStep implements IRepairStep {
public function getName() {
return 'Migrate chunked upload config';
}

public function run(IOutput $output) {
$maxChunkSize = Server::get(IConfig::class)->getAppValue('files', 'max_chunk_size');
if ($maxChunkSize === '') {
// Skip if no value was configured before
return;
}

ChunkedUploadConfig::setMaxChunkSize((int)$maxChunkSize);
Server::get(IConfig::class)->deleteAppValue('files', 'max_chunk_size');
}
}
30 changes: 30 additions & 0 deletions apps/files/lib/Service/ChunkedUploadConfig.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

namespace OCA\Files\Service;

use OCP\IConfig;
use OCP\Server;

class ChunkedUploadConfig {
private const KEY_MAX_SIZE = 'files.chunked_upload.max_size';
private const KEY_MAX_PARALLEL_COUNT = 'files.chunked_upload.max_parallel_count';

public static function getMaxChunkSize(): int {
return Server::get(IConfig::class)->getSystemValueInt(self::KEY_MAX_SIZE, 100 * 1024 * 1024);
}

public static function setMaxChunkSize(int $maxChunkSize): void {
Server::get(IConfig::class)->setSystemValue(self::KEY_MAX_SIZE, $maxChunkSize);
}

public static function getMaxParallelCount(): int {
return Server::get(IConfig::class)->getSystemValueInt(self::KEY_MAX_PARALLEL_COUNT, 5);
}
}
18 changes: 18 additions & 0 deletions apps/files/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"forbidden_filename_basenames",
"forbidden_filename_characters",
"forbidden_filename_extensions",
"chunked_upload",
"directEditing"
],
"properties": {
Expand Down Expand Up @@ -76,6 +77,23 @@
"type": "string"
}
},
"chunked_upload": {
"type": "object",
"required": [
"max_size",
"max_parallel_count"
],
"properties": {
"max_size": {
"type": "integer",
"format": "int64"
},
"max_parallel_count": {
"type": "integer",
"format": "int64"
}
}
},
"directEditing": {
"type": "object",
"required": [
Expand Down
18 changes: 18 additions & 0 deletions config/config.sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -2556,4 +2556,22 @@
'/bin',
'/opt/bin',
],

/**
* The maximum chunk size to use for chunked uploads.
* A bigger chunk size results in higher throughput, but above 100 MiB there are only diminishing returns,
* while services like Cloudflare already limit to 100 MiB.
*
* Defaults to 100 MiB.
*/
'files.chunked_upload.max_size' => 100 * 1024 * 1024,

/**
* The maximum number of chunks uploaded in parallel during chunked uploads.
* A bigger count results in higher throughput, but will also consume more server workers,
* while the improvements diminish.
*
* Defaults to 5.
*/
'files.chunked_upload.max_parallel_count' => 5,
];

0 comments on commit 51e971b

Please sign in to comment.