summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoricewind1991 <robin@icewind.nl>2014-04-25 14:42:43 +0200
committericewind1991 <robin@icewind.nl>2014-04-25 14:42:43 +0200
commit5194f014c9c196bb891b6ed057500bd151ee7169 (patch)
tree23b552695e1c274850d901142be8e96399c2d7b5 /lib
parent6925e722fa16c1f93d9c4b523cc00ab3ea624296 (diff)
parent4109521ccef38ff2cf16bf0fab7ff4d142d26713 (diff)
downloadnextcloud-server-5194f014c9c196bb891b6ed057500bd151ee7169.tar.gz
nextcloud-server-5194f014c9c196bb891b6ed057500bd151ee7169.zip
Merge pull request #7504 from owncloud/webdav-injection
Proper injection of filesystem view into the webdav connector
Diffstat (limited to 'lib')
-rw-r--r--lib/private/connector/sabre/aborteduploaddetectionplugin.php33
-rw-r--r--lib/private/connector/sabre/directory.php45
-rw-r--r--lib/private/connector/sabre/file.php70
-rw-r--r--lib/private/connector/sabre/node.php169
-rw-r--r--lib/private/connector/sabre/objecttree.php104
-rw-r--r--lib/private/connector/sabre/quotaplugin.php35
-rw-r--r--lib/private/files/cache/scanner.php7
7 files changed, 207 insertions, 256 deletions
diff --git a/lib/private/connector/sabre/aborteduploaddetectionplugin.php b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
index ad759d1d84a..1a092a59a82 100644
--- a/lib/private/connector/sabre/aborteduploaddetectionplugin.php
+++ b/lib/private/connector/sabre/aborteduploaddetectionplugin.php
@@ -22,11 +22,16 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
private $server;
/**
- * is kept public to allow overwrite for unit testing
- *
* @var \OC\Files\View
*/
- public $fileView;
+ private $fileView;
+
+ /**
+ * @param \OC\Files\View $view
+ */
+ public function __construct($view) {
+ $this->fileView = $view;
+ }
/**
* This initializes the plugin.
@@ -55,7 +60,7 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
// we should only react on PUT which is used for upload
// e.g. with LOCK this will not work, but LOCK uses createFile() as well
- if ($this->server->httpRequest->getMethod() !== 'PUT' ) {
+ if ($this->server->httpRequest->getMethod() !== 'PUT') {
return;
}
@@ -70,9 +75,9 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
if (!$expected) {
return;
}
- $actual = $this->getFileView()->filesize($filePath);
+ $actual = $this->fileView->filesize($filePath);
if ($actual != $expected) {
- $this->getFileView()->unlink($filePath);
+ $this->fileView->unlink($filePath);
throw new Sabre_DAV_Exception_BadRequest('expected filesize ' . $expected . ' got ' . $actual);
}
@@ -81,8 +86,7 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
/**
* @return string
*/
- public function getLength()
- {
+ public function getLength() {
$req = $this->server->httpRequest;
$length = $req->getHeader('X-Expected-Entity-Length');
if (!$length) {
@@ -91,17 +95,4 @@ class OC_Connector_Sabre_AbortedUploadDetectionPlugin extends Sabre_DAV_ServerPl
return $length;
}
-
- /**
- * @return \OC\Files\View
- */
- public function getFileView()
- {
- if (is_null($this->fileView)) {
- // initialize fileView
- $this->fileView = \OC\Files\Filesystem::getView();
- }
-
- return $this->fileView;
- }
}
diff --git a/lib/private/connector/sabre/directory.php b/lib/private/connector/sabre/directory.php
index 5d386a772a7..1bb526e451e 100644
--- a/lib/private/connector/sabre/directory.php
+++ b/lib/private/connector/sabre/directory.php
@@ -29,7 +29,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* Data will either be supplied as a stream resource, or in certain cases
* as a string. Keep in mind that you may have to support either.
*
- * After succesful creation of the file, you may choose to return the ETag
+ * After successful creation of the file, you may choose to return the ETag
* of the new file here.
*
* The returned ETag must be surrounded by double-quotes (The quotes should
@@ -51,25 +51,27 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
public function createFile($name, $data = null) {
// for chunked upload also updating a existing file is a "createFile"
- // because we create all the chunks before reasamble them to the existing file.
+ // because we create all the chunks before re-assemble them to the existing file.
if (isset($_SERVER['HTTP_OC_CHUNKED'])) {
// exit if we can't create a new file and we don't updatable existing file
$info = OC_FileChunking::decodeName($name);
- if (!\OC\Files\Filesystem::isCreatable($this->path) &&
- !\OC\Files\Filesystem::isUpdatable($this->path . '/' . $info['name'])) {
+ if (!$this->fileView->isCreatable($this->path) &&
+ !$this->fileView->isUpdatable($this->path . '/' . $info['name'])) {
throw new \Sabre_DAV_Exception_Forbidden();
}
} else {
// For non-chunked upload it is enough to check if we can create a new file
- if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+ if (!$this->fileView->isCreatable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
}
- $path = $this->path . '/' . $name;
- $node = new OC_Connector_Sabre_File($path);
+ $path = $this->fileView->getAbsolutePath($this->path) . '/' . $name;
+ // using a dummy FileInfo is acceptable here since it will be refreshed after the put is complete
+ $info = new \OC\Files\FileInfo($path, null, null, array());
+ $node = new OC_Connector_Sabre_File($this->fileView, $info);
return $node->put($data);
}
@@ -81,13 +83,12 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* @return void
*/
public function createDirectory($name) {
-
- if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+ if (!$this->fileView->isCreatable($this->path)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
$newPath = $this->path . '/' . $name;
- if(!\OC\Files\Filesystem::mkdir($newPath)) {
+ if(!$this->fileView->mkdir($newPath)) {
throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath);
}
@@ -97,15 +98,15 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
* Returns a specific child node, referenced by its name
*
* @param string $name
- * @param OC\Files\FileInfo $info
- * @throws Sabre_DAV_Exception_FileNotFound
+ * @param \OCP\Files\FileInfo $info
+ * @throws Sabre_DAV_Exception_NotFound
* @return Sabre_DAV_INode
*/
public function getChild($name, $info = null) {
$path = $this->path . '/' . $name;
if (is_null($info)) {
- $info = \OC\Files\Filesystem::getFileInfo($path);
+ $info = $this->fileView->getFileInfo($path);
}
if (!$info) {
@@ -113,12 +114,10 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
}
if ($info['mimetype'] == 'httpd/unix-directory') {
- $node = new OC_Connector_Sabre_Directory($path);
+ $node = new OC_Connector_Sabre_Directory($this->fileView, $info);
} else {
- $node = new OC_Connector_Sabre_File($path);
+ $node = new OC_Connector_Sabre_File($this->fileView, $info);
}
-
- $node->setFileinfoCache($info);
return $node;
}
@@ -129,7 +128,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function getChildren() {
- $folder_content = \OC\Files\Filesystem::getDirectoryContent($this->path);
+ $folder_content = $this->fileView->getDirectoryContent($this->path);
$paths = array();
foreach($folder_content as $info) {
$paths[] = $this->path.'/'.$info['name'];
@@ -160,7 +159,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
$nodes = array();
foreach($folder_content as $info) {
- $node = $this->getChild($info['name'], $info);
+ $node = $this->getChild($info->getName(), $info);
$node->setPropertyCache($properties[$this->path.'/'.$info['name']]);
$nodes[] = $node;
}
@@ -176,7 +175,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
public function childExists($name) {
$path = $this->path . '/' . $name;
- return \OC\Files\Filesystem::file_exists($path);
+ return $this->fileView->file_exists($path);
}
@@ -188,11 +187,11 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
*/
public function delete() {
- if (!\OC\Files\Filesystem::isDeletable($this->path)) {
+ if (!$this->info->isDeletable()) {
throw new \Sabre_DAV_Exception_Forbidden();
}
- \OC\Files\Filesystem::rmdir($this->path);
+ $this->fileView->rmdir($this->path);
}
@@ -224,7 +223,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
public function getProperties($properties) {
$props = parent::getProperties($properties);
if (in_array(self::GETETAG_PROPERTYNAME, $properties) && !isset($props[self::GETETAG_PROPERTYNAME])) {
- $props[self::GETETAG_PROPERTYNAME] = $this->getETagPropertyForPath($this->path);
+ $props[self::GETETAG_PROPERTYNAME] = $this->info->getEtag();
}
return $props;
}
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index 433b4d805c9..66b50a87552 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -42,14 +42,16 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
*
* @param resource $data
* @throws Sabre_DAV_Exception_Forbidden
+ * @throws OC_Connector_Sabre_Exception_UnsupportedMediaType
+ * @throws Sabre_DAV_Exception_BadRequest
+ * @throws Sabre_DAV_Exception
+ * @throws OC_Connector_Sabre_Exception_EntityTooLarge
+ * @throws Sabre_DAV_Exception_ServiceUnavailable
* @return string|null
*/
public function put($data) {
-
- $fs = $this->getFS();
-
- if ($fs->file_exists($this->path) &&
- !$fs->isUpdatable($this->path)) {
+ if ($this->info && $this->fileView->file_exists($this->path) &&
+ !$this->info->isUpdateable()) {
throw new \Sabre_DAV_Exception_Forbidden();
}
@@ -72,10 +74,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
$partpath = $this->path . '.ocTransferId' . rand() . '.part';
try {
- $putOkay = $fs->file_put_contents($partpath, $data);
+ $putOkay = $this->fileView->file_put_contents($partpath, $data);
if ($putOkay === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR);
- $fs->unlink($partpath);
+ $this->fileView->unlink($partpath);
// because we have no clue about the cause we can only throw back a 500/Internal Server Error
throw new Sabre_DAV_Exception('Could not write file contents');
}
@@ -98,29 +100,30 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
}
// rename to correct path
- $renameOkay = $fs->rename($partpath, $this->path);
- $fileExists = $fs->file_exists($this->path);
+ $renameOkay = $this->fileView->rename($partpath, $this->path);
+ $fileExists = $this->fileView->file_exists($this->path);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
- $fs->unlink($partpath);
+ $this->fileView->unlink($partpath);
throw new Sabre_DAV_Exception('Could not rename part file to final file');
}
// allow sync clients to send the mtime along in a header
$mtime = OC_Request::hasModificationTime();
if ($mtime !== false) {
- if($fs->touch($this->path, $mtime)) {
+ if($this->fileView->touch($this->path, $mtime)) {
header('X-OC-MTime: accepted');
}
}
+ $this->refreshInfo();
- return $this->getETagPropertyForPath($this->path);
+ return '"' . $this->info->getEtag() . '"';
}
/**
* Returns the data
*
- * @return string
+ * @return string | resource
*/
public function get() {
@@ -128,7 +131,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
if (\OC_Util::encryptedFiles()) {
throw new \Sabre_DAV_Exception_ServiceUnavailable();
} else {
- return \OC\Files\Filesystem::fopen($this->path, 'rb');
+ return $this->fileView->fopen($this->path, 'rb');
}
}
@@ -140,12 +143,10 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
* @throws Sabre_DAV_Exception_Forbidden
*/
public function delete() {
- $fs = $this->getFS();
-
- if (!$fs->isDeletable($this->path)) {
+ if (!$this->info->isDeletable()) {
throw new \Sabre_DAV_Exception_Forbidden();
}
- $fs->unlink($this->path);
+ $this->fileView->unlink($this->path);
// remove properties
$this->removeProperties();
@@ -158,12 +159,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
* @return int
*/
public function getSize() {
- $this->getFileinfoCache();
- if ($this->fileinfo_cache['size'] > -1) {
- return $this->fileinfo_cache['size'];
- } else {
- return null;
- }
+ return $this->info->getSize();
}
/**
@@ -178,11 +174,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
* @return mixed
*/
public function getETag() {
- $properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME));
- if (isset($properties[self::GETETAG_PROPERTYNAME])) {
- return $properties[self::GETETAG_PROPERTYNAME];
- }
- return null;
+ return '"' . $this->info->getEtag() . '"';
}
/**
@@ -193,18 +185,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
* @return mixed
*/
public function getContentType() {
- if (isset($this->fileinfo_cache['mimetype'])) {
- $mimeType = $this->fileinfo_cache['mimetype'];
- } else {
- $mimeType = \OC\Files\Filesystem::getMimeType($this->path);
- }
+ $mimeType = $this->info->getMimetype();
return \OC_Helper::getSecureMimeType($mimeType);
-
}
/**
* @param resource $data
+ * @return null|string
*/
private function createFileChunked($data)
{
@@ -236,15 +224,14 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
$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);
+ $renameOkay = $this->fileView->rename($partFile, $targetPath);
+ $fileExists = $this->fileView->file_exists($targetPath);
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
// only delete if an error occurred and the target file was already created
if ($fileExists) {
- $fs->unlink($targetPath);
+ $this->fileView->unlink($targetPath);
}
throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks');
}
@@ -252,12 +239,13 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
// allow sync clients to send the mtime along in a header
$mtime = OC_Request::hasModificationTime();
if ($mtime !== false) {
- if($fs->touch($targetPath, $mtime)) {
+ if($this->fileView->touch($targetPath, $mtime)) {
header('X-OC-MTime: accepted');
}
}
- return OC_Connector_Sabre_Node::getETagPropertyForPath($targetPath);
+ $info = $this->fileView->getFileInfo($targetPath);
+ return $info->getEtag();
}
return null;
diff --git a/lib/private/connector/sabre/node.php b/lib/private/connector/sabre/node.php
index 7ff9f50ca68..eede39cba8b 100644
--- a/lib/private/connector/sabre/node.php
+++ b/lib/private/connector/sabre/node.php
@@ -20,7 +20,6 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
-
abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties {
const GETETAG_PROPERTYNAME = '{DAV:}getetag';
const LASTMODIFIED_PROPERTYNAME = '{DAV:}lastmodified';
@@ -29,15 +28,13 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* Allow configuring the method used to generate Etags
*
* @var array(class_name, function_name)
- */
+ */
public static $ETagFunction = null;
/**
- * is kept public to allow overwrite for unit testing
- *
* @var \OC\Files\View
*/
- public $fileView;
+ protected $fileView;
/**
* The path to the current node
@@ -47,52 +44,54 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
protected $path;
/**
- * node fileinfo cache
- * @var array
- */
- protected $fileinfo_cache;
- /**
* node properties cache
+ *
* @var array
*/
protected $property_cache = null;
/**
+ * @var \OCP\Files\FileInfo
+ */
+ protected $info;
+
+ /**
* @brief Sets up the node, expects a full path name
- * @param string $path
- * @return void
+ * @param \OC\Files\View $view
+ * @param \OCP\Files\FileInfo $info
*/
- public function __construct($path) {
- $this->path = $path;
+ public function __construct($view, $info) {
+ $this->fileView = $view;
+ $this->path = $this->fileView->getRelativePath($info->getPath());
+ $this->info = $info;
}
-
+ protected function refreshInfo() {
+ $this->info = $this->fileView->getFileInfo($this->path);
+ }
/**
* @brief Returns the name of the node
* @return string
*/
public function getName() {
-
- list(, $name) = Sabre_DAV_URLUtil::splitPath($this->path);
- return $name;
-
+ return $this->info->getName();
}
/**
* @brief Renames the node
* @param string $name The new name
- * @return void
+ * @throws Sabre_DAV_Exception_BadRequest
+ * @throws Sabre_DAV_Exception_Forbidden
*/
public function setName($name) {
- $fs = $this->getFS();
// rename is only allowed if the update privilege is granted
- if (!$fs->isUpdatable($this->path)) {
+ if (!$this->info->isUpdateable()) {
throw new \Sabre_DAV_Exception_Forbidden();
}
- list($parentPath, ) = Sabre_DAV_URLUtil::splitPath($this->path);
+ list($parentPath,) = Sabre_DAV_URLUtil::splitPath($this->path);
list(, $newName) = Sabre_DAV_URLUtil::splitPath($name);
if (!\OCP\Util::isValidFileName($newName)) {
@@ -102,38 +101,17 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
$newPath = $parentPath . '/' . $newName;
$oldPath = $this->path;
- $fs->rename($this->path, $newPath);
+ $this->fileView->rename($this->path, $newPath);
$this->path = $newPath;
- $query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?'
- .' WHERE `userid` = ? AND `propertypath` = ?' );
- $query->execute( array( $newPath, OC_User::getUser(), $oldPath ));
-
- }
-
- public function setFileinfoCache($fileinfo_cache)
- {
- $this->fileinfo_cache = $fileinfo_cache;
- }
-
- /**
- * @brief Ensure that the fileinfo cache is filled
- * @note Uses OC_FileCache or a direct stat
- */
- protected function getFileinfoCache() {
- if (!isset($this->fileinfo_cache)) {
- if ($fileinfo_cache = \OC\Files\Filesystem::getFileInfo($this->path)) {
- } else {
- $fileinfo_cache = \OC\Files\Filesystem::stat($this->path);
- }
-
- $this->fileinfo_cache = $fileinfo_cache;
- }
+ $query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?'
+ . ' WHERE `userid` = ? AND `propertypath` = ?');
+ $query->execute(array($newPath, OC_User::getUser(), $oldPath));
+ $this->refreshInfo();
}
- public function setPropertyCache($property_cache)
- {
+ public function setPropertyCache($property_cache) {
$this->property_cache = $property_cache;
}
@@ -142,8 +120,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* @return int timestamp as integer
*/
public function getLastModified() {
- $this->getFileinfoCache();
- $timestamp = $this->fileinfo_cache['mtime'];
+ $timestamp = $this->info->getMtime();
if (!empty($timestamp)) {
return (int)$timestamp;
}
@@ -156,39 +133,40 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* Even if the modification time is set to a custom value the access time is set to now.
*/
public function touch($mtime) {
- \OC\Files\Filesystem::touch($this->path, $mtime);
+ $this->fileView->touch($this->path, $mtime);
+ $this->refreshInfo();
}
/**
* @brief Updates properties on this node,
* @see Sabre_DAV_IProperties::updateProperties
+ * @param array $properties
* @return boolean
*/
public function updateProperties($properties) {
$existing = $this->getProperties(array());
- foreach($properties as $propertyName => $propertyValue) {
+ foreach ($properties as $propertyName => $propertyValue) {
// If it was null, we need to delete the property
if (is_null($propertyValue)) {
- if(array_key_exists( $propertyName, $existing )) {
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
- .' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
- $query->execute( array( OC_User::getUser(), $this->path, $propertyName ));
+ if (array_key_exists($propertyName, $existing)) {
+ $query = OC_DB::prepare('DELETE FROM `*PREFIX*properties`'
+ . ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?');
+ $query->execute(array(OC_User::getUser(), $this->path, $propertyName));
}
- }
- else {
- if( strcmp( $propertyName, self::GETETAG_PROPERTYNAME) === 0 ) {
- \OC\Files\Filesystem::putFileInfo($this->path, array('etag'=> $propertyValue));
- } elseif( strcmp( $propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0 ) {
+ } else {
+ if (strcmp($propertyName, self::GETETAG_PROPERTYNAME) === 0) {
+ \OC\Files\Filesystem::putFileInfo($this->path, array('etag' => $propertyValue));
+ } elseif (strcmp($propertyName, self::LASTMODIFIED_PROPERTYNAME) === 0) {
$this->touch($propertyValue);
} else {
- if(!array_key_exists( $propertyName, $existing )) {
- $query = OC_DB::prepare( 'INSERT INTO `*PREFIX*properties`'
- .' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)' );
- $query->execute( array( OC_User::getUser(), $this->path, $propertyName,$propertyValue ));
+ if (!array_key_exists($propertyName, $existing)) {
+ $query = OC_DB::prepare('INSERT INTO `*PREFIX*properties`'
+ . ' (`userid`,`propertypath`,`propertyname`,`propertyvalue`) VALUES(?,?,?,?)');
+ $query->execute(array(OC_User::getUser(), $this->path, $propertyName, $propertyValue));
} else {
- $query = OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'
- .' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?' );
- $query->execute( array( $propertyValue,OC_User::getUser(), $this->path, $propertyName ));
+ $query = OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertyvalue` = ?'
+ . ' WHERE `userid` = ? AND `propertypath` = ? AND `propertyname` = ?');
+ $query->execute(array($propertyValue, OC_User::getUser(), $this->path, $propertyName));
}
}
}
@@ -202,9 +180,9 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* removes all properties for this node and user
*/
public function removeProperties() {
- $query = OC_DB::prepare( 'DELETE FROM `*PREFIX*properties`'
- .' WHERE `userid` = ? AND `propertypath` = ?' );
- $query->execute( array( OC_User::getUser(), $this->path));
+ $query = OC_DB::prepare('DELETE FROM `*PREFIX*properties`'
+ . ' WHERE `userid` = ? AND `propertypath` = ?');
+ $query->execute(array(OC_User::getUser(), $this->path));
$this->setPropertyCache(null);
}
@@ -222,29 +200,23 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
if (is_null($this->property_cache)) {
$sql = 'SELECT * FROM `*PREFIX*properties` WHERE `userid` = ? AND `propertypath` = ?';
- $result = OC_DB::executeAudited( $sql, array( OC_User::getUser(), $this->path ) );
+ $result = OC_DB::executeAudited($sql, array(OC_User::getUser(), $this->path));
$this->property_cache = array();
- while( $row = $result->fetchRow()) {
+ while ($row = $result->fetchRow()) {
$this->property_cache[$row['propertyname']] = $row['propertyvalue'];
}
- // Don't call the static getETagPropertyForPath, its result is not cached
- $this->getFileinfoCache();
- if ($this->fileinfo_cache['etag']) {
- $this->property_cache[self::GETETAG_PROPERTYNAME] = '"'.$this->fileinfo_cache['etag'].'"';
- } else {
- $this->property_cache[self::GETETAG_PROPERTYNAME] = null;
- }
+ $this->property_cache[self::GETETAG_PROPERTYNAME] = '"' . $this->info->getEtag() . '"';
}
// if the array was empty, we need to return everything
- if(count($properties) == 0) {
+ if (count($properties) == 0) {
return $this->property_cache;
}
$props = array();
- foreach($properties as $property) {
+ foreach ($properties as $property) {
if (isset($this->property_cache[$property])) {
$props[$property] = $this->property_cache[$property];
}
@@ -254,35 +226,12 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
}
/**
- * Returns the ETag surrounded by double-quotes for this path.
- * @param string $path Path of the file
- * @return string|null Returns null if the ETag can not effectively be determined
- */
- protected function getETagPropertyForPath($path) {
- $data = $this->getFS()->getFileInfo($path);
- if (isset($data['etag'])) {
- return '"'.$data['etag'].'"';
- }
- return null;
- }
-
- protected function getFS() {
- if (is_null($this->fileView)) {
- $this->fileView = \OC\Files\Filesystem::getView();
- }
- return $this->fileView;
- }
-
- /**
* @return string|null
*/
- public function getFileId()
- {
- $this->getFileinfoCache();
-
- if (isset($this->fileinfo_cache['fileid'])) {
+ public function getFileId() {
+ if ($this->info->getId()) {
$instanceId = OC_Util::getInstanceId();
- $id = sprintf('%08d', $this->fileinfo_cache['fileid']);
+ $id = sprintf('%08d', $this->info->getId());
return $id . $instanceId;
}
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index 2956f608380..35cc1679ab6 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -8,25 +8,45 @@
namespace OC\Connector\Sabre;
+use OC\Files\FileInfo;
use OC\Files\Filesystem;
class ObjectTree extends \Sabre_DAV_ObjectTree {
/**
- * keep this public to allow mock injection during unit test
- *
* @var \OC\Files\View
*/
- public $fileView;
+ protected $fileView;
+
+ /**
+ * Creates the object
+ *
+ * This method expects the rootObject to be passed as a parameter
+ */
+ public function __construct() {
+ }
+
+ /**
+ * @param \Sabre_DAV_ICollection $rootNode
+ * @param \OC\Files\View $view
+ */
+ public function init(\Sabre_DAV_ICollection $rootNode, \OC\Files\View $view) {
+ $this->rootNode = $rootNode;
+ $this->fileView = $view;
+ }
/**
* Returns the INode object for the requested path
*
* @param string $path
+ * @throws \Sabre_DAV_Exception_ServiceUnavailable
* @throws \Sabre_DAV_Exception_NotFound
* @return \Sabre_DAV_INode
*/
public function getNodeForPath($path) {
+ if (!$this->fileView) {
+ throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup');
+ }
$path = trim($path, '/');
if (isset($this->cache[$path])) {
@@ -40,31 +60,34 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
// read from storage
- $absPath = $this->getFileView()->getAbsolutePath($path);
+ $absPath = $this->fileView->getAbsolutePath($path);
list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath);
if ($storage) {
+ /**
+ * @var \OC\Files\Storage\Storage $storage
+ */
$scanner = $storage->getScanner($internalPath);
// get data directly
- $info = $scanner->getData($internalPath);
+ $data = $scanner->getData($internalPath);
+ $info = new FileInfo($absPath, $storage, $internalPath, $data);
+ } else {
+ $info = null;
}
- }
- else {
+ } else {
// read from cache
- $info = $this->getFileView()->getFileInfo($path);
+ $info = $this->fileView->getFileInfo($path);
}
if (!$info) {
throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
}
- if ($info['mimetype'] === 'httpd/unix-directory') {
- $node = new \OC_Connector_Sabre_Directory($path);
+ if ($info->getType() === 'dir') {
+ $node = new \OC_Connector_Sabre_Directory($this->fileView, $info);
} else {
- $node = new \OC_Connector_Sabre_File($path);
+ $node = new \OC_Connector_Sabre_File($this->fileView, $info);
}
- $node->setFileinfoCache($info);
-
$this->cache[$path] = $node;
return $node;
@@ -75,10 +98,15 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
*
* @param string $sourcePath The path to the file which should be moved
* @param string $destinationPath The full destination path, so not just the destination parent node
+ * @throws \Sabre_DAV_Exception_BadRequest
+ * @throws \Sabre_DAV_Exception_ServiceUnavailable
* @throws \Sabre_DAV_Exception_Forbidden
* @return int
*/
public function move($sourcePath, $destinationPath) {
+ if (!$this->fileView) {
+ throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup');
+ }
$sourceNode = $this->getNodeForPath($sourcePath);
if ($sourceNode instanceof \Sabre_DAV_ICollection and $this->nodeExists($destinationPath)) {
@@ -94,19 +122,21 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
}
// check update privileges
- $fs = $this->getFileView();
- if (!$fs->isUpdatable($sourcePath) && !$isShareMountPoint) {
+ if (!$this->fileView->isUpdatable($sourcePath) && !$isShareMountPoint) {
throw new \Sabre_DAV_Exception_Forbidden();
}
if ($sourceDir !== $destinationDir) {
// for a full move we need update privileges on sourcePath and sourceDir as well as destinationDir
- if (!$fs->isUpdatable($sourceDir)) {
+ if (ltrim($destinationDir, '/') === '') {
throw new \Sabre_DAV_Exception_Forbidden();
}
- if (!$fs->isUpdatable($destinationDir)) {
+ if (!$this->fileView->isUpdatable($sourceDir)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
- if (!$fs->isDeletable($sourcePath)) {
+ if (!$this->fileView->isUpdatable($destinationDir)) {
+ throw new \Sabre_DAV_Exception_Forbidden();
+ }
+ if (!$this->fileView->isDeletable($sourcePath)) {
throw new \Sabre_DAV_Exception_Forbidden();
}
}
@@ -116,15 +146,15 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
throw new \Sabre_DAV_Exception_BadRequest();
}
- $renameOkay = $fs->rename($sourcePath, $destinationPath);
+ $renameOkay = $this->fileView->rename($sourcePath, $destinationPath);
if (!$renameOkay) {
throw new \Sabre_DAV_Exception_Forbidden('');
}
// update properties
- $query = \OC_DB::prepare( 'UPDATE `*PREFIX*properties` SET `propertypath` = ?'
- .' WHERE `userid` = ? AND `propertypath` = ?' );
- $query->execute( array( $destinationPath, \OC_User::getUser(), $sourcePath ));
+ $query = \OC_DB::prepare('UPDATE `*PREFIX*properties` SET `propertypath` = ?'
+ . ' WHERE `userid` = ? AND `propertypath` = ?');
+ $query->execute(array(\OC\Files\Filesystem::normalizePath($destinationPath), \OC_User::getUser(), \OC\Files\Filesystem::normalizePath($sourcePath)));
$this->markDirty($sourceDir);
$this->markDirty($destinationDir);
@@ -139,20 +169,24 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
*
* @param string $source
* @param string $destination
+ * @throws \Sabre_DAV_Exception_ServiceUnavailable
* @return void
*/
public function copy($source, $destination) {
+ if (!$this->fileView) {
+ throw new \Sabre_DAV_Exception_ServiceUnavailable('filesystem not setup');
+ }
- if (Filesystem::is_file($source)) {
- Filesystem::copy($source, $destination);
+ if ($this->fileView->is_file($source)) {
+ $this->fileView->copy($source, $destination);
} else {
- Filesystem::mkdir($destination);
- $dh = Filesystem::opendir($source);
- if(is_resource($dh)) {
- while (($subnode = readdir($dh)) !== false) {
+ $this->fileView->mkdir($destination);
+ $dh = $this->fileView->opendir($source);
+ if (is_resource($dh)) {
+ while (($subNode = readdir($dh)) !== false) {
- if ($subnode == '.' || $subnode == '..') continue;
- $this->copy($source . '/' . $subnode, $destination . '/' . $subnode);
+ if ($subNode == '.' || $subNode == '..') continue;
+ $this->copy($source . '/' . $subNode, $destination . '/' . $subNode);
}
}
@@ -161,14 +195,4 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
list($destinationDir,) = \Sabre_DAV_URLUtil::splitPath($destination);
$this->markDirty($destinationDir);
}
-
- /**
- * @return \OC\Files\View
- */
- public function getFileView() {
- if (is_null($this->fileView)) {
- $this->fileView = \OC\Files\Filesystem::getView();
- }
- return $this->fileView;
- }
}
diff --git a/lib/private/connector/sabre/quotaplugin.php b/lib/private/connector/sabre/quotaplugin.php
index 227e684741c..1e73e1645c3 100644
--- a/lib/private/connector/sabre/quotaplugin.php
+++ b/lib/private/connector/sabre/quotaplugin.php
@@ -10,6 +10,11 @@
class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
/**
+ * @var \OC\Files\View
+ */
+ private $view;
+
+ /**
* Reference to main server object
*
* @var Sabre_DAV_Server
@@ -17,11 +22,11 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
private $server;
/**
- * is kept public to allow overwrite for unit testing
- *
- * @var \OC\Files\View
+ * @param \OC\Files\View $view
*/
- public $fileView;
+ public function __construct($view) {
+ $this->view = $view;
+ }
/**
* This initializes the plugin.
@@ -45,22 +50,23 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
/**
* This method is called before any HTTP method and validates there is enough free space to store the file
*
- * @throws Sabre_DAV_Exception
* @param string $uri
+ * @param null $data
+ * @throws Sabre_DAV_Exception_InsufficientStorage
* @return bool
*/
public function checkQuota($uri, $data = null) {
$length = $this->getLength();
if ($length) {
- if (substr($uri, 0, 1)!=='/') {
- $uri='/'.$uri;
+ if (substr($uri, 0, 1) !== '/') {
+ $uri = '/' . $uri;
}
list($parentUri, $newName) = Sabre_DAV_URLUtil::splitPath($uri);
$req = $this->server->httpRequest;
if ($req->getHeader('OC-Chunked')) {
$info = OC_FileChunking::decodeName($newName);
$chunkHandler = new OC_FileChunking($info);
- // substract the already uploaded size to see whether
+ // subtract the already uploaded size to see whether
// there is still enough space for the remaining chunks
$length -= $chunkHandler->getCurrentSize();
}
@@ -75,8 +81,7 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
return true;
}
- public function getLength()
- {
+ public function getLength() {
$req = $this->server->httpRequest;
$length = $req->getHeader('X-Expected-Entity-Length');
if (!$length) {
@@ -95,14 +100,8 @@ class OC_Connector_Sabre_QuotaPlugin extends Sabre_DAV_ServerPlugin {
* @param $parentUri
* @return mixed
*/
- public function getFreeSpace($parentUri)
- {
- if (is_null($this->fileView)) {
- // initialize fileView
- $this->fileView = \OC\Files\Filesystem::getView();
- }
-
- $freeSpace = $this->fileView->free_space($parentUri);
+ public function getFreeSpace($parentUri) {
+ $freeSpace = $this->view->free_space($parentUri);
return $freeSpace;
}
}
diff --git a/lib/private/files/cache/scanner.php b/lib/private/files/cache/scanner.php
index 79159724d16..c0bdde06a75 100644
--- a/lib/private/files/cache/scanner.php
+++ b/lib/private/files/cache/scanner.php
@@ -115,11 +115,12 @@ class Scanner extends BasicEmitter {
}
if ($reuseExisting) {
// prevent empty etag
- $etag = $cacheData['etag'];
- $propagateETagChange = false;
- if (empty($etag)) {
+ if (empty($cacheData['etag'])) {
$etag = $data['etag'];
$propagateETagChange = true;
+ } else {
+ $etag = $cacheData['etag'];
+ $propagateETagChange = false;
}
// only reuse data if the file hasn't explicitly changed
if (isset($data['storage_mtime']) && isset($cacheData['storage_mtime']) && $data['storage_mtime'] === $cacheData['storage_mtime']) {