aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/l10n/nl.js1
-rw-r--r--lib/l10n/nl.json1
-rw-r--r--lib/private/Files/FilenameValidator.php2
-rw-r--r--lib/private/Files/ObjectStore/S3ObjectTrait.php60
-rw-r--r--lib/public/Files/IFilenameValidator.php2
5 files changed, 47 insertions, 19 deletions
diff --git a/lib/l10n/nl.js b/lib/l10n/nl.js
index 7d9c078ad71..fec337c601d 100644
--- a/lib/l10n/nl.js
+++ b/lib/l10n/nl.js
@@ -75,6 +75,7 @@ OC.L10N.register(
"Empty file" : "Leeg bestand",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Module met ID: %s bestaat niet. Schakel die in binnen de app-instellingen of neem contact op met je beheerder.",
"Dot files are not allowed" : "Punt-bestanden zijn niet toegestaan",
+ "renamed file" : "bestand hernoemd",
"File already exists" : "Bestand bestaat al",
"Invalid path" : "Ongeldig pad",
"Failed to create file from template" : "Kon geen bestand van het sjabloon maken",
diff --git a/lib/l10n/nl.json b/lib/l10n/nl.json
index 0d11433dc52..75f2c23423e 100644
--- a/lib/l10n/nl.json
+++ b/lib/l10n/nl.json
@@ -73,6 +73,7 @@
"Empty file" : "Leeg bestand",
"Module with ID: %s does not exist. Please enable it in your apps settings or contact your administrator." : "Module met ID: %s bestaat niet. Schakel die in binnen de app-instellingen of neem contact op met je beheerder.",
"Dot files are not allowed" : "Punt-bestanden zijn niet toegestaan",
+ "renamed file" : "bestand hernoemd",
"File already exists" : "Bestand bestaat al",
"Invalid path" : "Ongeldig pad",
"Failed to create file from template" : "Kon geen bestand van het sjabloon maken",
diff --git a/lib/private/Files/FilenameValidator.php b/lib/private/Files/FilenameValidator.php
index 57a62b0b219..a78c6d3cc3c 100644
--- a/lib/private/Files/FilenameValidator.php
+++ b/lib/private/Files/FilenameValidator.php
@@ -232,7 +232,7 @@ class FilenameValidator implements IFilenameValidator {
$forbiddenCharacters = $this->getForbiddenCharacters();
if ($charReplacement === null) {
- $charReplacement = array_diff([' ', '_', '-'], $forbiddenCharacters);
+ $charReplacement = array_diff(['_', '-', ' '], $forbiddenCharacters);
$charReplacement = reset($charReplacement) ?: '';
}
if (mb_strlen($charReplacement) !== 1) {
diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php
index 61e8158b863..5e6dcf88a42 100644
--- a/lib/private/Files/ObjectStore/S3ObjectTrait.php
+++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php
@@ -119,28 +119,54 @@ trait S3ObjectTrait {
protected function writeMultiPart(string $urn, StreamInterface $stream, array $metaData): void {
$mimetype = $metaData['mimetype'] ?? null;
unset($metaData['mimetype']);
- $uploader = new MultipartUploader($this->getConnection(), $stream, [
- 'bucket' => $this->bucket,
- 'concurrency' => $this->concurrency,
- 'key' => $urn,
- 'part_size' => $this->uploadPartSize,
- 'params' => [
- 'ContentType' => $mimetype,
- 'Metadata' => $this->buildS3Metadata($metaData),
- 'StorageClass' => $this->storageClass,
- ] + $this->getSSECParameters(),
- ]);
- try {
- $uploader->upload();
- } catch (S3MultipartUploadException $e) {
+ $attempts = 0;
+ $uploaded = false;
+ $concurrency = $this->concurrency;
+ $exception = null;
+ $state = null;
+
+ // retry multipart upload once with concurrency at half on failure
+ while (!$uploaded && $attempts <= 1) {
+ $uploader = new MultipartUploader($this->getConnection(), $stream, [
+ 'bucket' => $this->bucket,
+ 'concurrency' => $concurrency,
+ 'key' => $urn,
+ 'part_size' => $this->uploadPartSize,
+ 'state' => $state,
+ 'params' => [
+ 'ContentType' => $mimetype,
+ 'Metadata' => $this->buildS3Metadata($metaData),
+ 'StorageClass' => $this->storageClass,
+ ] + $this->getSSECParameters(),
+ ]);
+
+ try {
+ $uploader->upload();
+ $uploaded = true;
+ } catch (S3MultipartUploadException $e) {
+ $exception = $e;
+ $attempts++;
+
+ if ($concurrency > 1) {
+ $concurrency = round($concurrency / 2);
+ }
+
+ if ($stream->isSeekable()) {
+ $stream->rewind();
+ }
+ }
+ }
+
+ if (!$uploaded) {
// if anything goes wrong with multipart, make sure that you don“t poison and
// slow down s3 bucket with orphaned fragments
- $uploadInfo = $e->getState()->getId();
- if ($e->getState()->isInitiated() && (array_key_exists('UploadId', $uploadInfo))) {
+ $uploadInfo = $exception->getState()->getId();
+ if ($exception->getState()->isInitiated() && (array_key_exists('UploadId', $uploadInfo))) {
$this->getConnection()->abortMultipartUpload($uploadInfo);
}
- throw new \OCA\DAV\Connector\Sabre\Exception\BadGateway('Error while uploading to S3 bucket', 0, $e);
+
+ throw new \OCA\DAV\Connector\Sabre\Exception\BadGateway('Error while uploading to S3 bucket', 0, $exception);
}
}
diff --git a/lib/public/Files/IFilenameValidator.php b/lib/public/Files/IFilenameValidator.php
index d8bd06d179d..9b7fa1e2e2e 100644
--- a/lib/public/Files/IFilenameValidator.php
+++ b/lib/public/Files/IFilenameValidator.php
@@ -43,7 +43,7 @@ interface IFilenameValidator {
* If no sanitizing is needed the same name is returned.
*
* @param string $name The filename to sanitize
- * @param null|string $charReplacement Character to use for replacing forbidden ones - by default space, dash or underscore is used if allowed.
+ * @param null|string $charReplacement Character to use for replacing forbidden ones - by default underscore, dash or space is used if allowed.
* @throws \InvalidArgumentException if no character replacement was given (and the default could not be applied) or the replacement is not valid.
* @since 32.0.0
*/