Merge pull request #14210 from nextcloud/fix/14192/fix_empty_uploads

Fix empty file uploads to S3 (and other streaming storages)
This commit is contained in:
Roeland Jago Douma 2019-02-18 15:39:17 +01:00 committed by GitHub
commit f6f002e2ad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 39 additions and 5 deletions

@ -1 +1 @@
Subproject commit 42b675142d5c33b585f1bb204e910afeed7e98db
Subproject commit 7c64d231f833b8ab8f9dcd017499c8c18b7b78f9

View file

@ -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;
@ -166,10 +167,22 @@ class File extends Node implements IFile {
}
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 {

View file

@ -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
@ -73,12 +76,30 @@ trait S3ObjectTrait {
* @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);
}
/**