From 3d2f68c43f4ed3b3bcf1f8a7d7fe17139a4604f1 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 5 Jul 2010 00:39:38 +0200 Subject: [PATCH] mayor improvements in the handling of locks in webdav --- inc/HTTP/WebDAV/Server/Filesystem.php | 88 +++++++++++++++++++++------ 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/inc/HTTP/WebDAV/Server/Filesystem.php b/inc/HTTP/WebDAV/Server/Filesystem.php index 72e747439d..b96fb414c2 100755 --- a/inc/HTTP/WebDAV/Server/Filesystem.php +++ b/inc/HTTP/WebDAV/Server/Filesystem.php @@ -323,7 +323,6 @@ function PUT(&$options) { $fspath = $options["path"]; - $dir = dirname($fspath); if (!OC_FILESYSTEM::file_exists($dir) || !OC_FILESYSTEM::is_dir($dir)) { return "409 Conflict"; // TODO right status code for both? @@ -394,7 +393,14 @@ if (!OC_FILESYSTEM::file_exists($path)) { return "404 Not found"; } - + $lock=self::checkLock($path); + if(is_array($lock)){ + $owner=$options['owner']; + $lockOwner=$lock['owner']; + if($owner==$lockOwner){ + return "423 Locked"; + } + } if (OC_FILESYSTEM::is_dir($path)) { $query = "DELETE FROM properties WHERE path LIKE '".$this->_slashify($options["path"])."%'"; OC_DB::query($query); @@ -593,11 +599,19 @@ { // get absolute fs path to requested resource $fspath = $options["path"]; - // TODO recursive locks on directories not supported yet // makes litmus test "32. lock_collection" fail - if (is_dir($fspath) && !empty($options["depth"])) { - return "409 Conflict"; + if (OC_FILESYSTEM::is_dir($fspath) && !empty($options["depth"])) { + switch($options["depth"]){ + case 'infinity': + $recursion=1; + break; + case '0': + $recursion=0; + break; + } + }else{ + $recursion=0; } $options["timeout"] = time()+300; // 5min. hardcoded @@ -606,11 +620,10 @@ $where = "WHERE path = '$options[path]' AND token = '$options[update]'"; $query = "SELECT owner, exclusivelock FROM locks $where"; - $res = OC_DB::query($query); - $row = OC_DB::fetch_assoc($res); - OC_DB::free_result($res); + $res = OC_DB::select($query); - if (is_array($row)) { + if (is_array($res) and isset($res[0])) { + $row=$res[0]; $query = "UPDATE `locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where"; OC_DB::query($query); @@ -619,8 +632,23 @@ $options['type'] = $row["exclusivelock"] ? "write" : "read"; return true; - } else { - return false; + } else {//check for indirect refresh + $query = "SELECT * + FROM locks + WHERE recursive = 1 + "; + $res = OC_DB::select($query); + foreach($res as $row){ + if(strpos($options['path'],$row['path'])==0){//are we a child of a folder with an recursive lock + $where = "WHERE path = '$row[path]' AND token = '$options[update]'"; + $query = "UPDATE `locks` SET `expires` = '$options[timeout]', `modified` = ".time()." $where"; + OC_DB::query($query); + $options['owner'] = $row['owner']; + $options['scope'] = $row["exclusivelock"] ? "exclusive" : "shared"; + $options['type'] = $row["exclusivelock"] ? "write" : "read"; + return true; + } + } } } @@ -631,11 +659,14 @@ , `modified` = ".time()." , `owner` = '$options[owner]' , `expires` = '$options[timeout]' - , `exclusivelock` = " .($options['scope'] === "exclusive" ? "1" : "0") - ; + , `exclusivelock` = " .($options['scope'] === "exclusive" ? "1" : "0")." + , `recursive` = $recursion"; OC_DB::query($query); - - return OC_DB::affected_rows() ? "200 OK" : "409 Conflict"; + $rows=OC_DB::affected_rows(); + if(!OC_FILESYSTEM::file_exists($fspath) and $rows>0) { + return "201 Created"; + } + return OC_DB::affected_rows($rows) ? "200 OK" : "409 Conflict"; } /** @@ -668,9 +699,8 @@ WHERE path = '$path' "; $res = OC_DB::select($query); - if ($res) { + if (is_array($res) and isset($res[0])) { $row=$res[0]; - OC_DB::free_result($res); if ($row) { $result = array( "type" => "write", @@ -680,9 +710,31 @@ "token" => $row['token'], "created" => $row['created'], "modified" => $row['modified'], - "expires" => $row['expires'] + "expires" => $row['expires'], + "recursive" => $row['recursive'] ); } + }else{ + //check for recursive locks; + $query = "SELECT * + FROM locks + WHERE recursive = 1 + "; + $res = OC_DB::select($query); + foreach($res as $row){ + if(strpos($path,$row['path'])==0){//are we a child of a folder with an recursive lock + $result = array( "type" => "write", + "scope" => $row["exclusivelock"] ? "exclusive" : "shared", + "depth" => 0, + "owner" => $row['owner'], + "token" => $row['token'], + "created" => $row['created'], + "modified" => $row['modified'], + "expires" => $row['expires'], + "recursive" => $row['recursive'] + ); + } + } } return $result;