]> source.dussan.org Git - nextcloud-server.git/commitdiff
added unencrypted file size to file cache
authorFlorin Peter <github@florin-peter.de>
Thu, 25 Apr 2013 13:20:06 +0000 (15:20 +0200)
committerFlorin Peter <github@florin-peter.de>
Thu, 25 Apr 2013 13:20:06 +0000 (15:20 +0200)
improved file size calculation and speeds

apps/files_encryption/lib/proxy.php
apps/files_encryption/lib/stream.php
db_structure.xml
lib/files/cache/cache.php

index b805ec648d45877f30d556fcffdaccd5e90a43bb..c07b9a8a7aad1aa0784802dbe1a2370144262775 100644 (file)
@@ -108,7 +108,8 @@ class Proxy extends \OC_FileProxy {
                                $size = strlen( $data );
                                
                                // Disable encryption proxy to prevent recursive calls
-                               \OC_FileProxy::$enabled = false;
+                $proxyStatus = \OC_FileProxy::$enabled;
+                \OC_FileProxy::$enabled = false;
                                
                                // Check if there is an existing key we can reuse
                                if ( $encKeyfile = Keymanager::getFileKey( $rootView, $userId, $filePath ) ) {
@@ -135,10 +136,8 @@ class Proxy extends \OC_FileProxy {
 
                 // Fetch public keys for all users who will share the file
                                $publicKeys = Keymanager::getPublicKeys( $rootView, $uniqueUserIds );
-                               
-                               \OC_FileProxy::$enabled = false;
-                               
-                               // Encrypt plain keyfile to multiple sharefiles
+
+                // Encrypt plain keyfile to multiple sharefiles
                                $multiEncrypted = Crypt::multiKeyEncrypt( $plainKey, $publicKeys );
                                
                                // Save sharekeys to user folders
@@ -157,7 +156,7 @@ class Proxy extends \OC_FileProxy {
                                \OC\Files\Filesystem::putFileInfo( $path, array( 'encrypted'=>true, 'size' => $size ), '' );
                                
                                // Re-enable proxy - our work is done
-                               \OC_FileProxy::$enabled = true;
+                               \OC_FileProxy::$enabled = $proxyStatus;
                                
                        }
                }
@@ -182,9 +181,10 @@ class Proxy extends \OC_FileProxy {
        
                // TODO check for existing key file and reuse it if possible to avoid problems with versioning etc.
                // Disable encryption proxy to prevent recursive calls
-               \OC_FileProxy::$enabled = false;
-               
-               // If data is a catfile
+        $proxyStatus = \OC_FileProxy::$enabled;
+        \OC_FileProxy::$enabled = false;
+
+        // If data is a catfile
                if ( 
                        Crypt::mode() == 'server' 
                        && Crypt::isCatfileContent( $data ) // TODO: Do we really need this check? Can't we assume it is properly encrypted?
@@ -215,7 +215,7 @@ class Proxy extends \OC_FileProxy {
                        
                }
                
-               \OC_FileProxy::$enabled = true;
+               \OC_FileProxy::$enabled = $proxyStatus;
                
                if ( ! isset( $plainData ) ) {
                
@@ -240,7 +240,8 @@ class Proxy extends \OC_FileProxy {
                $path = Keymanager::fixPartialFilePath( $path );
        
                // Disable encryption proxy to prevent recursive calls
-               \OC_FileProxy::$enabled = false;
+        $proxyStatus = \OC_FileProxy::$enabled;
+        \OC_FileProxy::$enabled = false;
                
                $view = new \OC_FilesystemView( '/' );
 
@@ -265,7 +266,7 @@ class Proxy extends \OC_FileProxy {
                                
                }
                
-               \OC_FileProxy::$enabled = true;
+               \OC_FileProxy::$enabled = $proxyStatus;
                
                // If we don't return true then file delete will fail; better
                // to leave orphaned keyfiles than to disallow file deletion
@@ -282,6 +283,7 @@ class Proxy extends \OC_FileProxy {
     {
 
         // Disable encryption proxy to prevent recursive calls
+        $proxyStatus = \OC_FileProxy::$enabled;
         \OC_FileProxy::$enabled = false;
 
         $view = new \OC_FilesystemView('/');
@@ -318,7 +320,7 @@ class Proxy extends \OC_FileProxy {
         // Rename keyfile so it isn't orphaned
         $result = $view->rename($oldKeyfilePath, $newKeyfilePath);
 
-        \OC_FileProxy::$enabled = true;
+        \OC_FileProxy::$enabled = $proxyStatus;
 
         return $result;
 
@@ -337,9 +339,10 @@ class Proxy extends \OC_FileProxy {
                $path_f = implode( '/', array_slice( $path_split, 3 ) );
                
                // Disable encryption proxy to prevent recursive calls
-               \OC_FileProxy::$enabled = false;
-               
-               $meta = stream_get_meta_data( $result );
+        $proxyStatus = \OC_FileProxy::$enabled;
+        \OC_FileProxy::$enabled = false;
+
+        $meta = stream_get_meta_data( $result );
                
                $view = new \OC_FilesystemView( '' );
                
@@ -369,13 +372,13 @@ class Proxy extends \OC_FileProxy {
                
                // NOTE: this is the case for new files saved via WebDAV
                
-                       if ( 
-                       $view->file_exists( $path ) 
-                       and $view->filesize( $path ) > 0 
-                       ) {
-                               $x = $view->file_get_contents( $path );
-                               
-                               $tmp = tmpfile();
+//                     if (
+//                     $view->file_exists( $path )
+//                     and $view->filesize( $path ) > 0
+//                     ) {
+//                             $x = $view->file_get_contents( $path );
+//
+//                             $tmp = tmpfile();
                                
 //                             // Make a temporary copy of the original file
 //                             \OCP\Files::streamCopy( $result, $tmp );
@@ -387,14 +390,14 @@ class Proxy extends \OC_FileProxy {
 //                             
 //                             fclose( $tmp );
                        
-                       }
+//                     }
 
             $result = fopen( 'crypt://'.$path_f, $meta['mode'] );
                
                }
                
                // Re-enable the proxy
-               \OC_FileProxy::$enabled = true;
+               \OC_FileProxy::$enabled = $proxyStatus;
                
                return $result;
        
@@ -417,15 +420,15 @@ class Proxy extends \OC_FileProxy {
         // if path is a folder do nothing
         if(is_array($data) && array_key_exists('size', $data)) {
             // Disable encryption proxy to prevent recursive calls
+            $proxyStatus = \OC_FileProxy::$enabled;
             \OC_FileProxy::$enabled = false;
 
+
             // get file size
             $data['size'] = self::postFileSize($path, $data['size']);
 
             // Re-enable the proxy
-            \OC_FileProxy::$enabled = true;
-
-            trigger_error('postGetFileInfo '.$path.' size: '.$data['size']);
+            \OC_FileProxy::$enabled = $proxyStatus;
         }
 
         return $data;
@@ -437,7 +440,7 @@ class Proxy extends \OC_FileProxy {
                
                        $cached = \OC\Files\Filesystem::getFileInfo( $path, '' );
                        
-                       $data['size'] = $cached['size'];
+                       $data['size'] = $cached['unencrypted_size'];
                        
                }
                
@@ -453,56 +456,20 @@ class Proxy extends \OC_FileProxy {
             return $size;
         }
 
+        $path = Keymanager::fixPartialFilePath( $path );
+
         // Reformat path for use with OC_FSV
         $path_split = explode('/', $path);
         $path_f = implode('/', array_slice($path_split, 3));
 
-        $userId = \OCP\User::getUser();
-        $util = new Util( $view, $userId );
-
-
-        // FIXME: is there a better solution to check if file belongs to files path?
-        // only get file size if file is in 'files' path
-        if (count($path_split) >= 2  && $path_split[2] == 'files' && $util->isEncryptedPath($path)) {
-
-            // Disable encryption proxy to prevent recursive calls
-            \OC_FileProxy::$enabled = false;
-
-            // open stream
-            $result = fopen('crypt://' . $path_f, "r");
-
-            if(is_resource($result)) {
-                // don't trust the given size, allways get the size from filesystem
-                $size = $view->filesize($path);
-
-                // calculate last chunk nr
-                $lastChunckNr = floor($size / 8192);
-
-                // calculate last chunk position
-                $lastChunckPos = ($lastChunckNr * 8192);
-
-                // seek to end
-                fseek($result, $lastChunckPos);
-
-                // get the content of the last chunck
-                $lastChunkContent = fgets($result);
-
-                // calc the real file size with the size of the last chunk
-                $realSize = (($lastChunckNr * 6126) + strlen($lastChunkContent));
-
-                // set the size
-                $size = $realSize;
-            }
-
-            // enable proxy
-            \OC_FileProxy::$enabled = true;
-
-            return $size;
+        // get file info from database/cache
+        $fileInfo = \OC\Files\Filesystem::getFileInfo($path_f);
 
+        // if file is encrypted return real file size
+        if(is_array($fileInfo) && $fileInfo['encrypted'] == 1) {
+            return $fileInfo['unencrypted_size'];
         } else {
-
-            return $size;
-
+            return $fileInfo['size'];
         }
        }
 }
index 9a37c3b08ee137c64ac9c4d0f0125d0f0d296c3a..7e42627f8ca07f2ffe908ab6c4f115c83e8a25ac 100644 (file)
@@ -64,6 +64,7 @@ class Stream {
        private $count;
        private $writeCache;
        public $size;
+    public $unencryptedSize;
        private $publicKey;
        private $keyfile;
        private $encKeyfile;
@@ -105,6 +106,7 @@ class Stream {
                } else {
 
             // Disable fileproxies so we can get the file size and open the source file without recursive encryption
+            $proxyStatus = \OC_FileProxy::$enabled;
             \OC_FileProxy::$enabled = false;
 
                        if ( 
@@ -116,6 +118,7 @@ class Stream {
 
                                // We're writing a new file so start write counter with 0 bytes
                                $this->size = 0;
+                $this->unencryptedSize = 0;
 
                        } else {
                                
@@ -129,7 +132,7 @@ class Stream {
                        
                        $this->handle = $this->rootView->fopen( $this->rawPath, $mode );
                        
-                       \OC_FileProxy::$enabled = true;
+                       \OC_FileProxy::$enabled = $proxyStatus;
 
                        if ( ! is_resource( $this->handle ) ) {
 
@@ -301,7 +304,7 @@ class Stream {
                // automatically attempted when the file is written to disk - 
                // we are handling that separately here and we don't want to 
                // get into an infinite loop
-               \OC_FileProxy::$enabled = false;
+               //\OC_FileProxy::$enabled = false;
                
                // Get the length of the unencrypted data that we are handling
                $length = strlen( $data );
@@ -438,7 +441,8 @@ class Stream {
                }
                
                $this->size = max( $this->size, $pointer + $length );
-               
+        $this->unencryptedSize += $length;
+
                return $length;
 
        }
@@ -501,9 +505,7 @@ class Stream {
                $this->meta['mode']!='r' 
                and $this->meta['mode']!='rb' 
                ) {
-                       
-                       \OC\Files\Filesystem::putFileInfo( $this->relPath, array( 'encrypted' => true, 'size' => $this->size ), '' );
-
+                       \OC\Files\Filesystem::putFileInfo( $this->relPath, array( 'encrypted' => 1, 'size' => $this->size, 'unencrypted_size' => $this->unencryptedSize ), '' );
                }
 
                return fclose( $this->handle );
index dce90697b1c5952bd6ac546aabde6d08700fed47..366f51a82d0c11578c1259c98b0dfa0465ab5a1f 100644 (file)
                                <length>4</length>
                        </field>
 
+            <field>
+                <name>unencrypted_size</name>
+                <type>integer</type>
+                <default></default>
+                <notnull>true</notnull>
+                <length>8</length>
+            </field>
+
                        <field>
                                <name>etag</name>
                                <type>text</type>
index 71b70abe3fec5f586cf3f191e3fc8bc6b7d97c39..4e32ff2ba8a374a29f2c065e948c82501b7a115c 100644 (file)
@@ -117,7 +117,7 @@ class Cache {
                        $params = array($file);
                }
                $query = \OC_DB::prepare(
-                       'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+                       'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
                         FROM `*PREFIX*filecache` ' . $where);
                $result = $query->execute($params);
                $data = $result->fetchRow();
@@ -133,6 +133,7 @@ class Cache {
                        $data['size'] = (int)$data['size'];
                        $data['mtime'] = (int)$data['mtime'];
                        $data['encrypted'] = (bool)$data['encrypted'];
+            $data['unencrypted_size'] = (int)$data['unencrypted_size'];
                        $data['storage'] = $this->storageId;
                        $data['mimetype'] = $this->getMimetype($data['mimetype']);
                        $data['mimepart'] = $this->getMimetype($data['mimepart']);
@@ -151,7 +152,7 @@ class Cache {
                $fileId = $this->getId($folder);
                if ($fileId > -1) {
                        $query = \OC_DB::prepare(
-                               'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+                               'SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
                                 FROM `*PREFIX*filecache` WHERE parent = ? ORDER BY `name` ASC');
                        $result = $query->execute(array($fileId));
                        $files = $result->fetchAll();
@@ -234,7 +235,7 @@ class Cache {
         * @return array
         */
        function buildParts(array $data) {
-               $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'etag');
+               $fields = array('path', 'parent', 'name', 'mimetype', 'size', 'mtime', 'encrypted', 'unencrypted_size', 'etag');
                $params = array();
                $queryParts = array();
                foreach ($data as $name => $value) {
@@ -391,7 +392,7 @@ class Cache {
         */
        public function search($pattern) {
                $query = \OC_DB::prepare('
-                       SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+                       SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
                        FROM `*PREFIX*filecache` WHERE `name` LIKE ? AND `storage` = ?'
                );
                $result = $query->execute(array($pattern, $this->numericId));
@@ -417,7 +418,7 @@ class Cache {
                        $where = '`mimepart` = ?';
                }
                $query = \OC_DB::prepare('
-                       SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `etag`
+                       SELECT `fileid`, `storage`, `path`, `parent`, `name`, `mimetype`, `mimepart`, `size`, `mtime`, `encrypted`, `unencrypted_size`, `etag`
                        FROM `*PREFIX*filecache` WHERE ' . $where . ' AND `storage` = ?'
                );
                $mimetype = $this->getMimetypeId($mimetype);