diff --git a/apps/dav/lib/Connector/Sabre/Directory.php b/apps/dav/lib/Connector/Sabre/Directory.php index 4df362548016..15bf6ab76161 100644 --- a/apps/dav/lib/Connector/Sabre/Directory.php +++ b/apps/dav/lib/Connector/Sabre/Directory.php @@ -42,6 +42,7 @@ use Sabre\DAV\Exception\BadRequest; use OC\Files\Mount\MoveableMount; use Sabre\DAV\IFile; +use OCA\DAV\Upload\FutureFile; class Directory extends \OCA\DAV\Connector\Sabre\Node implements \Sabre\DAV\ICollection, \Sabre\DAV\IQuota, \Sabre\DAV\IMoveTarget { @@ -125,18 +126,21 @@ public function createFile($name, $data = null) { throw new \Sabre\DAV\Exception\Forbidden(); } - // for chunked upload also updating a existing file is a "createFile" - // because we create all the chunks before re-assemble them to the existing file. - if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + $info = false; + if (\OC_FileChunking::isWebdavChunk()) { + // For chunked upload also updating a existing file is a "createFile" + // because we create all the chunks before re-assemble them to the existing file. - // exit if we can't create a new file and we don't updatable existing file + // exit if we can't create a new file and we don't update existing file $chunkInfo = \OC_FileChunking::decodeName($name); if (!$this->fileView->isCreatable($this->path) && !$this->fileView->isUpdatable($this->path . '/' . $chunkInfo['name']) ) { throw new \Sabre\DAV\Exception\Forbidden(); } - + } else if (FutureFile::isFutureFile()) { + // Future file (chunked upload) requires fileinfo + $info = $this->fileView->getFileInfo($this->path . '/' . $name); } else { // For non-chunked upload it is enough to check if we can create a new file if (!$this->fileView->isCreatable($this->path)) { @@ -147,12 +151,12 @@ public function createFile($name, $data = null) { $this->fileView->verifyPath($this->path, $name); $path = $this->fileView->getAbsolutePath($this->path) . '/' . $name; - // in case the file already exists/overwriting - $info = $this->fileView->getFileInfo($this->path . '/' . $name); + if (!$info) { // use a dummy FileInfo which is acceptable here since it will be refreshed after the put is complete $info = new \OC\Files\FileInfo($path, null, null, [], null); } + $node = new \OCA\DAV\Connector\Sabre\File($this->fileView, $info); $node->acquireLock(ILockingProvider::LOCK_SHARED); return $node->put($data); diff --git a/apps/dav/lib/Connector/Sabre/File.php b/apps/dav/lib/Connector/Sabre/File.php index 2687defcdc55..d0008a3f368b 100644 --- a/apps/dav/lib/Connector/Sabre/File.php +++ b/apps/dav/lib/Connector/Sabre/File.php @@ -120,7 +120,7 @@ public function put($data) { $this->verifyPath(); // chunked handling - if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + if (\OC_FileChunking::isWebdavChunk()) { try { return $this->createFileChunked($data); } catch (\Exception $e) { diff --git a/apps/dav/lib/Connector/Sabre/FilesPlugin.php b/apps/dav/lib/Connector/Sabre/FilesPlugin.php index 22aedd69e329..fec4d1c4fef2 100644 --- a/apps/dav/lib/Connector/Sabre/FilesPlugin.php +++ b/apps/dav/lib/Connector/Sabre/FilesPlugin.php @@ -398,7 +398,7 @@ public function handleUpdateProperties($path, PropPatch $propPatch) { */ public function sendFileIdHeader($filePath, \Sabre\DAV\INode $node = null) { // chunked upload handling - if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + if (\OC_FileChunking::isWebdavChunk()) { list($path, $name) = \Sabre\HTTP\URLUtil::splitPath($filePath); $info = \OC_FileChunking::decodeName($name); if (!empty($info)) { diff --git a/apps/dav/lib/Connector/Sabre/LockPlugin.php b/apps/dav/lib/Connector/Sabre/LockPlugin.php index 40e89d0a7128..4e3703c67c47 100644 --- a/apps/dav/lib/Connector/Sabre/LockPlugin.php +++ b/apps/dav/lib/Connector/Sabre/LockPlugin.php @@ -51,7 +51,7 @@ public function initialize(\Sabre\DAV\Server $server) { public function getLock(RequestInterface $request) { // we can't listen on 'beforeMethod:PUT' due to order of operations with setting up the tree // so instead we limit ourselves to the PUT method manually - if ($request->getMethod() !== 'PUT' || isset($_SERVER['HTTP_OC_CHUNKED'])) { + if ($request->getMethod() !== 'PUT' || \OC_FileChunking::isWebdavChunk()) { return; } try { @@ -69,7 +69,7 @@ public function getLock(RequestInterface $request) { } public function releaseLock(RequestInterface $request) { - if ($request->getMethod() !== 'PUT' || isset($_SERVER['HTTP_OC_CHUNKED'])) { + if ($request->getMethod() !== 'PUT' || \OC_FileChunking::isWebdavChunk()) { return; } try { diff --git a/apps/dav/lib/Connector/Sabre/ObjectTree.php b/apps/dav/lib/Connector/Sabre/ObjectTree.php index 4319f92011d0..2174a7c02bea 100644 --- a/apps/dav/lib/Connector/Sabre/ObjectTree.php +++ b/apps/dav/lib/Connector/Sabre/ObjectTree.php @@ -76,7 +76,7 @@ public function init(\Sabre\DAV\INode $rootNode, \OC\Files\View $view, \OCP\File * @return string path to real file */ private function resolveChunkFile($path) { - if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + if (\OC_FileChunking::isWebdavChunk()) { // resolve to real file name to find the proper node list($dir, $name) = \Sabre\HTTP\URLUtil::splitPath($path); if ($dir == '/' || $dir == '.') { diff --git a/apps/dav/lib/Upload/FutureFile.php b/apps/dav/lib/Upload/FutureFile.php index 706281628268..9ef8b98b5c2f 100644 --- a/apps/dav/lib/Upload/FutureFile.php +++ b/apps/dav/lib/Upload/FutureFile.php @@ -40,6 +40,23 @@ class FutureFile implements \Sabre\DAV\IFile { /** @var string */ private $name; + static public function getFutureFileName() { + return '.file'; + } + + static public function isFutureFile() { + $davUploadsTarget = '/dav/uploads'; + + // Check if pathinfo starts with dav uploads target and basename is future file basename + if (isset($_SERVER['PATH_INFO']) + && pathinfo($_SERVER['PATH_INFO'], PATHINFO_BASENAME) === FutureFile::getFutureFileName() + && (strpos($_SERVER['PATH_INFO'], $davUploadsTarget) === 0)) { + return true; + } + + return false; + } + /** * @param Directory $root * @param string $name diff --git a/apps/dav/lib/Upload/UploadFolder.php b/apps/dav/lib/Upload/UploadFolder.php index 774678b4684c..0597e742e3de 100644 --- a/apps/dav/lib/Upload/UploadFolder.php +++ b/apps/dav/lib/Upload/UploadFolder.php @@ -43,20 +43,20 @@ function createDirectory($name) { } function getChild($name) { - if ($name === '.file') { - return new FutureFile($this->node, '.file'); + if ($name === FutureFile::getFutureFileName()) { + return new FutureFile($this->node, FutureFile::getFutureFileName()); } return $this->node->getChild($name); } function getChildren() { $children = $this->node->getChildren(); - $children[] = new FutureFile($this->node, '.file'); + $children[] = new FutureFile($this->node, FutureFile::getFutureFileName()); return $children; } function childExists($name) { - if ($name === '.file') { + if ($name === FutureFile::getFutureFileName()) { return true; } return $this->node->childExists($name); diff --git a/lib/private/legacy/filechunking.php b/lib/private/legacy/filechunking.php index 7efe914071cd..50e00635e8c7 100644 --- a/lib/private/legacy/filechunking.php +++ b/lib/private/legacy/filechunking.php @@ -39,6 +39,13 @@ class OC_FileChunking { */ protected $ttl; + static public function isWebdavChunk() { + if (isset($_SERVER['HTTP_OC_CHUNKED'])) { + return true; + } + return false; + } + static public function decodeName($name) { preg_match('/(?P.*)-chunking-(?P\d+)-(?P\d+)-(?P\d+)/', $name, $matches); return $matches;