]> source.dussan.org Git - nextcloud-server.git/commitdiff
Merge branch 'master' into fixing-4546-master
authorThomas Müller <thomas.mueller@tmit.eu>
Mon, 7 Oct 2013 15:47:54 +0000 (17:47 +0200)
committerThomas Müller <thomas.mueller@tmit.eu>
Mon, 7 Oct 2013 15:47:54 +0000 (17:47 +0200)
Conflicts:
lib/private/connector/sabre/directory.php

1  2 
lib/private/cache/file.php
lib/private/connector/sabre/directory.php
lib/private/filechunking.php

index 0000000000000000000000000000000000000000,2ab914d17b891b421fd573a1ad98edc233d52a99..b0738d2a92ba20e2848729399adea7c2ba71f550
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,118 +1,136 @@@
+ <?php
+ /**
+  * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+  * This file is licensed under the Affero General Public License version 3 or
+  * later.
+  * See the COPYING-README file.
+  */
+ namespace OC\Cache;
+ class File {
+       protected $storage;
+       protected function getStorage() {
+               if (isset($this->storage)) {
+                       return $this->storage;
+               }
+               if(\OC_User::isLoggedIn()) {
+                       \OC\Files\Filesystem::initMountPoints(\OC_User::getUser());
+                       $subdir = 'cache';
+                       $view = new \OC\Files\View('/' . \OC_User::getUser());
+                       if(!$view->file_exists($subdir)) {
+                               $view->mkdir($subdir);
+                       }
+                       $this->storage = new \OC\Files\View('/' . \OC_User::getUser().'/'.$subdir);
+                       return $this->storage;
+               }else{
+                       \OC_Log::write('core', 'Can\'t get cache storage, user not logged in', \OC_Log::ERROR);
+                       return false;
+               }
+       }
+       public function get($key) {
+               $result = null;
+               $proxyStatus = \OC_FileProxy::$enabled;
+               \OC_FileProxy::$enabled = false;
+               if ($this->hasKey($key)) {
+                       $storage = $this->getStorage();
+                       $result = $storage->file_get_contents($key);
+               }
+               \OC_FileProxy::$enabled = $proxyStatus;
+               return $result;
+       }
++      /**
++       * Returns the size of the stored/cached data
++       *
++       * @param $key
++       * @return int
++       */
++      public function size($key) {
++              $result = 0;
++              $proxyStatus = \OC_FileProxy::$enabled;
++              \OC_FileProxy::$enabled = false;
++              if ($this->hasKey($key)) {
++                      $storage = $this->getStorage();
++                      $result = $storage->filesize($key);
++              }
++              \OC_FileProxy::$enabled = $proxyStatus;
++              return $result;
++      }
++
+       public function set($key, $value, $ttl=0) {
+               $storage = $this->getStorage();
+               $result = false;
+               $proxyStatus = \OC_FileProxy::$enabled;
+               \OC_FileProxy::$enabled = false;
+               if ($storage and $storage->file_put_contents($key, $value)) {
+                       if ($ttl === 0) {
+                               $ttl = 86400; // 60*60*24
+                       }
+                       $result = $storage->touch($key, time() + $ttl);
+               }
+               \OC_FileProxy::$enabled = $proxyStatus;
+               return $result;
+       }
+       public function hasKey($key) {
+               $storage = $this->getStorage();
+               if ($storage && $storage->is_file($key)) {
+                       $mtime = $storage->filemtime($key);
+                       if ($mtime < time()) {
+                               $storage->unlink($key);
+                               return false;
+                       }
+                       return true;
+               }
+               return false;
+       }
+       public function remove($key) {
+               $storage = $this->getStorage();
+               if(!$storage) {
+                       return false;
+               }
+               return $storage->unlink($key);
+       }
+       public function clear($prefix='') {
+               $storage = $this->getStorage();
+               if($storage and $storage->is_dir('/')) {
+                       $dh=$storage->opendir('/');
+                       if(is_resource($dh)) {
+                               while (($file = readdir($dh)) !== false) {
+                                       if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)) {
+                                               $storage->unlink('/'.$file);
+                                       }
+                               }
+                       }
+               }
+               return true;
+       }
+       public function gc() {
+               $storage = $this->getStorage();
+               if($storage and $storage->is_dir('/')) {
+                       $now = time();
+                       $dh=$storage->opendir('/');
+                       if(!is_resource($dh)) {
+                               return null;
+                       }
+                       while (($file = readdir($dh)) !== false) {
+                               if($file!='.' and $file!='..') {
+                                       $mtime = $storage->filemtime('/'.$file);
+                                       if ($mtime < $now) {
+                                               $storage->unlink('/'.$file);
+                                       }
+                               }
+                       }
+               }
+       }
+       public static function loginListener() {
+               $c = new self();
+               $c->gc();
+       }
+ }
index 0000000000000000000000000000000000000000,af0dfd70f08e32670285c5e5ba5544de5091beda..531b0a807bf4930efa2abc1ed24474b7837c0729
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,218 +1,218 @@@
 -
