[Pkg-owncloud-commits] [owncloud] 123/199: Refactor Large File handling code.

David Prévot taffit at moszumanska.debian.org
Sun Jun 1 18:53:17 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch master
in repository owncloud.

commit c8fa1fd68784c48c1df537310f16d6753f79b029
Author: Andreas Fischer <bantu at owncloud.com>
Date:   Sun Feb 9 01:25:33 2014 +0100

    Refactor Large File handling code.
---
 lib/private/files/storage/local.php       |  98 +++-------------------------
 lib/private/files/storage/mappedlocal.php |  53 ++++-----------
 lib/private/largefilehelper.php           | 103 ++++++++++++++++++++++++++++++
 3 files changed, 123 insertions(+), 131 deletions(-)

diff --git a/lib/private/files/storage/local.php b/lib/private/files/storage/local.php
index 7fa748a..883a69d 100644
--- a/lib/private/files/storage/local.php
+++ b/lib/private/files/storage/local.php
@@ -89,9 +89,8 @@ if (\OC_Util::runningOnWindows()) {
 		public function stat($path) {
 			$fullPath = $this->datadir . $path;
 			$statResult = stat($fullPath);
-
-			$filesize = self::getFileSizeWithTricks($fullPath);
-			if (!is_null($filesize)) {
+			if (PHP_INT_SIZE === 4) {
+				$filesize = $this->filesize($path);
 				$statResult['size'] = $filesize;
 				$statResult[7] = $filesize;
 			}
@@ -109,16 +108,16 @@ if (\OC_Util::runningOnWindows()) {
 		public function filesize($path) {
 			if ($this->is_dir($path)) {
 				return 0;
-			} else {
-				$fullPath = $this->datadir . $path;
-
-				$filesize = self::getFileSizeWithTricks($fullPath);
+			}
+			$fullPath = $this->datadir . $path;
+			if (PHP_INT_SIZE === 4) {
+				$helper = new \OC\LargeFileHelper;
+				$filesize = $helper->getFilesize($fullPath);
 				if (!is_null($filesize)) {
 					return $filesize;
 				}
-
-				return filesize($fullPath);
 			}
+			return filesize($fullPath);
 		}
 
 		public function isReadable($path) {
@@ -221,87 +220,6 @@ if (\OC_Util::runningOnWindows()) {
 			return $return;
 		}
 
-		/**
-		* @brief Tries to get the filesize via various workarounds if necessary.
-		* @param string $fullPath
-		* @return mixed Number of bytes on success and workaround necessary, null otherwise.
-		*/
-		private static function getFileSizeWithTricks($fullPath) {
-			if (PHP_INT_SIZE === 4) {
-				// filesize() and stat() are unreliable on 32bit systems
-				// for big files.
-				// In some cases they cause an E_WARNING and return false,
-				// in some other cases they silently wrap around at 2^32,
-				// i.e. e.g. report 674347008 bytes instead of 4969314304.
-				$filesize = self::getFileSizeFromCurl($fullPath);
-				if (!is_null($filesize)) {
-					return $filesize;
-				}
-				$filesize = self::getFileSizeFromOS($fullPath);
-				if (!is_null($filesize)) {
-					return $filesize;
-				}
-			}
-
-			return null;
-		}
-
-		/**
-		* @brief Tries to get the filesize via a CURL HEAD request.
-		* @param string $fullPath
-		* @return mixed Number of bytes on success, null otherwise.
-		*/
-		private static function getFileSizeFromCurl($fullPath) {
-			if (function_exists('curl_init')) {
-				$ch = curl_init("file://$fullPath");
-				curl_setopt($ch, CURLOPT_NOBODY, true);
-				curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-				curl_setopt($ch, CURLOPT_HEADER, true);
-				$data = curl_exec($ch);
-				curl_close($ch);
-				if ($data !== false) {
-					$matches = array();
-					preg_match('/Content-Length: (\d+)/', $data, $matches);
-					if (isset($matches[1])) {
-						return 0 + $matches[1];
-					}
-				}
-			}
-
-			return null;
-		}
-
-		/**
-		* @brief Tries to get the filesize via COM and exec().
-		* @param string $fullPath
-		* @return mixed Number of bytes on success, null otherwise.
-		*/
-		private static function getFileSizeFromOS($fullPath) {
-			$name = strtolower(php_uname('s'));
-			// Windows OS: we use COM to access the filesystem
-			if (strpos($name, 'win') !== false) {
-				if (class_exists('COM')) {
-					$fsobj = new \COM("Scripting.FileSystemObject");
-					$f = $fsobj->GetFile($fullPath);
-					return $f->Size;
-				}
-			} else if (strpos($name, 'bsd') !== false) {
-				if (\OC_Helper::is_function_enabled('exec')) {
-					return 0 + exec('stat -f %z ' . escapeshellarg($fullPath));
-				}
-			} else if (strpos($name, 'linux') !== false) {
-				if (\OC_Helper::is_function_enabled('exec')) {
-					return 0 + exec('stat -c %s ' . escapeshellarg($fullPath));
-				}
-			} else {
-				\OC_Log::write('core',
-					'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name,
-					\OC_Log::ERROR);
-			}
-
-			return null;
-		}
-
 		public function hash($type, $path, $raw = false) {
 			return hash_file($type, $this->datadir . $path, $raw);
 		}
diff --git a/lib/private/files/storage/mappedlocal.php b/lib/private/files/storage/mappedlocal.php
index 3ebdcf9..78d2616 100644
--- a/lib/private/files/storage/mappedlocal.php
+++ b/lib/private/files/storage/mappedlocal.php
@@ -111,11 +111,10 @@ class MappedLocal extends \OC\Files\Storage\Common {
 	public function stat($path) {
 		$fullPath = $this->buildPath($path);
 		$statResult = stat($fullPath);
-
-		if ($statResult['size'] < 0) {
-			$size = self::getFileSizeFromOS($fullPath);
-			$statResult['size'] = $size;
-			$statResult[7] = $size;
+		if (PHP_INT_SIZE === 4) {
+			$filesize = $this->filesize($path);
+			$statResult['size'] = $filesize;
+			$statResult[7] = $filesize;
 		}
 		return $statResult;
 	}
@@ -131,15 +130,16 @@ class MappedLocal extends \OC\Files\Storage\Common {
 	public function filesize($path) {
 		if ($this->is_dir($path)) {
 			return 0;
-		} else {
-			$fullPath = $this->buildPath($path);
-			$fileSize = filesize($fullPath);
-			if ($fileSize < 0) {
-				return self::getFileSizeFromOS($fullPath);
+		}
+		$fullPath = $this->buildPath($path);
+		if (PHP_INT_SIZE === 4) {
+			$helper = new \OC\LargeFileHelper;
+			$filesize = $helper->getFilesize($fullPath);
+			if (!is_null($filesize)) {
+				return $filesize;
 			}
-
-			return $fileSize;
 		}
+		return filesize($fullPath);
 	}
 
 	public function isReadable($path) {
@@ -294,35 +294,6 @@ class MappedLocal extends \OC\Files\Storage\Common {
 		return $return;
 	}
 
-	/**
-	 * @param string $fullPath
-	 */
-	private static function getFileSizeFromOS($fullPath) {
-		$name = strtolower(php_uname('s'));
-		// Windows OS: we use COM to access the filesystem
-		if (strpos($name, 'win') !== false) {
-			if (class_exists('COM')) {
-				$fsobj = new \COM("Scripting.FileSystemObject");
-				$f = $fsobj->GetFile($fullPath);
-				return $f->Size;
-			}
-		} else if (strpos($name, 'bsd') !== false) {
-			if (\OC_Helper::is_function_enabled('exec')) {
-				return (float)exec('stat -f %z ' . escapeshellarg($fullPath));
-			}
-		} else if (strpos($name, 'linux') !== false) {
-			if (\OC_Helper::is_function_enabled('exec')) {
-				return (float)exec('stat -c %s ' . escapeshellarg($fullPath));
-			}
-		} else {
-			\OC_Log::write('core',
-				'Unable to determine file size of "' . $fullPath . '". Unknown OS: ' . $name,
-				\OC_Log::ERROR);
-		}
-
-		return 0;
-	}
-
 	public function hash($type, $path, $raw = false) {
 		return hash_file($type, $this->buildPath($path), $raw);
 	}
diff --git a/lib/private/largefilehelper.php b/lib/private/largefilehelper.php
new file mode 100644
index 0000000..ca8f752
--- /dev/null
+++ b/lib/private/largefilehelper.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ * Copyright (c) 2014 Andreas Fischer <bantu at owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC;
+
+/**
+ * Helper class for large files on 32-bit platforms.
+ */
+class LargeFileHelper {
+	/**
+	* @brief Tries to get the filesize of a file via various workarounds that
+	*        even work for large files on 32-bit platforms.
+	*
+	* @param string $filename Path to the file.
+	*
+	* @return null|int|float Number of bytes as number (float or int) or
+	*                        null on failure.
+	*/
+	public function getFilesize($filename) {
+		$filesize = $this->getFilesizeViaCurl($filename);
+		if (!is_null($filesize)) {
+			return $filesize;
+		}
+		$filesize = $this->getFilesizeViaCOM($filename);
+		if (!is_null($filesize)) {
+			return $filesize;
+		}
+		$filesize = $this->getFilesizeViaExec($filename);
+		if (!is_null($filesize)) {
+			return $filesize;
+		}
+		return null;
+	}
+
+	/**
+	* @brief Tries to get the filesize of a file via a CURL HEAD request.
+	*
+	* @param string $filename Path to the file.
+	*
+	* @return null|int|float Number of bytes as number (float or int) or
+	*                        null on failure.
+	*/
+	public function getFilesizeViaCurl($filename) {
+		if (function_exists('curl_init')) {
+			$ch = curl_init("file://$filename");
+			curl_setopt($ch, CURLOPT_NOBODY, true);
+			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+			curl_setopt($ch, CURLOPT_HEADER, true);
+			$data = curl_exec($ch);
+			curl_close($ch);
+			if ($data !== false) {
+				$matches = array();
+				preg_match('/Content-Length: (\d+)/', $data, $matches);
+				if (isset($matches[1])) {
+					return 0 + $matches[1];
+				}
+			}
+		}
+		return null;
+	}
+
+	/**
+	* @brief Tries to get the filesize of a file via the Windows DOM extension.
+	*
+	* @param string $filename Path to the file.
+	*
+	* @return null|int|float Number of bytes as number (float or int) or
+	*                        null on failure.
+	*/
+	public function getFilesizeViaCOM($filename) {
+		if (class_exists('COM')) {
+			$fsobj = new \COM("Scripting.FileSystemObject");
+			$file = $fsobj->GetFile($filename);
+			return 0 + $file->Size;
+		}
+		return null;
+	}
+
+	/**
+	* @brief Tries to get the filesize of a file via an exec() call.
+	*
+	* @param string $filename Path to the file.
+	*
+	* @return null|int|float Number of bytes as number (float or int) or
+	*                        null on failure.
+	*/
+	public function getFilesizeViaExec($filename) {
+		if (\OC_Helper::is_function_enabled('exec')) {
+			$os = strtolower(php_uname('s'));
+			if (strpos($os, 'linux') !== false) {
+				return 0 + exec('stat -c %s ' . escapeshellarg($filename));
+			} else if (strpos($os, 'bsd') !== false) {
+				return 0 + exec('stat -f %z ' . escapeshellarg($filename));
+			}
+		}
+		return null;
+	}
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list