diff options
author | Vincent Petry <pvince81@owncloud.com> | 2013-11-13 02:59:34 -0800 |
---|---|---|
committer | Vincent Petry <pvince81@owncloud.com> | 2013-11-13 02:59:34 -0800 |
commit | 3fa651f2b1754963e3c0c1a30ab6584a72296b02 (patch) | |
tree | 2db912d87658ab5446f5d0a7587d009ed593560b /lib/private/connector | |
parent | dc30056025f63d32de0846bdf14e971988f83cdb (diff) | |
parent | 77429c28fd6a363959a1c4cf034a956059849d6b (diff) | |
download | nextcloud-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/private/connector')
-rw-r--r-- | lib/private/connector/sabre/file.php | 28 |
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; |