Merge pull request #14273 from nextcloud/backport/14210/stable15

[stable15] Fix empty file uploads to S3 (and other streaming storages)
This commit is contained in:
Roeland Jago Douma 2019-02-20 15:26:36 +01:00 committed by GitHub
commit c9a4f010dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 5 deletions

@ -1 +1 @@
Subproject commit 4c31d7509c9ab8388429a5c3e671dc3e49f9fe92
Subproject commit 88f57274c0fa29e05a08351944915b0772a2fc2a

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,26 @@ 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;
if (is_resource($wrappedData)) {
$result = feof($wrappedData);
}
}
} 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
]);
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);
}
/**