diff options
author | Morris Jobke <hey@morrisjobke.de> | 2019-01-14 11:26:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-14 11:26:29 +0100 |
commit | 5a27e54f4b6eb50b24ca8a6e4f77878b04e1c3fd (patch) | |
tree | c413f25054124afebea96ede701ffea688d04b6c /lib | |
parent | 8113dfd4e7587d829631f7656005b0d18897a3c6 (diff) | |
parent | d6bf5d43841f8d80ed54137db75c8ca6d2396cf4 (diff) | |
download | nextcloud-server-5a27e54f4b6eb50b24ca8a6e4f77878b04e1c3fd.tar.gz nextcloud-server-5a27e54f4b6eb50b24ca8a6e4f77878b04e1c3fd.zip |
Merge pull request #13032 from nextcloud/objectstore-write-exists
upload new files in objectstore to a .part path first
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Files/ObjectStore/Azure.php | 13 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/ObjectStoreStorage.php | 22 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/S3ObjectTrait.php | 4 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/StorageObjectStore.php | 3 | ||||
-rw-r--r-- | lib/private/Files/ObjectStore/Swift.php | 3 | ||||
-rw-r--r-- | lib/public/Files/ObjectStore/IObjectStore.php | 9 |
6 files changed, 49 insertions, 5 deletions
diff --git a/lib/private/Files/ObjectStore/Azure.php b/lib/private/Files/ObjectStore/Azure.php index 899c826ec19..e162c510b98 100644 --- a/lib/private/Files/ObjectStore/Azure.php +++ b/lib/private/Files/ObjectStore/Azure.php @@ -115,4 +115,17 @@ class Azure implements IObjectStore { public function deleteObject($urn) { $this->getBlobClient()->deleteBlob($this->containerName, $urn); } + + public function objectExists($urn) { + try { + $this->getBlobClient()->getBlobMetadata($this->containerName, $urn); + return true; + } catch (ServiceException $e) { + if ($e->getCode() === 404) { + return false; + } else { + throw $e; + } + } + } } diff --git a/lib/private/Files/ObjectStore/ObjectStoreStorage.php b/lib/private/Files/ObjectStore/ObjectStoreStorage.php index 26db551a384..7ee1c8e2055 100644 --- a/lib/private/Files/ObjectStore/ObjectStoreStorage.php +++ b/lib/private/Files/ObjectStore/ObjectStoreStorage.php @@ -436,7 +436,10 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { $stat['mimetype'] = $mimetype; $stat['etag'] = $this->getETag($path); - $fileId = $this->getCache()->put($path, $stat); + $exists = $this->getCache()->inCache($path); + $uploadPath = $exists ? $path : $path . '.part'; + $fileId = $this->getCache()->put($uploadPath, $stat); + $urn = $this->getURN($fileId); try { //upload to object storage if ($size === null) { @@ -446,22 +449,31 @@ class ObjectStoreStorage extends \OC\Files\Storage\Common { ]); $size = $writtenSize; }); - $this->objectStore->writeObject($this->getURN($fileId), $countStream); + $this->objectStore->writeObject($urn, $countStream); if (is_resource($countStream)) { fclose($countStream); } } else { - $this->objectStore->writeObject($this->getURN($fileId), $stream); + $this->objectStore->writeObject($urn, $stream); } } catch (\Exception $ex) { - $this->getCache()->remove($path); + $this->getCache()->remove($uploadPath); $this->logger->logException($ex, [ 'app' => 'objectstore', - 'message' => 'Could not create object ' . $this->getURN($fileId) . ' for ' . $path, + 'message' => 'Could not create object ' . $urn . ' for ' . $path, ]); throw $ex; // make this bubble up } + if (!$exists) { + if ($this->objectStore->objectExists($urn)) { + $this->getCache()->move($uploadPath, $path); + } else { + $this->getCache()->remove($uploadPath); + throw new \Exception("Object not found after writing (urn: $urn, path: $path)", 404); + } + } + return $size; } } diff --git a/lib/private/Files/ObjectStore/S3ObjectTrait.php b/lib/private/Files/ObjectStore/S3ObjectTrait.php index 280a8efa81c..a1110d87c8f 100644 --- a/lib/private/Files/ObjectStore/S3ObjectTrait.php +++ b/lib/private/Files/ObjectStore/S3ObjectTrait.php @@ -90,4 +90,8 @@ trait S3ObjectTrait { 'Key' => $urn ]); } + + public function objectExists($urn) { + return $this->getConnection()->doesObjectExist($this->bucket, $urn); + } } diff --git a/lib/private/Files/ObjectStore/StorageObjectStore.php b/lib/private/Files/ObjectStore/StorageObjectStore.php index 0d35ba2ed7a..f9fc1b5a4aa 100644 --- a/lib/private/Files/ObjectStore/StorageObjectStore.php +++ b/lib/private/Files/ObjectStore/StorageObjectStore.php @@ -89,4 +89,7 @@ class StorageObjectStore implements IObjectStore { $this->storage->unlink($urn); } + public function objectExists($urn) { + return $this->storage->file_exists($urn); + } } diff --git a/lib/private/Files/ObjectStore/Swift.php b/lib/private/Files/ObjectStore/Swift.php index e379e54d018..3d6bf9d69da 100644 --- a/lib/private/Files/ObjectStore/Swift.php +++ b/lib/private/Files/ObjectStore/Swift.php @@ -128,4 +128,7 @@ class Swift implements IObjectStore { $this->getContainer()->delete(); } + public function objectExists($urn) { + return $this->getContainer()->objectExists($urn); + } } diff --git a/lib/public/Files/ObjectStore/IObjectStore.php b/lib/public/Files/ObjectStore/IObjectStore.php index 628fd5852da..83c4b1065d6 100644 --- a/lib/public/Files/ObjectStore/IObjectStore.php +++ b/lib/public/Files/ObjectStore/IObjectStore.php @@ -63,4 +63,13 @@ interface IObjectStore { * @since 7.0.0 */ public function deleteObject($urn); + + /** + * Check if an object exists in the object store + * + * @param string $urn + * @return bool + * @since 16.0.0 + */ + public function objectExists($urn); } |