Skip to content

Commit

Permalink
Merge pull request #14210 from nextcloud/fix/14192/fix_empty_uploads
Browse files Browse the repository at this point in the history
Fix empty file uploads to S3 (and other streaming storages)
  • Loading branch information
rullzer authored Feb 18, 2019
2 parents 49e8093 + fc967a5 commit f6f002e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 5 deletions.
2 changes: 1 addition & 1 deletion 3rdparty
17 changes: 15 additions & 2 deletions apps/dav/lib/Connector/Sabre/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@

namespace OCA\DAV\Connector\Sabre;

use Icewind\Streams\CallbackWrapper;
use OC\AppFramework\Http\Request;
use OC\Files\Filesystem;
use OC\Files\View;
Expand Down Expand Up @@ -166,10 +167,22 @@ public function put($data) {
}

if ($partStorage->instanceOfStorage(Storage\IWriteStreamStorage::class)) {
$count = $partStorage->writeStream($internalPartPath, $data);

if (!is_resource($data)) {
$data = fopen('php://temp', 'r+');
fwrite($data, 'foobar');
rewind($data);
}

$isEOF = false;
$wrappedData = CallbackWrapper::wrap($data, null, null, null, null, function($stream) use (&$isEOF) {
$isEOF = feof($stream);
});

$count = $partStorage->writeStream($internalPartPath, $wrappedData);
$result = $count > 0;
if ($result === false) {
$result = feof($data);
$result = $isEOF;
}

} else {
Expand Down
25 changes: 23 additions & 2 deletions lib/private/Files/ObjectStore/S3ObjectTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@

namespace OC\Files\ObjectStore;

use Aws\S3\Exception\S3MultipartUploadException;
use Aws\S3\MultipartUploader;
use Aws\S3\ObjectUploader;
use Aws\S3\S3Client;
use Icewind\Streams\CallbackWrapper;

const S3_UPLOAD_PART_SIZE = 524288000; // 500MB

Expand Down Expand Up @@ -73,12 +76,30 @@ function readObject($urn) {
* @since 7.0.0
*/
function writeObject($urn, $stream) {
$uploader = new MultipartUploader($this->getConnection(), $stream, [
$count = 0;
$countStream = CallbackWrapper::wrap($stream, function ($read) use (&$count) {
$count += $read;
});

$uploader = new MultipartUploader($this->getConnection(), $countStream, [
'bucket' => $this->bucket,
'key' => $urn,
'part_size' => S3_UPLOAD_PART_SIZE
]);
$uploader->upload();

try {
$uploader->upload();
} catch (S3MultipartUploadException $e) {
// This is an emty file so just touch it then
if ($count === 0 && feof($countStream)) {
$uploader = new ObjectUploader($this->getConnection(), $this->bucket, $urn, '');
$uploader->upload();
} else {
throw $e;
}
}

fclose($countStream);
}

/**
Expand Down

0 comments on commit f6f002e

Please sign in to comment.