diff --git a/lib/base.php b/lib/base.php
index af78b4e4eb..f2d9251294 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -504,11 +504,12 @@ class OC {
if (!defined('PHPUNIT_RUN')) {
if (defined('DEBUG') and DEBUG) {
+ OC\Log\ErrorHandler::register(true);
set_exception_handler(array('OC_Template', 'printExceptionErrorPage'));
} else {
OC\Log\ErrorHandler::register();
- OC\Log\ErrorHandler::setLogger(OC_Log::$object);
}
+ OC\Log\ErrorHandler::setLogger(OC_Log::$object);
}
// register the stream wrappers
@@ -690,7 +691,8 @@ class OC {
// Check if ownCloud is installed or in maintenance (update) mode
if (!OC_Config::getValue('installed', false)) {
- require_once 'core/setup.php';
+ $controller = new OC\Core\Setup\Controller();
+ $controller->run($_POST);
exit();
}
diff --git a/lib/private/app.php b/lib/private/app.php
index 0c60557914..da09021cf3 100644
--- a/lib/private/app.php
+++ b/lib/private/app.php
@@ -63,8 +63,8 @@ class OC_App{
ob_start();
foreach( $apps as $app ) {
if((is_null($types) or self::isType($app, $types)) && !in_array($app, self::$loadedApps)) {
- self::loadApp($app);
self::$loadedApps[] = $app;
+ self::loadApp($app);
}
}
ob_end_clean();
diff --git a/lib/private/connector/sabre/exceptionloggerplugin.php b/lib/private/connector/sabre/exceptionloggerplugin.php
new file mode 100644
index 0000000000..8e77afaf20
--- /dev/null
+++ b/lib/private/connector/sabre/exceptionloggerplugin.php
@@ -0,0 +1,50 @@
+
+ *
+ * @license AGPL3
+ */
+
+class OC_Connector_Sabre_ExceptionLoggerPlugin extends Sabre_DAV_ServerPlugin
+{
+ private $appName;
+
+ /**
+ * @param string $loggerAppName app name to use when logging
+ */
+ public function __construct($loggerAppName = 'webdav') {
+ $this->appName = $loggerAppName;
+ }
+
+ /**
+ * This initializes the plugin.
+ *
+ * This function is called by Sabre_DAV_Server, after
+ * addPlugin is called.
+ *
+ * This method should set up the required event subscriptions.
+ *
+ * @param Sabre_DAV_Server $server
+ * @return void
+ */
+ public function initialize(Sabre_DAV_Server $server) {
+
+ $server->subscribeEvent('exception', array($this, 'logException'), 10);
+ }
+
+ /**
+ * Log exception
+ *
+ * @internal param Exception $e exception
+ */
+ public function logException($e) {
+ $exceptionClass = get_class($e);
+ if ($exceptionClass !== 'Sabre_DAV_Exception_NotAuthenticated') {
+ \OCP\Util::logException($this->appName, $e);
+ }
+ }
+}
diff --git a/lib/private/connector/sabre/file.php b/lib/private/connector/sabre/file.php
index c3b5900729..ed27cef440 100644
--- a/lib/private/connector/sabre/file.php
+++ b/lib/private/connector/sabre/file.php
@@ -79,7 +79,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
\OC_Log::write('webdav', '\OC\Files\Filesystem::file_put_contents() failed', \OC_Log::ERROR);
$fs->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();
+ throw new Sabre_DAV_Exception('Could not write file contents');
}
} catch (\OCP\Files\NotPermittedException $e) {
// a more general case - due to whatever reason the content could not be written
@@ -105,7 +105,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
if ($renameOkay === false || $fileExists === false) {
\OC_Log::write('webdav', '\OC\Files\Filesystem::rename() failed', \OC_Log::ERROR);
$fs->unlink($partpath);
- throw new Sabre_DAV_Exception();
+ throw new Sabre_DAV_Exception('Could not rename part file to final file');
}
// allow sync clients to send the mtime along in a header
@@ -246,7 +246,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
if ($fileExists) {
$fs->unlink($targetPath);
}
- throw new Sabre_DAV_Exception();
+ throw new Sabre_DAV_Exception('Could not rename part file assembled from chunks');
}
// allow sync clients to send the mtime along in a header
diff --git a/lib/private/connector/sabre/objecttree.php b/lib/private/connector/sabre/objecttree.php
index cd3f081f7c..d1e179af2e 100644
--- a/lib/private/connector/sabre/objecttree.php
+++ b/lib/private/connector/sabre/objecttree.php
@@ -38,7 +38,20 @@ class ObjectTree extends \Sabre_DAV_ObjectTree {
return $this->rootNode;
}
- $info = $this->getFileView()->getFileInfo($path);
+ if (pathinfo($path, PATHINFO_EXTENSION) === 'part') {
+ // read from storage
+ $absPath = $this->getFileView()->getAbsolutePath($path);
+ list($storage, $internalPath) = Filesystem::resolvePath('/' . $absPath);
+ if ($storage) {
+ $scanner = $storage->getScanner($internalPath);
+ // get data directly
+ $info = $scanner->getData($internalPath);
+ }
+ }
+ else {
+ // read from cache
+ $info = $this->getFileView()->getFileInfo($path);
+ }
if (!$info) {
throw new \Sabre_DAV_Exception_NotFound('File with name ' . $path . ' could not be located');
diff --git a/lib/private/helper.php b/lib/private/helper.php
index 1c8d01c141..580f81acc6 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -161,6 +161,7 @@ class OC_Helper {
'application/vnd.oasis.opendocument.text-template' => 'x-office/document',
'application/vnd.oasis.opendocument.text-web' => 'x-office/document',
'application/vnd.oasis.opendocument.text-master' => 'x-office/document',
+ 'application/mspowerpoint' => 'x-office/presentation',
'application/vnd.ms-powerpoint' => 'x-office/presentation',
'application/vnd.openxmlformats-officedocument.presentationml.presentation' => 'x-office/presentation',
'application/vnd.openxmlformats-officedocument.presentationml.template' => 'x-office/presentation',
@@ -171,6 +172,7 @@ class OC_Helper {
'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => 'x-office/presentation',
'application/vnd.oasis.opendocument.presentation' => 'x-office/presentation',
'application/vnd.oasis.opendocument.presentation-template' => 'x-office/presentation',
+ 'application/msexcel' => 'x-office/spreadsheet',
'application/vnd.ms-excel' => 'x-office/spreadsheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'x-office/spreadsheet',
'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => 'x-office/spreadsheet',
@@ -180,6 +182,7 @@ class OC_Helper {
'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => 'x-office/spreadsheet',
'application/vnd.oasis.opendocument.spreadsheet' => 'x-office/spreadsheet',
'application/vnd.oasis.opendocument.spreadsheet-template' => 'x-office/spreadsheet',
+ 'application/msaccess' => 'database',
);
if (isset($alias[$mimetype])) {
@@ -445,29 +448,6 @@ class OC_Helper {
*
*/
- //FIXME: should also check for value validation (i.e. the email is an email).
- public static function init_var($s, $d = "") {
- $r = $d;
- if (isset($_REQUEST[$s]) && !empty($_REQUEST[$s])) {
- $r = OC_Util::sanitizeHTML($_REQUEST[$s]);
- }
-
- return $r;
- }
-
- /**
- * returns "checked"-attribute if request contains selected radio element
- * OR if radio element is the default one -- maybe?
- *
- * @param string $s Name of radio-button element name
- * @param string $v Value of current radio-button element
- * @param string $d Value of default radio-button element
- */
- public static function init_radio($s, $v, $d) {
- if ((isset($_REQUEST[$s]) && $_REQUEST[$s] == $v) || (!isset($_REQUEST[$s]) && $v == $d))
- print "checked=\"checked\" ";
- }
-
/**
* detect if a given program is found in the search PATH
*
@@ -828,23 +808,39 @@ class OC_Helper {
* @return number of bytes representing
*/
public static function maxUploadFilesize($dir) {
- $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
- $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size'));
- $freeSpace = \OC\Files\Filesystem::free_space($dir);
- if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
- $maxUploadFilesize = \OC\Files\SPACE_UNLIMITED;
- } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
- $maxUploadFilesize = max($upload_max_filesize, $post_max_size); //only the non 0 value counts
- } else {
- $maxUploadFilesize = min($upload_max_filesize, $post_max_size);
- }
+ return min(self::freeSpace($dir), self::uploadLimit());
+ }
+ /**
+ * Calculate free space left within user quota
+ *
+ * @param $dir the current folder where the user currently operates
+ * @return number of bytes representing
+ */
+ public static function freeSpace($dir) {
+ $freeSpace = \OC\Files\Filesystem::free_space($dir);
if ($freeSpace !== \OC\Files\SPACE_UNKNOWN) {
$freeSpace = max($freeSpace, 0);
-
- return min($maxUploadFilesize, $freeSpace);
+ return $freeSpace;
} else {
- return $maxUploadFilesize;
+ return INF;
+ }
+ }
+
+ /**
+ * Calculate PHP upload limit
+ *
+ * @return PHP upload file size limit
+ */
+ public static function uploadLimit() {
+ $upload_max_filesize = OCP\Util::computerFileSize(ini_get('upload_max_filesize'));
+ $post_max_size = OCP\Util::computerFileSize(ini_get('post_max_size'));
+ if ((int)$upload_max_filesize === 0 and (int)$post_max_size === 0) {
+ return INF;
+ } elseif ((int)$upload_max_filesize === 0 or (int)$post_max_size === 0) {
+ return max($upload_max_filesize, $post_max_size); //only the non 0 value counts
+ } else {
+ return min($upload_max_filesize, $post_max_size);
}
}
diff --git a/lib/private/image.php b/lib/private/image.php
index a6a2413f59..62d2a1f0ff 100644
--- a/lib/private/image.php
+++ b/lib/private/image.php
@@ -409,14 +409,14 @@ class OC_Image {
/**
* @brief Loads an image from a local file.
- * @param $imageref The path to a local file.
+ * @param $imagePath The path to a local file.
* @returns An image resource or false on error
*/
public function loadFromFile($imagePath=false) {
// exif_imagetype throws "read error!" if file is less than 12 byte
if(!@is_file($imagePath) || !file_exists($imagePath) || filesize($imagePath) < 12 || !is_readable($imagePath)) {
// Debug output disabled because this method is tried before loadFromBase64?
- OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: '.$imagePath, OC_Log::DEBUG);
+ OC_Log::write('core', 'OC_Image->loadFromFile, couldn\'t load: ' . (string) urlencode($imagePath), OC_Log::DEBUG);
return false;
}
$iType = exif_imagetype($imagePath);
diff --git a/lib/private/l10n.php b/lib/private/l10n.php
index 98665c84c5..1aa1dc5ea2 100644
--- a/lib/private/l10n.php
+++ b/lib/private/l10n.php
@@ -132,10 +132,10 @@ class OC_L10N implements \OCP\IL10N {
$i18ndir = self::findI18nDir($app);
// Localization is in /l10n, Texts are in $i18ndir
// (Just no need to define date/time format etc. twice)
- if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/')
- || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
+ if((OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/core/l10n/')
|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/lib/l10n/')
|| OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC::$SERVERROOT.'/settings')
+ || OC_Helper::issubdirectory($i18ndir.$lang.'.php', OC_App::getAppPath($app).'/l10n/')
)
&& file_exists($i18ndir.$lang.'.php')) {
// Include the file, save the data from $CONFIG
diff --git a/lib/private/log/errorhandler.php b/lib/private/log/errorhandler.php
index 69cb960de9..1dde6b507f 100644
--- a/lib/private/log/errorhandler.php
+++ b/lib/private/log/errorhandler.php
@@ -14,10 +14,23 @@ class ErrorHandler {
/** @var LoggerInterface */
private static $logger;
- public static function register() {
+ /**
+ * @brief remove password in URLs
+ * @param string $msg
+ * @return string
+ */
+ protected static function removePassword($msg) {
+ return preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $msg);
+ }
+
+ public static function register($debug=false) {
$handler = new ErrorHandler();
- set_error_handler(array($handler, 'onError'));
+ if ($debug) {
+ set_error_handler(array($handler, 'onAll'), E_ALL);
+ } else {
+ set_error_handler(array($handler, 'onError'));
+ }
register_shutdown_function(array($handler, 'onShutdown'));
set_exception_handler(array($handler, 'onException'));
}
@@ -32,14 +45,14 @@ class ErrorHandler {
if($error && self::$logger) {
//ob_end_clean();
$msg = $error['message'] . ' at ' . $error['file'] . '#' . $error['line'];
- self::$logger->critical($msg, array('app' => 'PHP'));
+ self::$logger->critical(self::removePassword($msg), array('app' => 'PHP'));
}
}
// Uncaught exception handler
public static function onException($exception) {
$msg = $exception->getMessage() . ' at ' . $exception->getFile() . '#' . $exception->getLine();
- self::$logger->critical($msg, array('app' => 'PHP'));
+ self::$logger->critical(self::removePassword($msg), array('app' => 'PHP'));
}
//Recoverable errors handler
@@ -48,7 +61,15 @@ class ErrorHandler {
return;
}
$msg = $message . ' at ' . $file . '#' . $line;
- self::$logger->warning($msg, array('app' => 'PHP'));
+ self::$logger->error(self::removePassword($msg), array('app' => 'PHP'));
}
+
+ //Recoverable handler which catch all errors, warnings and notices
+ public static function onAll($number, $message, $file, $line) {
+ $msg = $message . ' at ' . $file . '#' . $line;
+ self::$logger->debug(self::removePassword($msg), array('app' => 'PHP'));
+
+ }
+
}
diff --git a/lib/private/log/owncloud.php b/lib/private/log/owncloud.php
index 4c86d0e45e..3590bbd436 100644
--- a/lib/private/log/owncloud.php
+++ b/lib/private/log/owncloud.php
@@ -69,7 +69,6 @@ class OC_Log_Owncloud {
}
$time = new DateTime(null, $timezone);
// remove username/passswords from URLs before writing the to the log file
- $message = preg_replace('/\/\/(.*):(.*)@/', '//xxx:xxx@', $message);
$entry=array('app'=>$app, 'message'=>$message, 'level'=>$level, 'time'=> $time->format($format));
$entry = json_encode($entry);
$handle = @fopen(self::$logFile, 'a');
diff --git a/lib/private/memcache/apc.php b/lib/private/memcache/apc.php
index e995cbc526..332bbfead0 100644
--- a/lib/private/memcache/apc.php
+++ b/lib/private/memcache/apc.php
@@ -9,15 +9,8 @@
namespace OC\Memcache;
class APC extends Cache {
- /**
- * entries in APC gets namespaced to prevent collisions between owncloud instances and users
- */
- protected function getNameSpace() {
- return $this->prefix;
- }
-
public function get($key) {
- $result = apc_fetch($this->getNamespace() . $key, $success);
+ $result = apc_fetch($this->getPrefix() . $key, $success);
if (!$success) {
return null;
}
@@ -25,26 +18,22 @@ class APC extends Cache {
}
public function set($key, $value, $ttl = 0) {
- return apc_store($this->getNamespace() . $key, $value, $ttl);
+ return apc_store($this->getPrefix() . $key, $value, $ttl);
}
public function hasKey($key) {
- return apc_exists($this->getNamespace() . $key);
+ return apc_exists($this->getPrefix() . $key);
}
public function remove($key) {
- return apc_delete($this->getNamespace() . $key);
+ return apc_delete($this->getPrefix() . $key);
}
public function clear($prefix = '') {
- $ns = $this->getNamespace() . $prefix;
- $cache = apc_cache_info('user');
- foreach ($cache['cache_list'] as $entry) {
- if (strpos($entry['info'], $ns) === 0) {
- apc_delete($entry['info']);
- }
- }
- return true;
+ $ns = $this->getPrefix() . $prefix;
+ $ns = preg_quote($ns, '/');
+ $iter = new \APCIterator('user', '/^' . $ns . '/');
+ return apc_delete($iter);
}
static public function isAvailable() {
diff --git a/lib/private/memcache/apcu.php b/lib/private/memcache/apcu.php
index dac0f5f208..7f780f3271 100644
--- a/lib/private/memcache/apcu.php
+++ b/lib/private/memcache/apcu.php
@@ -9,13 +9,6 @@
namespace OC\Memcache;
class APCu extends APC {
- public function clear($prefix = '') {
- $ns = $this->getNamespace() . $prefix;
- $ns = preg_quote($ns, '/');
- $iter = new \APCIterator('user', '/^'.$ns.'/');
- return apc_delete($iter);
- }
-
static public function isAvailable() {
if (!extension_loaded('apcu')) {
return false;
diff --git a/lib/private/memcache/cache.php b/lib/private/memcache/cache.php
index 0ad1cc7ec0..03671b3f24 100644
--- a/lib/private/memcache/cache.php
+++ b/lib/private/memcache/cache.php
@@ -18,7 +18,7 @@ abstract class Cache implements \ArrayAccess {
* @param string $prefix
*/
public function __construct($prefix = '') {
- $this->prefix = \OC_Util::getInstanceId() . '/' . $prefix;
+ $this->prefix = $prefix;
}
public function getPrefix() {
diff --git a/lib/private/memcache/factory.php b/lib/private/memcache/factory.php
index fde7d94756..334cf9a1f0 100644
--- a/lib/private/memcache/factory.php
+++ b/lib/private/memcache/factory.php
@@ -8,7 +8,21 @@
namespace OC\Memcache;
-class Factory {
+use \OCP\ICacheFactory;
+
+class Factory implements ICacheFactory {
+ /**
+ * @var string $globalPrefix
+ */
+ private $globalPrefix;
+
+ /**
+ * @param string $globalPrefix
+ */
+ public function __construct($globalPrefix) {
+ $this->globalPrefix = $globalPrefix;
+ }
+
/**
* get a cache instance, will return null if no backend is available
*
@@ -16,6 +30,7 @@ class Factory {
* @return \OC\Memcache\Cache
*/
function create($prefix = '') {
+ $prefix = $this->globalPrefix . '/' . $prefix;
if (XCache::isAvailable()) {
return new XCache($prefix);
} elseif (APCu::isAvailable()) {
diff --git a/lib/private/mimetypes.list.php b/lib/private/mimetypes.list.php
index 0822833696..40fb1d2d97 100644
--- a/lib/private/mimetypes.list.php
+++ b/lib/private/mimetypes.list.php
@@ -21,93 +21,91 @@
*/
/**
- * list of mimetypes by extension
+ * Array mapping file extensions to mimetypes (in alphabetical order).
*/
-
return array(
+ 'accdb'=>'application/msaccess',
+ 'ai' => 'application/illustrator',
+ 'avi'=>'video/x-msvideo',
+ 'bash' => 'text/x-shellscript',
+ 'blend'=>'application/x-blender',
+ 'cc' => 'text/x-c',
+ 'cdr' => 'application/coreldraw',
+ 'cpp' => 'text/x-c++src',
'css'=>'text/css',
+ 'c' => 'text/x-c',
+ 'c++' => 'text/x-c++src',
+ 'doc'=>'application/msword',
+ 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'dot'=>'application/msword',
+ 'dotx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'dv'=>'video/dv',
+ 'epub' => 'application/epub+zip',
+ 'exe'=>'application/x-ms-dos-executable',
'flac'=>'audio/flac',
'gif'=>'image/gif',
- 'gzip'=>'application/x-gzip',
'gz'=>'application/x-gzip',
+ 'gzip'=>'application/x-gzip',
'html'=>'text/html',
'htm'=>'text/html',
- 'ics'=>'text/calendar',
'ical'=>'text/calendar',
+ 'ics'=>'text/calendar',
+ 'impress' => 'text/impress',
'jpeg'=>'image/jpeg',
'jpg'=>'image/jpeg',
'js'=>'application/javascript',
+ 'keynote'=>'application/x-iwork-keynote-sffkey',
+ 'kra'=>'application/x-krita',
+ 'm2t'=>'video/mp2t',
+ 'm4v'=>'video/mp4',
+ 'markdown' => 'text/markdown',
+ 'mdown' => 'text/markdown',
+ 'md' => 'text/markdown',
+ 'mdb'=>'application/msaccess',
+ 'mdwn' => 'text/markdown',
+ 'mobi' => 'application/x-mobipocket-ebook',
+ 'mov'=>'video/quicktime',
+ 'mp3'=>'audio/mpeg',
+ 'mp4'=>'video/mp4',
+ 'mpeg'=>'video/mpeg',
+ 'mpg'=>'video/mpeg',
+ 'msi'=>'application/x-msi',
+ 'numbers'=>'application/x-iwork-numbers-sffnumbers',
+ 'odg'=>'application/vnd.oasis.opendocument.graphics',
+ 'odp'=>'application/vnd.oasis.opendocument.presentation',
+ 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
+ 'odt'=>'application/vnd.oasis.opendocument.text',
'oga'=>'audio/ogg',
'ogg'=>'audio/ogg',
'ogv'=>'video/ogg',
- 'pdf'=>'application/pdf',
- 'png'=>'image/png',
- 'svg'=>'image/svg+xml',
- 'tar'=>'application/x-tar',
- 'tgz'=>'application/x-compressed',
- 'tar.gz'=>'application/x-compressed',
- 'tif'=>'image/tiff',
- 'tiff'=>'image/tiff',
- 'txt'=>'text/plain',
- 'zip'=>'application/zip',
- 'wav'=>'audio/wav',
- 'odt'=>'application/vnd.oasis.opendocument.text',
- 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
- 'odg'=>'application/vnd.oasis.opendocument.graphics',
- 'odp'=>'application/vnd.oasis.opendocument.presentation',
'pages'=>'application/x-iwork-pages-sffpages',
- 'numbers'=>'application/x-iwork-numbers-sffnumbers',
- 'keynote'=>'application/x-iwork-keynote-sffkey',
- 'kra'=>'application/x-krita',
- 'mp3'=>'audio/mpeg',
- 'doc'=>'application/msword',
- 'docx'=>'application/msword',
- 'xls'=>'application/msexcel',
- 'xlsx'=>'application/msexcel',
+ 'pdf'=>'application/pdf',
'php'=>'application/x-php',
- 'exe'=>'application/x-ms-dos-executable',
- 'msi'=>'application/x-msi',
'pl'=>'application/x-pearl',
- 'py'=>'application/x-python',
- 'blend'=>'application/x-blender',
- 'xcf'=>'application/x-gimp',
- 'psd'=>'application/x-photoshop',
- 'xml'=>'application/xml',
- 'avi'=>'video/x-msvideo',
- 'dv'=>'video/dv',
- 'm2t'=>'video/mp2t',
- 'mp4'=>'video/mp4',
- 'm4v'=>'video/mp4',
- 'mpg'=>'video/mpeg',
- 'mpeg'=>'video/mpeg',
- 'mov'=>'video/quicktime',
- 'webm'=>'video/webm',
- 'wmv'=>'video/x-ms-asf',
- 'py'=>'text/x-script.python',
- 'vcf' => 'text/vcard',
- 'vcard' => 'text/vcard',
- 'doc'=>'application/msword',
- 'docx'=>'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'xls'=>'application/msexcel',
- 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'png'=>'image/png',
'ppt'=>'application/mspowerpoint',
'pptx'=>'application/vnd.openxmlformats-officedocument.presentationml.presentation',
- 'sgf' => 'application/sgf',
- 'cdr' => 'application/coreldraw',
- 'impress' => 'text/impress',
- 'ai' => 'application/illustrator',
- 'epub' => 'application/epub+zip',
- 'mobi' => 'application/x-mobipocket-ebook',
- 'md' => 'text/markdown',
- 'markdown' => 'text/markdown',
- 'mdown' => 'text/markdown',
- 'mdwn' => 'text/markdown',
+ 'psd'=>'application/x-photoshop',
+ 'py'=>'text/x-script.python',
'reveal' => 'text/reveal',
- 'c' => 'text/x-c',
- 'cc' => 'text/x-c',
- 'cpp' => 'text/x-c++src',
- 'c++' => 'text/x-c++src',
- 'sh' => 'text/x-shellscript',
- 'bash' => 'text/x-shellscript',
+ 'sgf' => 'application/sgf',
'sh-lib' => 'text/x-shellscript',
+ 'sh' => 'text/x-shellscript',
+ 'svg'=>'image/svg+xml',
+ 'tar'=>'application/x-tar',
+ 'tar.gz'=>'application/x-compressed',
+ 'tgz'=>'application/x-compressed',
+ 'tiff'=>'image/tiff',
+ 'tif'=>'image/tiff',
+ 'txt'=>'text/plain',
+ 'vcard' => 'text/vcard',
+ 'vcf' => 'text/vcard',
+ 'wav'=>'audio/wav',
+ 'webm'=>'video/webm',
+ 'wmv'=>'video/x-ms-asf',
+ 'xcf'=>'application/x-gimp',
+ 'xls'=>'application/msexcel',
+ 'xlsx'=>'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'xml'=>'application/xml',
+ 'zip'=>'application/zip',
);
diff --git a/lib/private/request.php b/lib/private/request.php
index d9d5ae08e2..2c5b907846 100755
--- a/lib/private/request.php
+++ b/lib/private/request.php
@@ -11,6 +11,7 @@ class OC_Request {
const USER_AGENT_IE = '/MSIE/';
// Android Chrome user agent: https://developers.google.com/chrome/mobile/docs/user-agent
const USER_AGENT_ANDROID_MOBILE_CHROME = '#Android.*Chrome/[.0-9]*#';
+ const USER_AGENT_FREEBOX = '#^Mozilla/5\.0$#';
/**
* @brief Check overwrite condition
diff --git a/lib/private/response.php b/lib/private/response.php
index 0474643734..52dbb9d90f 100644
--- a/lib/private/response.php
+++ b/lib/private/response.php
@@ -153,7 +153,11 @@ class OC_Response {
* @param string $type disposition type, either 'attachment' or 'inline'
*/
static public function setContentDispositionHeader( $filename, $type = 'attachment' ) {
- if (OC_Request::isUserAgent(array(OC_Request::USER_AGENT_IE, OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME))) {
+ if (OC_Request::isUserAgent(array(
+ OC_Request::USER_AGENT_IE,
+ OC_Request::USER_AGENT_ANDROID_MOBILE_CHROME,
+ OC_Request::USER_AGENT_FREEBOX
+ ))) {
header( 'Content-Disposition: ' . rawurlencode($type) . '; filename="' . rawurlencode( $filename ) . '"' );
} else {
header( 'Content-Disposition: ' . rawurlencode($type) . '; filename*=UTF-8\'\'' . rawurlencode( $filename )
diff --git a/lib/private/server.php b/lib/private/server.php
index 2cbd37a97d..c9e593ec2e 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -138,6 +138,10 @@ class Server extends SimpleContainer implements IServerContainer {
$this->registerService('UserCache', function($c) {
return new UserCache();
});
+ $this->registerService('MemCacheFactory', function ($c) {
+ $instanceId = \OC_Util::getInstanceId();
+ return new \OC\Memcache\Factory($instanceId);
+ });
$this->registerService('ActivityManager', function($c) {
return new ActivityManager();
});
@@ -297,6 +301,15 @@ class Server extends SimpleContainer implements IServerContainer {
return $this->query('UserCache');
}
+ /**
+ * Returns an \OCP\CacheFactory instance
+ *
+ * @return \OCP\CacheFactory
+ */
+ function getMemCacheFactory() {
+ return $this->query('MemCacheFactory');
+ }
+
/**
* Returns the current session
*
diff --git a/lib/private/util.php b/lib/private/util.php
index 66a770a33d..b16c5980d7 100755
--- a/lib/private/util.php
+++ b/lib/private/util.php
@@ -788,8 +788,12 @@ class OC_Util {
}
$fp = @fopen($testFile, 'w');
- @fwrite($fp, $testContent);
- @fclose($fp);
+ if (!$fp) {
+ throw new OC\HintException('Can\'t create test file to check for working .htaccess file.',
+ 'Make sure it is possible for the webserver to write to '.$testFile);
+ }
+ fwrite($fp, $testContent);
+ fclose($fp);
// accessing the file via http
$url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$fileName);
diff --git a/lib/public/icachefactory.php b/lib/public/icachefactory.php
new file mode 100644
index 0000000000..874f1ec0a5
--- /dev/null
+++ b/lib/public/icachefactory.php
@@ -0,0 +1,28 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OCP;
+
+interface ICacheFactory{
+ /**
+ * Get a memory cache instance
+ *
+ * All entries added trough the cache instance will be namespaced by $prefix to prevent collisions between apps
+ *
+ * @param string $prefix
+ * @return \OCP\ICache
+ */
+ public function create($prefix = '');
+
+ /**
+ * Check if any memory cache backend is available
+ *
+ * @return bool
+ */
+ public function isAvailable();
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index b958d2d03f..5473f3ee33 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -141,6 +141,13 @@ interface IServerContainer {
*/
function getCache();
+ /**
+ * Returns an \OCP\CacheFactory instance
+ *
+ * @return \OCP\ICacheFactory
+ */
+ function getMemCacheFactory();
+
/**
* Returns the current session
*
diff --git a/lib/public/share.php b/lib/public/share.php
index f832d04a70..ae7d29e8b8 100644
--- a/lib/public/share.php
+++ b/lib/public/share.php
@@ -1152,7 +1152,7 @@ class Share {
$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `*PREFIX*share`.`parent`, `uid_owner`, '
.'`share_type`, `share_with`, `file_source`, `path`, `file_target`, '
.'`permissions`, `expiration`, `storage`, `*PREFIX*filecache`.`parent` as `file_parent`, '
- .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `encrypted`, `etag`, `mail_send`';
+ .'`name`, `mtime`, `mimetype`, `mimepart`, `size`, `unencrypted_size`, `encrypted`, `etag`, `mail_send`';
} else {
$select = '`*PREFIX*share`.`id`, `item_type`, `item_source`, `item_target`,
`*PREFIX*share`.`parent`, `share_type`, `share_with`, `uid_owner`,
diff --git a/lib/public/util.php b/lib/public/util.php
index 6317f10a66..d8497e29cf 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -88,14 +88,18 @@ class Util {
* @param Exception $ex exception to log
*/
public static function logException( $app, \Exception $ex ) {
- $message = $ex->getMessage();
+ $class = get_class($ex);
+ if ($class !== 'Exception') {
+ $message = $class . ': ';
+ }
+ $message .= $ex->getMessage();
if ($ex->getCode()) {
$message .= ' [' . $ex->getCode() . ']';
}
\OCP\Util::writeLog($app, 'Exception: ' . $message, \OCP\Util::FATAL);
if (defined('DEBUG') and DEBUG) {
// also log stack trace
- $stack = explode('#', $ex->getTraceAsString());
+ $stack = explode("\n", $ex->getTraceAsString());
// first element is empty
array_shift($stack);
foreach ($stack as $s) {
@@ -462,4 +466,23 @@ class Util {
public static function maxUploadFilesize($dir) {
return \OC_Helper::maxUploadFilesize($dir);
}
+
+ /**
+ * Calculate free space left within user quota
+ *
+ * @param $dir the current folder where the user currently operates
+ * @return number of bytes representing
+ */
+ public static function freeSpace($dir) {
+ return \OC_Helper::freeSpace($dir);
+ }
+
+ /**
+ * Calculate PHP upload limit
+ *
+ * @return number of bytes representing
+ */
+ public static function uploadLimit() {
+ return \OC_Helper::uploadLimit();
+ }
}
diff --git a/settings/img/log Icon License b/settings/img/log Icon License
deleted file mode 100644
index b5c3167d73..0000000000
--- a/settings/img/log Icon License
+++ /dev/null
@@ -1,2 +0,0 @@
-CC BY 3.0
-http://thenounproject.com/en-us/noun/printer/#icon-No109
\ No newline at end of file
diff --git a/settings/img/log.png b/settings/img/log.png
deleted file mode 100644
index b34a58f844..0000000000
Binary files a/settings/img/log.png and /dev/null differ
diff --git a/settings/img/log.svg b/settings/img/log.svg
deleted file mode 100644
index a3939b7309..0000000000
--- a/settings/img/log.svg
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
diff --git a/settings/templates/apps.php b/settings/templates/apps.php
index e04815f9b9..4c77c62f51 100644
--- a/settings/templates/apps.php
+++ b/settings/templates/apps.php
@@ -9,9 +9,11 @@
diff --git a/tests/karma.config.js b/tests/karma.config.js
index f73ade0f3c..529bd31338 100644
--- a/tests/karma.config.js
+++ b/tests/karma.config.js
@@ -29,25 +29,52 @@
* environment variable to the apps name, for example "core" or "files_encryption".
* Multiple apps can be specified by separating them with space.
*
+ * Setting the environment variable NOCOVERAGE to 1 will disable the coverage
+ * preprocessor, which is needed to be able to debug tests properly in a browser.
*/
+
+/* jshint node: true */
module.exports = function(config) {
+ function findApps() {
+ /*
+ var fs = require('fs');
+ var apps = fs.readdirSync('apps');
+ return apps;
+ */
+ // other apps tests don't run yet... needs further research / clean up
+ return ['files'];
+ }
+
+ // respect NOCOVERAGE env variable
+ // it is useful to disable coverage for debugging
+ // because the coverage preprocessor will wrap the JS files somehow
+ var enableCoverage = !parseInt(process.env.NOCOVERAGE, 10);
+ console.log('Coverage preprocessor: ', enableCoverage?'enabled':'disabled');
+
// default apps to test when none is specified (TODO: read from filesystem ?)
- var defaultApps = 'core files';
- var appsToTest = process.env.KARMA_TESTSUITE || defaultApps;
+ var appsToTest = process.env.KARMA_TESTSUITE;
+ if (appsToTest) {
+ appsToTest = appsToTest.split(' ');
+ }
+ else {
+ appsToTest = ['core'].concat(findApps());
+ }
+
+ console.log('Apps to test: ', appsToTest);
// read core files from core.json,
// these are required by all apps so always need to be loaded
// note that the loading order is important that's why they
// are specified in a separate file
var corePath = 'core/js/';
- var coreFiles = require('../' + corePath + 'core.json').modules;
+ var coreModule = require('../' + corePath + 'core.json');
var testCore = false;
var files = [];
var index;
+ var preprocessors = {};
// find out what apps to test from appsToTest
- appsToTest = appsToTest.split(' ');
index = appsToTest.indexOf('core');
if (index > -1) {
appsToTest.splice(index, 1);
@@ -60,11 +87,23 @@ module.exports = function(config) {
// core mocks
files.push(corePath + 'tests/specHelper.js');
- // add core files
- for ( var i = 0; i < coreFiles.length; i++ ) {
- files.push( corePath + coreFiles[i] );
+ // add core library files
+ for ( var i = 0; i < coreModule.libraries.length; i++ ) {
+ var srcFile = corePath + coreModule.libraries[i];
+ files.push(srcFile);
}
+ // add core modules files
+ for ( var i = 0; i < coreModule.modules.length; i++ ) {
+ var srcFile = corePath + coreModule.modules[i];
+ files.push(srcFile);
+ if (enableCoverage) {
+ preprocessors[srcFile] = 'coverage';
+ }
+ }
+
+ // TODO: settings pages
+
// need to test the core app as well ?
if (testCore) {
// core tests
@@ -73,7 +112,11 @@ module.exports = function(config) {
for ( var i = 0; i < appsToTest.length; i++ ) {
// add app JS
- files.push('apps/' + appsToTest[i] + '/js/*.js');
+ var srcFile = 'apps/' + appsToTest[i] + '/js/*.js';
+ files.push(srcFile);
+ if (enableCoverage) {
+ preprocessors[srcFile] = 'coverage';
+ }
// add test specs
files.push('apps/' + appsToTest[i] + '/tests/js/*.js');
}
@@ -83,7 +126,6 @@ module.exports = function(config) {
// base path, that will be used to resolve files and exclude
basePath: '..',
-
// frameworks to use
frameworks: ['jasmine'],
@@ -106,9 +148,7 @@ module.exports = function(config) {
// web server port
port: 9876,
- preprocessors: {
- 'apps/files/js/*.js': 'coverage'
- },
+ preprocessors: preprocessors,
coverageReporter: {
dir:'tests/karma-coverage',
diff --git a/tests/lib/errorHandler.php b/tests/lib/errorHandler.php
new file mode 100644
index 0000000000..68b87deccb
--- /dev/null
+++ b/tests/lib/errorHandler.php
@@ -0,0 +1,62 @@
+
+ *
+ * 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 .
+ *
+ */
+
+class Test_ErrorHandler extends \PHPUnit_Framework_TestCase {
+
+ /**
+ * @brief provide username, password combinations for testRemovePassword
+ * @return array
+ */
+ function passwordProvider() {
+ return array(
+ array('user', 'password'),
+ array('user@owncloud.org', 'password'),
+ array('user', 'pass@word'),
+ array('us:er', 'password'),
+ array('user', 'pass:word'),
+ );
+
+ }
+
+ /**
+ * @dataProvider passwordProvider
+ * @param string $username
+ * @param string $password
+ */
+ function testRemovePassword($username, $password) {
+ $url = 'http://'.$username.':'.$password.'@owncloud.org';
+ $expectedResult = 'http://xxx:xxx@owncloud.org';
+ $result = TestableErrorHandler::testRemovePassword($url);
+
+ $this->assertEquals($expectedResult, $result);
+ }
+
+}
+
+/**
+ * @brief dummy class to access protected methods of \OC\Log\ErrorHandler
+ */
+class TestableErrorHandler extends \OC\Log\ErrorHandler {
+ public static function testRemovePassword($msg) {
+ return self::removePassword($msg);
+ }
+}
diff --git a/tests/lib/request.php b/tests/lib/request.php
index c6401a5714..1d77acc70a 100644
--- a/tests/lib/request.php
+++ b/tests/lib/request.php
@@ -118,6 +118,21 @@ class Test_Request extends PHPUnit_Framework_TestCase {
),
true
),
+ array(
+ 'Mozilla/5.0 (X11; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
+ OC_Request::USER_AGENT_FREEBOX,
+ false
+ ),
+ array(
+ 'Mozilla/5.0',
+ OC_Request::USER_AGENT_FREEBOX,
+ true
+ ),
+ array(
+ 'Fake Mozilla/5.0',
+ OC_Request::USER_AGENT_FREEBOX,
+ false
+ ),
);
}
}