aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/files/type/detection.php127
-rw-r--r--lib/private/helper.php5
-rw-r--r--lib/private/server.php18
-rw-r--r--lib/public/files/imimetypedetector.php78
-rw-r--r--lib/public/iservercontainer.php9
-rw-r--r--tests/lib/files/type/detection.php97
6 files changed, 333 insertions, 1 deletions
diff --git a/lib/private/files/type/detection.php b/lib/private/files/type/detection.php
index 3287375bc79..571062061df 100644
--- a/lib/private/files/type/detection.php
+++ b/lib/private/files/type/detection.php
@@ -4,6 +4,7 @@
* @author Jens-Christian Fischer <jens-christian.fischer@switch.ch>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Tanghus <thomas@tanghus.net>
*
* @copyright Copyright (c) 2015, ownCloud, Inc.
@@ -25,6 +26,8 @@
namespace OC\Files\Type;
+use OCP\Files\IMimeTypeDetector;
+
/**
* Class Detection
*
@@ -32,10 +35,85 @@ namespace OC\Files\Type;
*
* @package OC\Files\Type
*/
-class Detection {
+class Detection implements IMimeTypeDetector {
protected $mimetypes = array();
protected $secureMimeTypes = array();
+ protected $mimetypeIcons = [];
+ /** @var string[] */
+ protected $mimeTypeAlias = [
+ 'application/octet-stream' => 'file', // use file icon as fallback
+
+ 'application/illustrator' => 'image/vector',
+ 'application/postscript' => 'image/vector',
+ 'image/svg+xml' => 'image/vector',
+
+ 'application/coreldraw' => 'image',
+ 'application/x-gimp' => 'image',
+ 'application/x-photoshop' => 'image',
+ 'application/x-dcraw' => 'image',
+
+ 'application/font-sfnt' => 'font',
+ 'application/x-font' => 'font',
+ 'application/font-woff' => 'font',
+ 'application/vnd.ms-fontobject' => 'font',
+
+ 'application/json' => 'text/code',
+ 'application/x-perl' => 'text/code',
+ 'application/x-php' => 'text/code',
+ 'text/x-shellscript' => 'text/code',
+ 'application/yaml' => 'text/code',
+ 'application/xml' => 'text/html',
+ 'text/css' => 'text/code',
+ 'application/x-tex' => 'text',
+
+ 'application/x-compressed' => 'package/x-generic',
+ 'application/x-7z-compressed' => 'package/x-generic',
+ 'application/x-deb' => 'package/x-generic',
+ 'application/x-gzip' => 'package/x-generic',
+ 'application/x-rar-compressed' => 'package/x-generic',
+ 'application/x-tar' => 'package/x-generic',
+ 'application/vnd.android.package-archive' => 'package/x-generic',
+ 'application/zip' => 'package/x-generic',
+
+ 'application/msword' => 'x-office/document',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'x-office/document',
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => 'x-office/document',
+ 'application/vnd.ms-word.document.macroEnabled.12' => 'x-office/document',
+ 'application/vnd.ms-word.template.macroEnabled.12' => 'x-office/document',
+ 'application/vnd.oasis.opendocument.text' => 'x-office/document',
+ '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',
+ 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => 'x-office/presentation',
+ 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => 'x-office/presentation',
+ 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => 'x-office/presentation',
+ 'application/vnd.ms-powerpoint.template.macroEnabled.12' => 'x-office/presentation',
+ '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',
+ 'application/vnd.ms-excel.sheet.macroEnabled.12' => 'x-office/spreadsheet',
+ 'application/vnd.ms-excel.template.macroEnabled.12' => 'x-office/spreadsheet',
+ 'application/vnd.ms-excel.addin.macroEnabled.12' => 'x-office/spreadsheet',
+ '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',
+ 'text/csv' => 'x-office/spreadsheet',
+
+ 'application/msaccess' => 'database',
+ ];
+
+
/**
* Add an extension -> mimetype mapping
*
@@ -170,4 +248,51 @@ class Detection {
? $this->secureMimeTypes[$mimeType]
: 'application/octet-stream';
}
+
+ /**
+ * Get path to the icon of a file type
+ * @param string $mimeType the MIME type
+ * @return string the url
+ */
+ public function mimeTypeIcon($mimetype) {
+ if (isset($this->mimeTypeAlias[$mimetype])) {
+ $mimetype = $this->mimeTypeAlias[$mimetype];
+ }
+ if (isset($this->mimetypeIcons[$mimetype])) {
+ return $this->mimetypeIcons[$mimetype];
+ }
+ // Replace slash and backslash with a minus
+ $icon = str_replace('/', '-', $mimetype);
+ $icon = str_replace('\\', '-', $icon);
+
+ // Is it a dir?
+ if ($mimetype === 'dir') {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/folder.png';
+ return OC::$WEBROOT . '/core/img/filetypes/folder.png';
+ }
+ if ($mimetype === 'dir-shared') {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/folder-shared.png';
+ return OC::$WEBROOT . '/core/img/filetypes/folder-shared.png';
+ }
+ if ($mimetype === 'dir-external') {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/folder-external.png';
+ return OC::$WEBROOT . '/core/img/filetypes/folder-external.png';
+ }
+
+ // Icon exists?
+ if (file_exists(OC::$SERVERROOT . '/core/img/filetypes/' . $icon . '.png')) {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/' . $icon . '.png';
+ return OC::$WEBROOT . '/core/img/filetypes/' . $icon . '.png';
+ }
+
+ // Try only the first part of the filetype
+ $mimePart = substr($icon, 0, strpos($icon, '-'));
+ if (file_exists(OC::$SERVERROOT . '/core/img/filetypes/' . $mimePart . '.png')) {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/' . $mimePart . '.png';
+ return OC::$WEBROOT . '/core/img/filetypes/' . $mimePart . '.png';
+ } else {
+ $this->mimetypeIcons[$mimetype] = OC::$WEBROOT . '/core/img/filetypes/file.png';
+ return OC::$WEBROOT . '/core/img/filetypes/file.png';
+ }
+ }
}
diff --git a/lib/private/helper.php b/lib/private/helper.php
index ed954f87630..09f0ba1da3c 100644
--- a/lib/private/helper.php
+++ b/lib/private/helper.php
@@ -183,6 +183,7 @@ class OC_Helper {
* @return string the url
*
* Returns the path to the image of this file type.
+ * @deprecated Use \OC::$server->getMimeTypeDetector()->mimeTypeIcon($mimetype)
*/
public static function mimetypeIcon($mimetype) {
@@ -465,6 +466,7 @@ class OC_Helper {
*
* @param string $path
* @return string
+ * @deprecated Use \OC::$server->getMimeTypeDetector()->detectPath($path)
*/
static public function getFileNameMimeType($path) {
return self::getMimetypeDetector()->detectPath($path);
@@ -476,6 +478,7 @@ class OC_Helper {
* @param string $path
* @return string
* does NOT work for ownClouds filesystem, use OC_FileSystem::getMimeType instead
+ * @deprecated Use \OC::$server->getMimeTypeDetector()->detect($path)
*/
static function getMimeType($path) {
return self::getMimetypeDetector()->detect($path);
@@ -486,6 +489,7 @@ class OC_Helper {
*
* @param string $mimeType
* @return string
+ * @deprecated Use \OC::$server->getMimeTypeDetector()->getSecureMimeType($mimeType)
*/
static function getSecureMimeType($mimeType) {
return self::getMimetypeDetector()->getSecureMimeType($mimeType);
@@ -496,6 +500,7 @@ class OC_Helper {
*
* @param string $data
* @return string
+ * @deprecated Use \OC::$server->getMimeTypeDetector->detectString($data)
*/
static function getStringMimeType($data) {
return self::getMimetypeDetector()->detectString($data);
diff --git a/lib/private/server.php b/lib/private/server.php
index 53949b53df7..7aa331884b6 100644
--- a/lib/private/server.php
+++ b/lib/private/server.php
@@ -12,6 +12,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
* @author Robin McCorkell <rmccorkell@karoshi.org.uk>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Sander <brantje@gmail.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Thomas Tanghus <thomas@tanghus.net>
@@ -58,6 +59,7 @@ use OC\Security\SecureRandom;
use OC\Security\TrustedDomainHelper;
use OC\Tagging\TagMapper;
use OCP\IServerContainer;
+use OC\Files\Type\Detection;
/**
* Class Server
@@ -443,6 +445,13 @@ class Server extends SimpleContainer implements IServerContainer {
$this->registerService('MountManager', function () {
return new \OC\Files\Mount\Manager();
});
+ $this->registerService('MimeTypeDetector', function(Server $c) {
+ $mimeTypeDetector = new Detection();
+ $dist = file_get_contents(\OC::$configDir . '/mimetypemapping.dist.json');
+ $mimetypemapping = get_object_vars(json_decode($dist));
+ $mimeTypeDetector->registerTypeArray($mimetypemapping);
+ return $mimeTypeDetector;
+ });
}
/**
@@ -930,4 +939,13 @@ class Server extends SimpleContainer implements IServerContainer {
function getMountManager() {
return $this->query('MountManager');
}
+
+ /*
+ * Get the MimeTypeDetector
+ *
+ * @return \OCP\Files\IMimeTypeDetector
+ */
+ public function getMimeTypeDetector() {
+ return $this->query('MimeTypeDetector');
+ }
}
diff --git a/lib/public/files/imimetypedetector.php b/lib/public/files/imimetypedetector.php
new file mode 100644
index 00000000000..79ed8a4fac9
--- /dev/null
+++ b/lib/public/files/imimetypedetector.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+// use OCP namespace for all classes that are considered public.
+// This means that they should be used by apps instead of the internal ownCloud classes
+namespace OCP\Files;
+
+
+/**
+ * Interface IMimeTypeDetector
+ * @package OCP\Files
+ * @since 8.2.0
+ *
+ * Interface to handle mimetypes (detection and icon retrieval)
+ **/
+interface IMimeTypeDetector {
+
+ /**
+ * detect mimetype only based on filename, content of file is not used
+ * @param string $path
+ * @return string
+ * @since 8.2.0
+ **/
+ public function detectPath($path);
+
+ /**
+ * detect mimetype based on both filename and content
+ *
+ * @param string $path
+ * @return string
+ * @since 8.2.0
+ */
+ public function detect($path);
+
+ /**
+ * Get a secure mimetype that won't expose potential XSS.
+ *
+ * @param string $mimeType
+ * @return string
+ * @since 8.2.0
+ */
+ public function getSecureMimeType($mimeType);
+
+ /**
+ * detect mimetype based on the content of a string
+ *
+ * @param string $data
+ * @return string
+ * @since 8.2.0
+ */
+ public function detectString($data);
+
+ /**
+ * Get path to the icon of a file type
+ * @param string $mimeType the MIME type
+ * @return string the url
+ * @since 8.2.0
+ */
+ public function mimeTypeIcon($mimeType);
+}
diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php
index 95ee853d84c..f3165db33da 100644
--- a/lib/public/iservercontainer.php
+++ b/lib/public/iservercontainer.php
@@ -9,6 +9,7 @@
* @author Lukas Reschke <lukas@owncloud.com>
* @author Morris Jobke <hey@morrisjobke.de>
* @author Robin Appelman <icewind@owncloud.com>
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Thomas Tanghus <thomas@tanghus.net>
*
@@ -429,4 +430,12 @@ interface IServerContainer {
* @since 8.2.0
*/
public function getMountManager();
+
+ /**
+ * Get the MimeTypeDetector
+ *
+ * @return \OCP\Files\IMimeTypeDetector
+ * @since 8.2.0
+ */
+ public function getMimeTypeDetector();
}
diff --git a/tests/lib/files/type/detection.php b/tests/lib/files/type/detection.php
new file mode 100644
index 00000000000..1483839bf7f
--- /dev/null
+++ b/tests/lib/files/type/detection.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * @author Roeland Jago Douma <roeland@famdouma.nl>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OC\Files\Type;
+
+use \OC\Files\Type\Detection;
+
+class DetectionTest extends \Test\TestCase {
+
+ public function testDetect() {
+ $detection = new Detection();
+ $dir = \OC::$SERVERROOT.'/tests/data';
+
+ $result = $detection->detect($dir."/");
+ $expected = 'httpd/unix-directory';
+ $this->assertEquals($expected, $result);
+
+ $result = $detection->detect($dir."/data.tar.gz");
+ $expected = 'application/x-gzip';
+ $this->assertEquals($expected, $result);
+
+ $result = $detection->detect($dir."/data.zip");
+ $expected = 'application/zip';
+ $this->assertEquals($expected, $result);
+
+ $result = $detection->detect($dir."/testimagelarge.svg");
+ $expected = 'image/svg+xml';
+ $this->assertEquals($expected, $result);
+
+ $result = $detection->detect($dir."/testimage.png");
+ $expected = 'image/png';
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testGetSecureMimeType() {
+ $detection = new Detection();
+ $dist = file_get_contents(\OC::$configDir . '/mimetypemapping.dist.json');
+ $mimetypemapping = get_object_vars(json_decode($dist));
+ $detection->registerTypeArray($mimetypemapping);
+
+ $result = $detection->getSecureMimeType('image/svg+xml');
+ $expected = 'text/plain';
+ $this->assertEquals($expected, $result);
+
+ $result = $detection->getSecureMimeType('image/png');
+ $expected = 'image/png';
+ $this->assertEquals($expected, $result);
+ }
+
+ public function testDetectPath() {
+ $detection = new Detection();
+ $dist = file_get_contents(\OC::$configDir . '/mimetypemapping.dist.json');
+ $mimetypemapping = get_object_vars(json_decode($dist));
+ $detection->registerTypeArray($mimetypemapping);
+
+ $this->assertEquals('text/plain', $detection->detectPath('foo.txt'));
+ $this->assertEquals('image/png', $detection->detectPath('foo.png'));
+ $this->assertEquals('image/png', $detection->detectPath('foo.bar.png'));
+ $this->assertEquals('application/octet-stream', $detection->detectPath('.png'));
+ $this->assertEquals('application/octet-stream', $detection->detectPath('foo'));
+ $this->assertEquals('application/octet-stream', $detection->detectPath(''));
+ }
+
+ public function testDetectString() {
+ if (\OC_Util::runningOnWindows()) {
+ $this->markTestSkipped('[Windows] Strings have mimetype application/octet-stream on Windows');
+ }
+
+ $detection = new Detection();
+ $dist = file_get_contents(\OC::$configDir . '/mimetypemapping.dist.json');
+ $mimetypemapping = get_object_vars(json_decode($dist));
+ $detection->registerTypeArray($mimetypemapping);
+
+ $result = $detection->detectString("/data/data.tar.gz");
+ $expected = 'text/plain; charset=us-ascii';
+ $this->assertEquals($expected, $result);
+ }
+
+}