+ <?php
+ /**
+  * ownCloud
+  *
+  * @author Jakob Sack
+  * @copyright 2011 Jakob Sack kde@jakobsack.de
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+  * License as published by the Free Software Foundation; either
+  * version 3 of the License, or any later version.
+  *
+  * This library is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  * GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+  *
+  * You should have received a copy of the GNU Affero General Public
+  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+  *
+  */
+ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sabre_DAV_ICollection, Sabre_DAV_IQuota {
+       /**
+        * Creates a new file in the directory
+        *
+        * 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
+        * of the new file here.
+        *
+        * The returned ETag must be surrounded by double-quotes (The quotes should
+        * be part of the actual string).
+        *
+        * If you cannot accurately determine the ETag, you should not return it.
+        * If you don't store the file exactly as-is (you're transforming it
+        * somehow) you should also not return an ETag.
+        *
+        * This means that if a subsequent GET to this new file does not exactly
+        * return the same contents of what was submitted here, you are strongly
+        * recommended to omit the ETag.
+        *
+        * @param string $name Name of the file
+        * @param resource|string $data Initial payload
+        * @throws Sabre_DAV_Exception_Forbidden
+        * @return null|string
+        */
+       public function createFile($name, $data = null) {
+               if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+                       throw new \Sabre_DAV_Exception_Forbidden();
+               }
+               $path = $this->path . '/' . $name;
+               $node = new OC_Connector_Sabre_File($path);
+               return $node->put($data);
+       }
+       /**
+        * Creates a new subdirectory
+        *
+        * @param string $name
+        * @throws Sabre_DAV_Exception_Forbidden
+        * @return void
+        */
+       public function createDirectory($name) {
+               if (!\OC\Files\Filesystem::isCreatable($this->path)) {
+                       throw new \Sabre_DAV_Exception_Forbidden();
+               }
+               $newPath = $this->path . '/' . $name;
+               if(!\OC\Files\Filesystem::mkdir($newPath)) {
+                       throw new Sabre_DAV_Exception_Forbidden('Could not create directory '.$newPath);
+               }
+       }
+       /**
+        * Returns a specific child node, referenced by its name
+        *
+        * @param string $name
+        * @throws Sabre_DAV_Exception_FileNotFound
+        * @return Sabre_DAV_INode
+        */
+       public function getChild($name, $info = null) {
+               $path = $this->path . '/' . $name;
+               if (is_null($info)) {
+                       $info = \OC\Files\Filesystem::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);
+               } else {
+                       $node = new OC_Connector_Sabre_File($path);
+               }
+               $node->setFileinfoCache($info);
+               return $node;
+       }
+       /**
+        * Returns an array with all the child nodes
+        *
+        * @return Sabre_DAV_INode[]
+        */
+       public function getChildren() {
+               $folder_content = \OC\Files\Filesystem::getDirectoryContent($this->path);
+               $paths = array();
+               foreach($folder_content as $info) {
+                       $paths[] = $this->path.'/'.$info['name'];
+                       $properties[$this->path.'/'.$info['name']][self::GETETAG_PROPERTYNAME] = '"' . $info['etag'] . '"';
+               }
+               if(count($paths)>0) {
+                       //
+                       // the number of arguments within IN conditions are limited in most databases
+                       // we chunk $paths into arrays of 200 items each to meet this criteria
+                       //
+                       $chunks = array_chunk($paths, 200, false);
+                       foreach ($chunks as $pack) {
+                               $placeholders = join(',', array_fill(0, count($pack), '?'));
+                               $query = OC_DB::prepare( 'SELECT * FROM `*PREFIX*properties`'
+                                       .' WHERE `userid` = ?' . ' AND `propertypath` IN ('.$placeholders.')' );
+                               array_unshift($pack, OC_User::getUser()); // prepend userid
+                               $result = $query->execute( $pack );
+                               while($row = $result->fetchRow()) {
+                                       $propertypath = $row['propertypath'];
+                                       $propertyname = $row['propertyname'];
+                                       $propertyvalue = $row['propertyvalue'];
+                                       if($propertyname !== self::GETETAG_PROPERTYNAME) {
+                                               $properties[$propertypath][$propertyname] = $propertyvalue;
+                                       }
+                               }
+                       }
+               }
+               $nodes = array();
+               foreach($folder_content as $info) {
+                       $node = $this->getChild($info['name'], $info);
+                       $node->setPropertyCache($properties[$this->path.'/'.$info['name']]);
+                       $nodes[] = $node;
+               }
+               return $nodes;
+       }
+       /**
+        * Checks if a child exists.
+        *
+        * @param string $name
+        * @return bool
+        */
+       public function childExists($name) {
+               $path = $this->path . '/' . $name;
+               return \OC\Files\Filesystem::file_exists($path);
+       }
+       /**
+        * Deletes all files in this directory, and then itself
+        *
+        * @return void
+        * @throws Sabre_DAV_Exception_Forbidden
+        */
+       public function delete() {
+               if (!\OC\Files\Filesystem::isDeletable($this->path)) {
+                       throw new \Sabre_DAV_Exception_Forbidden();
+               }
+               if ($this->path != "/Shared") {
+                       \OC\Files\Filesystem::rmdir($this->path);
+               }
+       }
+       /**
+        * Returns available diskspace information
+        *
+        * @return array
+        */
+       public function getQuotaInfo() {
+               $storageInfo = OC_Helper::getStorageInfo($this->path);
+               return array(
+                       $storageInfo['used'],
+                       $storageInfo['free']
+               );
+       }
+       /**
+        * Returns a list of properties for this nodes.;
+        *
+        * The properties list is a list of propertynames the client requested,
+        * encoded as xmlnamespace#tagName, for example:
+        * http://www.example.org/namespace#author
+        * If the array is empty, all properties should be returned
+        *
+        * @param array $properties
+        * @return array
+        */
+       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);
+               }
+               return $props;
+       }
++
+ }
index 0000000000000000000000000000000000000000,313a6ee87d2975d6139b2a3a8691a63d6994784e..0dfce696cda7a37057bc853e846a5426477ac653
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,149 +1,170 @@@
 -                      $cache->remove($prefix.$i);
