summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2013-11-13 02:59:34 -0800
committerVincent Petry <pvince81@owncloud.com>2013-11-13 02:59:34 -0800
commit3fa651f2b1754963e3c0c1a30ab6584a72296b02 (patch)
tree2db912d87658ab5446f5d0a7587d009ed593560b /lib
parentdc30056025f63d32de0846bdf14e971988f83cdb (diff)
parent77429c28fd6a363959a1c4cf034a956059849d6b (diff)
downloadnextcloud-server-3fa651f2b1754963e3c0c1a30ab6584a72296b02.tar.gz
nextcloud-server-3fa651f2b1754963e3c0c1a30ab6584a72296b02.zip
Merge pull request #5447 from owncloud/fixing-5117-master
No data corruption duriing parallel upload
Diffstat (limited to 'lib')
-rw-r--r--lib/private/connector/sabre/file.php28
1 files changed, 25 insertions, 3 deletions
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 919bb1fc6f4..26b5d200bde 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -230,9 +230,31 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
}
if ($chunk_handler->isComplete()) {
- $newPath = $path . '/' . $info['name'];
- $chunk_handler->file_assemble($newPath);
- return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
+
+ // we first assembly the target file as a part file
+ $partFile = $path . '/' . $info['name'] . '.ocTransferId' . $info['transferid'] . '.part';
+ $chunk_handler->file_assemble($partFile);
+
+ // here is the final atomic rename
+ $fs = $this->getFS();
+ $targetPath = $path . '/' . $info['name'];
+ $renameOkay = $fs->rename($partFile, $targetPath);
+ $fileExists = $fs->file_exists($targetPath);
+ if ($renameOkay === false || $fileExists === false) {
+ \OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
+ $fs->unlink($targetPath);
+ throw new Sabre_DAV_Exception();
+ }
+
+ // allow sync clients to send the mtime along in a header
+ $mtime = OC_Request::hasModificationTime();
+ if ($mtime !== false) {
+ if($fs->touch($this->path, $mtime)) {
+ header('X-OC-MTime: accepted');
+ }
+ }
+
+ return OC_Connector_Sabre_Node::getETagPropertyForPath($targetPath);
}
return null;