diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2013-02-09 19:15:23 +0100 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2013-02-09 19:15:23 +0100 |
commit | b9089fe8d966b48e4c8dc3f06fd365fc506a0199 (patch) | |
tree | 36d04441896a142a69bba884ec6c8d9ba00d10b5 /lib | |
parent | 05b46f78281e5df49a5c6a0513a37eaf03c3c29d (diff) | |
parent | 0222c589ac7c006c09dca6cea09cae9a1006a0b4 (diff) | |
download | nextcloud-server-b9089fe8d966b48e4c8dc3f06fd365fc506a0199.tar.gz nextcloud-server-b9089fe8d966b48e4c8dc3f06fd365fc506a0199.zip |
Merge branch 'master' into fixing-1424-master
Diffstat (limited to 'lib')
-rw-r--r-- | lib/app.php | 26 | ||||
-rw-r--r-- | lib/archive/tar.php | 2 | ||||
-rw-r--r-- | lib/base.php | 8 | ||||
-rw-r--r-- | lib/files/cache/scanner.php | 2 | ||||
-rw-r--r-- | lib/files/mapper.php | 216 | ||||
-rw-r--r-- | lib/files/storage/local.php | 5 | ||||
-rw-r--r-- | lib/files/storage/mappedlocal.php | 335 | ||||
-rw-r--r-- | lib/files/view.php | 6 | ||||
-rw-r--r-- | lib/l10n.php | 2 | ||||
-rw-r--r-- | lib/mimetypes.list.php | 2 | ||||
-rw-r--r-- | lib/public/util.php | 14 | ||||
-rw-r--r-- | lib/setup.php | 20 | ||||
-rwxr-xr-x | lib/util.php | 45 |
13 files changed, 666 insertions, 17 deletions
diff --git a/lib/app.php b/lib/app.php index 3a4e21e8cd1..ca256ed1aaa 100644 --- a/lib/app.php +++ b/lib/app.php @@ -39,6 +39,15 @@ class OC_App{ static private $altLogin = array(); /** + * @brief clean the appid + * @param $app Appid that needs to be cleaned + * @return string + */ + public static function cleanAppId($app) { + return str_replace(array('\0', '/', '\\', '..'), '', $app); + } + + /** * @brief loads all apps * @param array $types * @return bool @@ -286,6 +295,23 @@ class OC_App{ } /** + * @brief Get the navigation entries for the $app + * @param string $app app + * @return array of the $data added with addNavigationEntry + */ + public static function getAppNavigationEntries($app) { + if(is_file(self::getAppPath($app).'/appinfo/app.php')) { + $save = self::$navigation; + self::$navigation = array(); + require $app.'/appinfo/app.php'; + $app_entries = self::$navigation; + self::$navigation = $save; + return $app_entries; + } + return array(); + } + + /** * @brief gets the active Menu entry * @return string id or empty string * diff --git a/lib/archive/tar.php b/lib/archive/tar.php index 117d88e5f42..e7c81389619 100644 --- a/lib/archive/tar.php +++ b/lib/archive/tar.php @@ -6,7 +6,7 @@ * See the COPYING-README file. */ -require_once 'Archive/Tar.php'; +require_once OC::$THIRDPARTYROOT . '/3rdparty/Archive/Tar.php'; class OC_Archive_TAR extends OC_Archive{ const PLAIN=0; diff --git a/lib/base.php b/lib/base.php index 5bfdb0b7c0a..c60a97100f4 100644 --- a/lib/base.php +++ b/lib/base.php @@ -346,7 +346,7 @@ class OC { public static function init() { // register autoloader spl_autoload_register(array('OC', 'autoload')); - setlocale(LC_ALL, 'en_US.UTF-8'); + OC_Util::issetlocaleworking(); // set some stuff //ob_start(); @@ -468,7 +468,7 @@ class OC { register_shutdown_function(array('OC_Helper', 'cleanTmp')); //parse the given parameters - self::$REQUESTEDAPP = (isset($_GET['app']) && trim($_GET['app']) != '' && !is_null($_GET['app']) ? str_replace(array('\0', '/', '\\', '..'), '', strip_tags($_GET['app'])) : OC_Config::getValue('defaultapp', 'files')); + self::$REQUESTEDAPP = (isset($_GET['app']) && trim($_GET['app']) != '' && !is_null($_GET['app']) ? OC_App::cleanAppId(strip_tags($_GET['app'])) : OC_Config::getValue('defaultapp', 'files')); if (substr_count(self::$REQUESTEDAPP, '?') != 0) { $app = substr(self::$REQUESTEDAPP, 0, strpos(self::$REQUESTEDAPP, '?')); $param = substr($_GET['app'], strpos($_GET['app'], '?') + 1); @@ -498,7 +498,7 @@ class OC { // write error into log if locale can't be set if (OC_Util::issetlocaleworking() == false) { - OC_Log::write('core', 'setting locale to en_US.UTF-8 failed. Support is probably not installed on your system', OC_Log::ERROR); + OC_Log::write('core', 'setting locale to en_US.UTF-8/en_US.UTF8 failed. Support is probably not installed on your system', OC_Log::ERROR); } if (OC_Config::getValue('installed', false)) { if (OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') { @@ -548,6 +548,7 @@ class OC { require_once 'core/setup.php'; exit(); } + $request = OC_Request::getPathInfo(); if(substr($request, -3) !== '.js'){// we need these files during the upgrade self::checkMaintenanceMode(); @@ -556,6 +557,7 @@ class OC { if (!self::$CLI) { try { + OC_App::loadApps(); OC::getRouter()->match(OC_Request::getPathInfo()); return; } catch (Symfony\Component\Routing\Exception\ResourceNotFoundException $e) { diff --git a/lib/files/cache/scanner.php b/lib/files/cache/scanner.php index 8d504af6163..9a5546dce3f 100644 --- a/lib/files/cache/scanner.php +++ b/lib/files/cache/scanner.php @@ -138,7 +138,7 @@ class Scanner { * walk over any folders that are not fully scanned yet and scan them */ public function backgroundScan() { - while ($path = $this->cache->getIncomplete()) { + while (($path = $this->cache->getIncomplete()) !== false) { $this->scan($path); $this->cache->correctFolderSize($path); } diff --git a/lib/files/mapper.php b/lib/files/mapper.php new file mode 100644 index 00000000000..90e4e1ca669 --- /dev/null +++ b/lib/files/mapper.php @@ -0,0 +1,216 @@ +<?php + +namespace OC\Files; + +/** + * class Mapper is responsible to translate logical paths to physical paths and reverse + */ +class Mapper +{ + /** + * @param string $logicPath + * @param bool $create indicates if the generated physical name shall be stored in the database or not + * @return string the physical path + */ + public function logicToPhysical($logicPath, $create) { + $physicalPath = $this->resolveLogicPath($logicPath); + if ($physicalPath !== null) { + return $physicalPath; + } + + return $this->create($logicPath, $create); + } + + /** + * @param string $physicalPath + * @return string|null + */ + public function physicalToLogic($physicalPath) { + $logicPath = $this->resolvePhysicalPath($physicalPath); + if ($logicPath !== null) { + return $logicPath; + } + + $this->insert($physicalPath, $physicalPath); + return $physicalPath; + } + + /** + * @param string $path + * @param bool $isLogicPath indicates if $path is logical or physical + * @param $recursive + */ + public function removePath($path, $isLogicPath, $recursive) { + if ($recursive) { + $path=$path.'%'; + } + + if ($isLogicPath) { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); + $query->execute(array($path)); + } else { + $query = \OC_DB::prepare('DELETE FROM `*PREFIX*file_map` WHERE `physic_path` LIKE ?'); + $query->execute(array($path)); + } + } + + /** + * @param $path1 + * @param $path2 + * @throws \Exception + */ + public function copy($path1, $path2) + { + $path1 = $this->stripLast($path1); + $path2 = $this->stripLast($path2); + $physicPath1 = $this->logicToPhysical($path1, true); + $physicPath2 = $this->logicToPhysical($path2, true); + + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` LIKE ?'); + $result = $query->execute(array($path1.'%')); + $updateQuery = \OC_DB::prepare('UPDATE `*PREFIX*file_map`' + .' SET `logic_path` = ?' + .' AND `physic_path` = ?' + .' WHERE `logic_path` = ?'); + while( $row = $result->fetchRow()) { + $currentLogic = $row['logic_path']; + $currentPhysic = $row['physic_path']; + $newLogic = $path2.$this->stripRootFolder($currentLogic, $path1); + $newPhysic = $physicPath2.$this->stripRootFolder($currentPhysic, $physicPath1); + if ($path1 !== $currentLogic) { + try { + $updateQuery->execute(array($newLogic, $newPhysic, $currentLogic)); + } catch (\Exception $e) { + error_log('Mapper::Copy failed '.$currentLogic.' -> '.$newLogic.'\n'.$e); + throw $e; + } + } + } + } + + /** + * @param $path + * @param $root + * @return bool|string + */ + public function stripRootFolder($path, $root) { + if (strpos($path, $root) !== 0) { + // throw exception ??? + return false; + } + if (strlen($path) > strlen($root)) { + return substr($path, strlen($root)); + } + + return ''; + } + + private function stripLast($path) { + if (substr($path, -1) == '/') { + $path = substr_replace($path ,'',-1); + } + return $path; + } + + private function resolveLogicPath($logicPath) { + $logicPath = $this->stripLast($logicPath); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `logic_path` = ?'); + $result = $query->execute(array($logicPath)); + $result = $result->fetchRow(); + + return $result['physic_path']; + } + + private function resolvePhysicalPath($physicalPath) { + $physicalPath = $this->stripLast($physicalPath); + $query = \OC_DB::prepare('SELECT * FROM `*PREFIX*file_map` WHERE `physic_path` = ?'); + $result = $query->execute(array($physicalPath)); + $result = $result->fetchRow(); + + return $result['logic_path']; + } + + private function create($logicPath, $store) { + $logicPath = $this->stripLast($logicPath); + $index = 0; + + // create the slugified path + $physicalPath = $this->slugifyPath($logicPath); + + // detect duplicates + while ($this->resolvePhysicalPath($physicalPath) !== null) { + $physicalPath = $this->slugifyPath($physicalPath, $index++); + } + + // insert the new path mapping if requested + if ($store) { + $this->insert($logicPath, $physicalPath); + } + + return $physicalPath; + } + + private function insert($logicPath, $physicalPath) { + $query = \OC_DB::prepare('INSERT INTO `*PREFIX*file_map`(`logic_path`,`physic_path`) VALUES(?,?)'); + $query->execute(array($logicPath, $physicalPath)); + } + + private function slugifyPath($path, $index=null) { + $pathElements = explode('/', $path); + $sluggedElements = array(); + + // skip slugging the drive letter on windows - TODO: test if local path + if (strpos(strtolower(php_uname('s')), 'win') !== false) { + $sluggedElements[]= $pathElements[0]; + array_shift($pathElements); + } + foreach ($pathElements as $pathElement) { + // TODO: remove file ext before slugify on last element + $sluggedElements[] = self::slugify($pathElement); + } + + // + // TODO: add the index before the file extension + // + if ($index !== null) { + $last= end($sluggedElements); + array_pop($sluggedElements); + array_push($sluggedElements, $last.'-'.$index); + } + return implode(DIRECTORY_SEPARATOR, $sluggedElements); + } + + /** + * Modifies a string to remove all non ASCII characters and spaces. + * + * @param string $text + * @return string + */ + private function slugify($text) + { + // replace non letter or digits by - + $text = preg_replace('~[^\\pL\d]+~u', '-', $text); + + // trim + $text = trim($text, '-'); + + // transliterate + if (function_exists('iconv')) { + $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text); + } + + // lowercase + $text = strtolower($text); + + // remove unwanted characters + $text = preg_replace('~[^-\w]+~', '', $text); + + if (empty($text)) + { + // TODO: we better generate a guid in this case + return 'n-a'; + } + + return $text; + } +} diff --git a/lib/files/storage/local.php b/lib/files/storage/local.php index a5db4ba9194..d387a898320 100644 --- a/lib/files/storage/local.php +++ b/lib/files/storage/local.php @@ -8,6 +8,10 @@ namespace OC\Files\Storage; +if (\OC_Util::runningOnWindows()) { + require_once 'mappedlocal.php'; +} else { + /** * for local filestore, we only have to map the paths */ @@ -245,3 +249,4 @@ class Local extends \OC\Files\Storage\Common{ return $this->filemtime($path)>$time; } } +} diff --git a/lib/files/storage/mappedlocal.php b/lib/files/storage/mappedlocal.php new file mode 100644 index 00000000000..80dd79bc41f --- /dev/null +++ b/lib/files/storage/mappedlocal.php @@ -0,0 +1,335 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ +namespace OC\Files\Storage; + +/** + * for local filestore, we only have to map the paths + */ +class Local extends \OC\Files\Storage\Common{ + protected $datadir; + private $mapper; + + public function __construct($arguments) { + $this->datadir=$arguments['datadir']; + if(substr($this->datadir, -1)!=='/') { + $this->datadir.='/'; + } + + $this->mapper= new \OC\Files\Mapper(); + } + public function __destruct() { + if (defined('PHPUNIT_RUN')) { + $this->mapper->removePath($this->datadir, true, true); + } + } + public function getId(){ + return 'local::'.$this->datadir; + } + public function mkdir($path) { + return @mkdir($this->buildPath($path)); + } + public function rmdir($path) { + if ($result = @rmdir($this->buildPath($path))) { + $this->cleanMapper($path); + } + return $result; + } + public function opendir($path) { + $files = array('.', '..'); + $physicalPath= $this->buildPath($path); + + $logicalPath = $this->mapper->physicalToLogic($physicalPath); + $dh = opendir($physicalPath); + while ($file = readdir($dh)) { + if ($file === '.' or $file === '..') { + continue; + } + + $logicalFilePath = $this->mapper->physicalToLogic($physicalPath.DIRECTORY_SEPARATOR.$file); + + $file= $this->mapper->stripRootFolder($logicalFilePath, $logicalPath); + $file = $this->stripLeading($file); + $files[]= $file; + } + + \OC\Files\Stream\Dir::register('local-win32'.$path, $files); + return opendir('fakedir://local-win32'.$path); + } + public function is_dir($path) { + if(substr($path,-1)=='/') { + $path=substr($path, 0, -1); + } + return is_dir($this->buildPath($path)); + } + public function is_file($path) { + return is_file($this->buildPath($path)); + } + 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; + } + return $statResult; + } + public function filetype($path) { + $filetype=filetype($this->buildPath($path)); + if($filetype=='link') { + $filetype=filetype(realpath($this->buildPath($path))); + } + return $filetype; + } + 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); + } + + return $fileSize; + } + } + public function isReadable($path) { + return is_readable($this->buildPath($path)); + } + public function isUpdatable($path) { + return is_writable($this->buildPath($path)); + } + public function file_exists($path) { + return file_exists($this->buildPath($path)); + } + public function filemtime($path) { + return filemtime($this->buildPath($path)); + } + public function touch($path, $mtime=null) { + // sets the modification time of the file to the given value. + // If mtime is nil the current time is set. + // note that the access time of the file always changes to the current time. + if(!is_null($mtime)) { + $result=touch( $this->buildPath($path), $mtime ); + }else{ + $result=touch( $this->buildPath($path)); + } + if( $result ) { + clearstatcache( true, $this->buildPath($path) ); + } + + return $result; + } + public function file_get_contents($path) { + return file_get_contents($this->buildPath($path)); + } + public function file_put_contents($path, $data) {//trigger_error("$path = ".var_export($path, 1)); + return file_put_contents($this->buildPath($path), $data); + } + public function unlink($path) { + return $this->delTree($path); + } + public function rename($path1, $path2) { + if (!$this->isUpdatable($path1)) { + \OC_Log::write('core','unable to rename, file is not writable : '.$path1,\OC_Log::ERROR); + return false; + } + if(! $this->file_exists($path1)) { + \OC_Log::write('core','unable to rename, file does not exists : '.$path1,\OC_Log::ERROR); + return false; + } + + $physicPath1 = $this->buildPath($path1); + $physicPath2 = $this->buildPath($path2); + if($return=rename($physicPath1, $physicPath2)) { + // mapper needs to create copies or all children + $this->copyMapping($path1, $path2); + $this->cleanMapper($physicPath1, false, true); + } + return $return; + } + public function copy($path1, $path2) { + if($this->is_dir($path2)) { + if(!$this->file_exists($path2)) { + $this->mkdir($path2); + } + $source=substr($path1, strrpos($path1, '/')+1); + $path2.=$source; + } + if($return=copy($this->buildPath($path1), $this->buildPath($path2))) { + // mapper needs to create copies or all children + $this->copyMapping($path1, $path2); + } + return $return; + } + public function fopen($path, $mode) { + if($return=fopen($this->buildPath($path), $mode)) { + switch($mode) { + case 'r': + break; + case 'r+': + case 'w+': + case 'x+': + case 'a+': + break; + case 'w': + case 'x': + case 'a': + break; + } + } + return $return; + } + + public function getMimeType($path) { + if($this->isReadable($path)) { + return \OC_Helper::getMimeType($this->buildPath($path)); + }else{ + return false; + } + } + + private function delTree($dir, $isLogicPath=true) { + $dirRelative=$dir; + if ($isLogicPath) { + $dir=$this->buildPath($dir); + } + if (!file_exists($dir)) { + return true; + } + if (!is_dir($dir) || is_link($dir)) { + if($return=unlink($dir)) { + $this->cleanMapper($dir, false); + return $return; + } + } + foreach (scandir($dir) as $item) { + if ($item == '.' || $item == '..') { + continue; + } + if(is_file($dir.'/'.$item)) { + if(unlink($dir.'/'.$item)) { + $this->cleanMapper($dir.'/'.$item, false); + } + }elseif(is_dir($dir.'/'.$item)) { + if (!$this->delTree($dir. "/" . $item, false)) { + return false; + }; + } + } + if($return=rmdir($dir)) { + $this->cleanMapper($dir, false); + } + return $return; + } + + 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($path, $type, $raw=false) { + return hash_file($type, $this->buildPath($path), $raw); + } + + public function free_space($path) { + return @disk_free_space($this->buildPath($path)); + } + + public function search($query) { + return $this->searchInDir($query); + } + public function getLocalFile($path) { + return $this->buildPath($path); + } + public function getLocalFolder($path) { + return $this->buildPath($path); + } + + protected function searchInDir($query, $dir='', $isLogicPath=true) { + $files=array(); + $physicalDir = $this->buildPath($dir); + foreach (scandir($physicalDir) as $item) { + if ($item == '.' || $item == '..') + continue; + $physicalItem = $this->mapper->physicalToLogic($physicalDir.DIRECTORY_SEPARATOR.$item); + $item = substr($physicalItem, strlen($physicalDir)+1); + + if(strstr(strtolower($item), strtolower($query)) !== false) { + $files[]=$dir.'/'.$item; + } + if(is_dir($physicalItem)) { + $files=array_merge($files, $this->searchInDir($query, $physicalItem, false)); + } + } + return $files; + } + + /** + * check if a file or folder has been updated since $time + * @param string $path + * @param int $time + * @return bool + */ + public function hasUpdated($path, $time) { + return $this->filemtime($path)>$time; + } + + private function buildPath($path, $create=true) { + $path = $this->stripLeading($path); + $fullPath = $this->datadir.$path; + return $this->mapper->logicToPhysical($fullPath, $create); + } + + private function cleanMapper($path, $isLogicPath=true, $recursive=true) { + $fullPath = $path; + if ($isLogicPath) { + $fullPath = $this->datadir.$path; + } + $this->mapper->removePath($fullPath, $isLogicPath, $recursive); + } + + private function copyMapping($path1, $path2) { + $path1 = $this->stripLeading($path1); + $path2 = $this->stripLeading($path2); + + $fullPath1 = $this->datadir.$path1; + $fullPath2 = $this->datadir.$path2; + + $this->mapper->copy($fullPath1, $fullPath2); + } + + private function stripLeading($path) { + if(strpos($path, '/') === 0) { + $path = substr($path, 1); + } + + return $path; + } +} diff --git a/lib/files/view.php b/lib/files/view.php index dfcb770328b..1a234228eab 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -509,11 +509,7 @@ class View { if (Filesystem::isValidPath($path)) { $source = $this->fopen($path, 'r'); if ($source) { - $extension = ''; - $extOffset = strpos($path, '.'); - if ($extOffset !== false) { - $extension = substr($path, strrpos($path, '.')); - } + $extension = pathinfo($path, PATHINFO_EXTENSION); $tmpFile = \OC_Helper::tmpFile($extension); file_put_contents($tmpFile, $source); return $tmpFile; diff --git a/lib/l10n.php b/lib/l10n.php index ee879009265..e272bcd79f3 100644 --- a/lib/l10n.php +++ b/lib/l10n.php @@ -97,7 +97,7 @@ class OC_L10N{ if ($this->app === true) { return; } - $app = $this->app; + $app = OC_App::cleanAppId($this->app); $lang = $this->lang; $this->app = true; // Find the right language diff --git a/lib/mimetypes.list.php b/lib/mimetypes.list.php index fc87d011ecd..86ce9c6c237 100644 --- a/lib/mimetypes.list.php +++ b/lib/mimetypes.list.php @@ -97,4 +97,6 @@ return array( 'ai' => 'application/illustrator', 'epub' => 'application/epub+zip', 'mobi' => 'application/x-mobipocket-ebook', + 'exe' => 'application', + 'msi' => 'application' ); diff --git a/lib/public/util.php b/lib/public/util.php index 968ca891b4c..5f6ede4460e 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -148,6 +148,20 @@ class Util { } /** + * @brief Creates an url using a defined route + * @param $route + * @param array $parameters + * @return + * @internal param array $args with param=>value, will be appended to the returned url + * @returns the url + * + * Returns a url to the given app and file. + */ + public static function linkToRoute( $route, $parameters = array() ) { + return \OC_Helper::linkToRoute($route, $parameters); + } + + /** * @brief Creates an url * @param string $app app * @param string $file file diff --git a/lib/setup.php b/lib/setup.php index 4dd190b99fb..f342142c957 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -610,4 +610,24 @@ class OC_Setup { file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/.htaccess', $content); file_put_contents(OC_Config::getValue('datadirectory', OC::$SERVERROOT.'/data').'/index.html', ''); } + + /** + * @brief Post installation checks + */ + public static function postSetupCheck($params) { + // setup was successful -> webdav testing now + if (OC_Util::isWebDAVWorking()) { + header("Location: ".OC::$WEBROOT.'/'); + } else { + $l=OC_L10N::get('lib'); + + $error = $l->t('Your web server is not yet properly setup to allow files synchronization because the WebDAV interface seems to be broken.'); + $hint = $l->t('Please double check the <a href=\'%s\'>installation guides</a>.', 'http://doc.owncloud.org/server/5.0/admin_manual/installation.html'); + + $tmpl = new OC_Template('', 'error', 'guest'); + $tmpl->assign('errors', array(1 => array('error' => $error, 'hint' => $hint)), false); + $tmpl->printPage(); + exit(); + } + } } diff --git a/lib/util.php b/lib/util.php index 9ce974619bc..a5fe4cb175a 100755 --- a/lib/util.php +++ b/lib/util.php @@ -516,6 +516,40 @@ class OC_Util { } } + /** + * we test if webDAV is working properly + * + * The basic assumption is that if the server returns 401/Not Authenticated for an unauthenticated PROPFIND + * the web server it self is setup properly. + * + * Why not an authenticated PROFIND and other verbs? + * - We don't have the password available + * - We have no idea about other auth methods implemented (e.g. OAuth with Bearer header) + * + */ + public static function isWebDAVWorking() { + if (!function_exists('curl_init')) { + return; + } + + $settings = array( + 'baseUri' => OC_Helper::linkToRemote('webdav'), + ); + + $client = new \Sabre_DAV_Client($settings); + + $return = true; + try { + // test PROPFIND + $client->propfind('', array('{DAV:}resourcetype')); + } catch(\Sabre_DAV_Exception_NotAuthenticated $e) { + $return = true; + } catch(\Exception $e) { + $return = false; + } + + return $return; + } /** * Check if the setlocal call doesn't work. This can happen if the right local packages are not available on the server. @@ -526,12 +560,11 @@ class OC_Util { return true; } - $result=setlocale(LC_ALL, 'en_US.UTF-8'); - if($result==false) { - return(false); - }else{ - return(true); - } + $result = setlocale(LC_ALL, 'en_US.UTF-8', 'en_US.UTF8'); + if($result == false) { + return false; + } + return true; } /** |