From 810f99c1c906b754d89df675965febe820f0bcda Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 2 Sep 2016 13:29:30 +0200 Subject: [PATCH 1/3] Correctly remove the charset from finfo mimetype --- lib/private/Files/Type/Detection.php | 5 +++-- tests/lib/Files/Type/DetectionTest.php | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/private/Files/Type/Detection.php b/lib/private/Files/Type/Detection.php index 492025b7bf..66ef0dd2aa 100644 --- a/lib/private/Files/Type/Detection.php +++ b/lib/private/Files/Type/Detection.php @@ -200,7 +200,7 @@ class Detection implements IMimeTypeDetector { $info = @strtolower(finfo_file($finfo, $path)); finfo_close($finfo); if ($info) { - $mimeType = substr($info, 0, strpos($info, ';')); + $mimeType = strpos($info, ';') !== false ? substr($info, 0, strpos($info, ';')) : $info; return empty($mimeType) ? 'application/octet-stream' : $mimeType; } @@ -238,7 +238,8 @@ class Detection implements IMimeTypeDetector { public function detectString($data) { if (function_exists('finfo_open') and function_exists('finfo_file')) { $finfo = finfo_open(FILEINFO_MIME); - return finfo_buffer($finfo, $data); + $info = finfo_buffer($finfo, $data); + return strpos($info, ';') !== false ? substr($info, 0, strpos($info, ';')) : $info; } else { $tmpFile = \OC::$server->getTempManager()->getTemporaryFile(); $fh = fopen($tmpFile, 'wb'); diff --git a/tests/lib/Files/Type/DetectionTest.php b/tests/lib/Files/Type/DetectionTest.php index 7b9dc1b3e4..11267ee2e7 100644 --- a/tests/lib/Files/Type/DetectionTest.php +++ b/tests/lib/Files/Type/DetectionTest.php @@ -81,7 +81,7 @@ class DetectionTest extends \Test\TestCase { public function testDetectString() { $result = $this->detection->detectString("/data/data.tar.gz"); - $expected = 'text/plain; charset=us-ascii'; + $expected = 'text/plain'; $this->assertEquals($expected, $result); } From d3a1fbd9ebf7a1582c21b6dfa65af65cb890616b Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 2 Sep 2016 13:37:23 +0200 Subject: [PATCH 2/3] Better detection of mimetypes while uploading a zip on a mac --- .../workflowengine/lib/Check/FileMimeType.php | 60 +++++++++++++++---- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/apps/workflowengine/lib/Check/FileMimeType.php b/apps/workflowengine/lib/Check/FileMimeType.php index 1de9a70a17..43c856a7c9 100644 --- a/apps/workflowengine/lib/Check/FileMimeType.php +++ b/apps/workflowengine/lib/Check/FileMimeType.php @@ -23,12 +23,13 @@ namespace OCA\WorkflowEngine\Check; use OCP\Files\IMimeTypeDetector; +use OCP\Files\Storage\IStorage; use OCP\IL10N; use OCP\IRequest; class FileMimeType extends AbstractStringCheck { - /** @var string */ + /** @var array */ protected $mimeType; /** @var IRequest */ @@ -37,6 +38,12 @@ class FileMimeType extends AbstractStringCheck { /** @var IMimeTypeDetector */ protected $mimeTypeDetector; + /** @var IStorage */ + protected $storage; + + /** @var string */ + protected $path; + /** * @param IL10N $l * @param IRequest $request @@ -48,27 +55,58 @@ class FileMimeType extends AbstractStringCheck { $this->mimeTypeDetector = $mimeTypeDetector; } + /** + * @param IStorage $storage + * @param string $path + */ + public function setFileInfo(IStorage $storage, $path) { + $this->storage = $storage; + $this->path = $path; + if (!isset($this->mimeType[$this->storage->getId()][$this->path]) + || $this->mimeType[$this->storage->getId()][$this->path] === '') { + $this->mimeType[$this->storage->getId()][$this->path] = null; + } + } + /** * @return string */ protected function getActualValue() { - if ($this->mimeType !== null) { - return $this->mimeType; + if ($this->mimeType[$this->storage->getId()][$this->path] !== null) { + return $this->mimeType[$this->storage->getId()][$this->path]; } - $this->mimeType = ''; + $this->mimeType[$this->storage->getId()][$this->path] = ''; if ($this->isWebDAVRequest()) { if ($this->request->getMethod() === 'PUT') { $path = $this->request->getPathInfo(); - $this->mimeType = $this->mimeTypeDetector->detectPath($path); - } - } else if (in_array($this->request->getMethod(), ['POST', 'PUT'])) { - $files = $this->request->getUploadedFile('files'); - if (isset($files['type'][0])) { - $this->mimeType = $files['type'][0]; + $this->mimeType[$this->storage->getId()][$this->path] = $this->mimeTypeDetector->detectPath($path); + return $this->mimeType[$this->storage->getId()][$this->path]; } } - return $this->mimeType; + + if (in_array($this->request->getMethod(), ['POST', 'PUT'])) { + $files = $this->request->getUploadedFile('files'); + if (isset($files['type'][0])) { + $mimeType = $files['type'][0]; + if ($this->mimeType === 'application/octet-stream') { + // Maybe not... + $mimeTypeTest = $this->mimeTypeDetector->detectPath($files['name'][0]); + if ($mimeTypeTest !== 'application/octet-stream' && $mimeTypeTest !== false) { + $mimeType = $mimeTypeTest; + } else { + $mimeTypeTest = $this->mimeTypeDetector->detect($files['tmp_name'][0]); + if ($mimeTypeTest !== 'application/octet-stream' && $mimeTypeTest !== false) { + $mimeType = $mimeTypeTest; + } + } + } + $this->mimeType[$this->storage->getId()][$this->path] = $mimeType; + return $mimeType; + } + } + + return $this->mimeType[$this->storage->getId()][$this->path]; } /** From 5996983e28cdfa7d96b71f0fe3c030ba248bf104 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 2 Sep 2016 13:38:27 +0200 Subject: [PATCH 3/3] Make mimetype also work for READ and DELETE operations --- apps/workflowengine/js/filemimetypeplugin.js | 2 +- .../workflowengine/lib/Check/FileMimeType.php | 39 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/apps/workflowengine/js/filemimetypeplugin.js b/apps/workflowengine/js/filemimetypeplugin.js index 33cbbd7fd7..9fc9e3452f 100644 --- a/apps/workflowengine/js/filemimetypeplugin.js +++ b/apps/workflowengine/js/filemimetypeplugin.js @@ -27,7 +27,7 @@ getCheck: function() { return { 'class': 'OCA\\WorkflowEngine\\Check\\FileMimeType', - 'name': t('workflowengine', 'File mime type (upload)'), + 'name': t('workflowengine', 'File mime type'), 'operators': [ {'operator': 'is', 'name': t('workflowengine', 'is')}, {'operator': '!is', 'name': t('workflowengine', 'is not')}, diff --git a/apps/workflowengine/lib/Check/FileMimeType.php b/apps/workflowengine/lib/Check/FileMimeType.php index 43c856a7c9..4a985840e6 100644 --- a/apps/workflowengine/lib/Check/FileMimeType.php +++ b/apps/workflowengine/lib/Check/FileMimeType.php @@ -106,9 +106,48 @@ class FileMimeType extends AbstractStringCheck { } } + $this->mimeType[$this->storage->getId()][$this->path] = $this->storage->getMimeType($this->path); + if ($this->mimeType[$this->storage->getId()][$this->path] === 'application/octet-stream') { + $this->mimeType[$this->storage->getId()][$this->path] = $this->detectMimetypeFromPath(); + } + return $this->mimeType[$this->storage->getId()][$this->path]; } + /** + * @return string + */ + protected function detectMimetypeFromPath() { + $mimeType = $this->mimeTypeDetector->detectPath($this->path); + if ($mimeType !== 'application/octet-stream' && $mimeType !== false) { + return $mimeType; + } + + if ($this->storage->instanceOfStorage('\OC\Files\Storage\Local') + || $this->storage->instanceOfStorage('\OC\Files\Storage\Home') + || $this->storage->instanceOfStorage('\OC\Files\ObjectStore\HomeObjectStoreStorage')) { + $localFile = $this->storage->getLocalFile($this->path); + if ($localFile !== false) { + $mimeType = $this->mimeTypeDetector->detect($localFile); + if ($mimeType !== false) { + return $mimeType; + } + } + + return 'application/octet-stream'; + } else { + $handle = $this->storage->fopen($this->path, 'r'); + $data = fread($handle, 8024); + fclose($handle); + $mimeType = $this->mimeTypeDetector->detectString($data); + if ($mimeType !== false) { + return $mimeType; + } + + return 'application/octet-stream'; + } + } + /** * @return bool */