+ <?php
+ /**
+  * Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl>
+  * This file is licensed under the Affero General Public License version 3 or
+  * later.
+  * See the COPYING-README file.
+  */
+ class OC_FileChunking {
+       protected $info;
+       protected $cache;
+       static public function decodeName($name) {
+               preg_match('/(?P<name>.*)-chunking-(?P<transferid>\d+)-(?P<chunkcount>\d+)-(?P<index>\d+)/', $name, $matches);
+               return $matches;
+       }
+       public function __construct($info) {
+               $this->info = $info;
+       }
+       public function getPrefix() {
+               $name = $this->info['name'];
+               $transferid = $this->info['transferid'];
+               return $name.'-chunking-'.$transferid.'-';
+       }
+       protected function getCache() {
+               if (!isset($this->cache)) {
+                       $this->cache = new \OC\Cache\File();
+               }
+               return $this->cache;
+       }
++      /**
++       * Stores the given $data under the given $key - the number of stored bytes is returned
++       *
++       * @param $index
++       * @param $data
++       * @return int
++       */
+       public function store($index, $data) {
+               $cache = $this->getCache();
+               $name = $this->getPrefix().$index;
+               $cache->set($name, $data);
++
++              return $cache->size($name);
+       }
+       public function isComplete() {
+               $prefix = $this->getPrefix();
+               $parts = 0;
+               $cache = $this->getCache();
+               for($i=0; $i < $this->info['chunkcount']; $i++) {
+                       if ($cache->hasKey($prefix.$i)) {
+                               $parts ++;
+                       }
+               }
+               return $parts == $this->info['chunkcount'];
+       }
+       public function assemble($f) {
+               $cache = $this->getCache();
+               $prefix = $this->getPrefix();
+               $count = 0;
+               for($i=0; $i < $this->info['chunkcount']; $i++) {
+                       $chunk = $cache->get($prefix.$i);
+                       $count += fwrite($f, $chunk);
+               }
++
++              $this->cleanup();
+               return $count;
+       }
++      /**
++       * Removes all chunks which belong to this transmission
++       */
++      public function cleanup() {
++              $cache = $this->getCache();
++              $prefix = $this->getPrefix();
++              for($i=0; $i < $this->info['chunkcount']; $i++) {
++                      $cache->remove($prefix.$i);
++              }
++      }
++
+       public function signature_split($orgfile, $input) {
+               $info = unpack('n', fread($input, 2));
+               $blocksize = $info[1];
+               $this->info['transferid'] = mt_rand();
+               $count = 0;
+               $needed = array();
+               $cache = $this->getCache();
+               $prefix = $this->getPrefix();
+               while (!feof($orgfile)) {
+                       $new_md5 = fread($input, 16);
+                       if (feof($input)) {
+                               break;
+                       }
+                       $data = fread($orgfile, $blocksize);
+                       $org_md5 = md5($data, true);
+                       if ($org_md5 == $new_md5) {
+                               $cache->set($prefix.$count, $data);
+                       } else {
+                               $needed[] = $count;
+                       }
+                       $count++;
+               }
+               return array(
+                       'transferid' => $this->info['transferid'],
+                       'needed' => $needed,
+                       'count' => $count,
+               );
+       }
+       public function file_assemble($path) {
+               $absolutePath = \OC\Files\Filesystem::normalizePath(\OC\Files\Filesystem::getView()->getAbsolutePath($path));
+               $data = '';
+               // use file_put_contents as method because that best matches what this function does
+               if (OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data)
+                       && \OC\Files\Filesystem::isValidPath($path)) {
+                       $path = \OC\Files\Filesystem::getView()->getRelativePath($absolutePath);
+                       $exists = \OC\Files\Filesystem::file_exists($path);
+                       $run = true;
+                       if(!$exists) {
+                               OC_Hook::emit(
+                                       \OC\Files\Filesystem::CLASSNAME,
+                                       \OC\Files\Filesystem::signal_create,
+                                       array(
+                                               \OC\Files\Filesystem::signal_param_path => $path,
+                                               \OC\Files\Filesystem::signal_param_run => &$run
+                                       )
+                               );
+                       }
+                       OC_Hook::emit(
+                               \OC\Files\Filesystem::CLASSNAME,
+                               \OC\Files\Filesystem::signal_write,
+                               array(
+                                       \OC\Files\Filesystem::signal_param_path => $path,
+                                       \OC\Files\Filesystem::signal_param_run => &$run
+                               )
+                       );
+                       if(!$run) {
+                               return false;
+                       }
+                       $target = \OC\Files\Filesystem::fopen($path, 'w');
+                       if($target) {
+                               $count = $this->assemble($target);
+                               fclose($target);
+                               if(!$exists) {
+                                       OC_Hook::emit(
+                                               \OC\Files\Filesystem::CLASSNAME,
+                                               \OC\Files\Filesystem::signal_post_create,
+                                               array( \OC\Files\Filesystem::signal_param_path => $path)
+                                       );
+                               }
+                               OC_Hook::emit(
+                                       \OC\Files\Filesystem::CLASSNAME,
+                                       \OC\Files\Filesystem::signal_post_write,
+                                       array( \OC\Files\Filesystem::signal_param_path => $path)
+                               );
+                               OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count);
+                               return $count > 0;
+                       }else{
+                               return false;
+                       }
+               }
+       }
+ }