From 807f91b45ba74594c705fdb4d727d0ad5dc69554 Mon Sep 17 00:00:00 2001 From: Matthias Glaub Date: Wed, 20 Oct 2021 16:15:56 +0200 Subject: [PATCH 01/26] add reverse matching of mimetype to possible extensions --- src/GeneratedExtensionToMimeTypeMap.php | 12 ++++++++++ src/GeneratedExtensionToMimeTypeMapTest.php | 23 +++++++++++++++++++ .../ExtensionToMimeTypeMap.php.template | 12 ++++++++++ 3 files changed, 47 insertions(+) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 13a97f9..0d3e214 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -1215,4 +1215,16 @@ public function lookupMimeType(string $extension): ?string { return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; } + + /** + * @param string $mimeType + * @return string[] + */ + public function lookupExtensions(string $mimeType): array + { + return array_keys(array_filter(self::MIME_TYPES_FOR_EXTENSIONS, function ($mimeTypeFromArray) use ($mimeType + ): bool { + return $mimeType === $mimeTypeFromArray; + })); + } } diff --git a/src/GeneratedExtensionToMimeTypeMapTest.php b/src/GeneratedExtensionToMimeTypeMapTest.php index 0968a33..16f45f8 100644 --- a/src/GeneratedExtensionToMimeTypeMapTest.php +++ b/src/GeneratedExtensionToMimeTypeMapTest.php @@ -49,4 +49,27 @@ public function the_generated_map_should_be_up_to_date(): void $this->assertEquals($source, $storedSource); } + + /** + * @test + * @dataProvider expectedExtensionResults + */ + public function looking_up_extensions($mimeType, $expectedExtensions): void + { + $map = new GeneratedExtensionToMimeTypeMap(); + $actual = $map->lookupExtensions($mimeType); + + sort($expectedExtensions); + sort($actual); + + $this->assertEquals($expectedExtensions, $actual); + } + + public function expectedExtensionResults(): Generator + { + yield ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', ['docx']]; + yield ['image/jpeg', ['jpg', 'jpeg', 'jpe']]; + yield ['image/svg+xml', ['svg', 'svgz']]; + yield ['lol/lol', []]; + } } diff --git a/src/Generation/ExtensionToMimeTypeMap.php.template b/src/Generation/ExtensionToMimeTypeMap.php.template index 9d4e600..e581234 100644 --- a/src/Generation/ExtensionToMimeTypeMap.php.template +++ b/src/Generation/ExtensionToMimeTypeMap.php.template @@ -17,4 +17,16 @@ class ExtensionToMimeTypeMapClass implements ExtensionToMimeTypeMap { return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; } + + /** + * @param string $mimeType + * @return string[] + */ + public function lookupExtensions(string $mimeType): array + { + return array_keys(array_filter(self::MIME_TYPES_FOR_EXTENSIONS, function ($mimeTypeFromArray) use ($mimeType + ): bool { + return $mimeType === $mimeTypeFromArray; + })); + } } From dd3985a597ea29d9dd45fb4e9120cf0b18403e29 Mon Sep 17 00:00:00 2001 From: Matthias Glaub Date: Wed, 20 Oct 2021 19:55:43 +0200 Subject: [PATCH 02/26] fixes missing typehints --- src/GeneratedExtensionToMimeTypeMapTest.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/GeneratedExtensionToMimeTypeMapTest.php b/src/GeneratedExtensionToMimeTypeMapTest.php index 16f45f8..5ff918e 100644 --- a/src/GeneratedExtensionToMimeTypeMapTest.php +++ b/src/GeneratedExtensionToMimeTypeMapTest.php @@ -53,8 +53,10 @@ public function the_generated_map_should_be_up_to_date(): void /** * @test * @dataProvider expectedExtensionResults + * @param string $mimeType + * @param string[] $expectedExtensions */ - public function looking_up_extensions($mimeType, $expectedExtensions): void + public function looking_up_extensions(string $mimeType, array $expectedExtensions): void { $map = new GeneratedExtensionToMimeTypeMap(); $actual = $map->lookupExtensions($mimeType); From a526a3692503e64899c5f835162e71150b85ac65 Mon Sep 17 00:00:00 2001 From: Fabien Villepinte Date: Wed, 6 Oct 2021 13:45:43 +0200 Subject: [PATCH 03/26] Upgrade PHP-CS-Fixer to 3.x --- .gitattributes | 2 +- .github/workflows/quality-assurance.yml | 2 +- .gitignore | 3 ++- .php_cs.dist => .php-cs-fixer.dist.php | 4 ++-- composer.json | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) rename .php_cs.dist => .php-cs-fixer.dist.php (91%) diff --git a/.gitattributes b/.gitattributes index 7d3749f..5934914 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,7 +3,7 @@ /phpstan.neon export-ignore /bin export-ignore /.github export-ignore -/.php_cs.dist export-ignore +/.php-cs-fixer.dist.php export-ignore /.scrutinizer.yml export-ignore /src/Generation export-ignore /test_files export-ignore diff --git a/.github/workflows/quality-assurance.yml b/.github/workflows/quality-assurance.yml index ef8fee7..3649ab8 100644 --- a/.github/workflows/quality-assurance.yml +++ b/.github/workflows/quality-assurance.yml @@ -39,6 +39,6 @@ jobs: - run: COMPOSER_OPTS='${{ matrix.composer-flags }}' vendor/bin/phpunit ${{ matrix.phpunit-flags }} - run: vendor/bin/phpstan analyse -l 6 src if: ${{ matrix.php == '7.4' }} - - run: vendor/bin/php-cs-fixer fix --dry-run + - run: vendor/bin/php-cs-fixer fix --diff --dry-run if: ${{ matrix.php == '7.4' }} diff --git a/.gitignore b/.gitignore index abda3f3..cb06ef3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /vendor/ /coverage/ /.phpunit.result.cache -/.php_cs.cache +/.php-cs-fixer.php +/.php-cs-fixer.cache /phpunit.xml /composer.lock diff --git a/.php_cs.dist b/.php-cs-fixer.dist.php similarity index 91% rename from .php_cs.dist rename to .php-cs-fixer.dist.php index 6820cf8..da6a281 100644 --- a/.php_cs.dist +++ b/.php-cs-fixer.dist.php @@ -4,13 +4,13 @@ ->in([__DIR__ . '/src']) ; -return PhpCsFixer\Config::create() +return (new PhpCsFixer\Config()) ->setRules([ '@PSR2' => true, 'array_syntax' => ['syntax' => 'short'], 'binary_operator_spaces' => true, 'single_line_after_imports' => true, - 'blank_line_before_return' => true, + 'blank_line_before_statement' => ['statements' => ['return']], 'cast_spaces' => true, 'concat_space' => ['spacing' => 'one'], 'no_singleline_whitespace_before_semicolons' => true, diff --git a/composer.json b/composer.json index 765b05c..455f8fb 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "require-dev": { "phpunit/phpunit": "^8.5.8 || ^9.3", "phpstan/phpstan": "^0.12.68", - "friendsofphp/php-cs-fixer": "^2.18" + "friendsofphp/php-cs-fixer": "^3.2" }, "autoload": { "psr-4": { From 88f38047d6ac08e71b31f944cee8449ec10fef30 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sun, 21 Nov 2021 12:46:17 +0100 Subject: [PATCH 04/26] Updated types --- src/GeneratedExtensionToMimeTypeMap.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 0d3e214..3fabdae 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -37,6 +37,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'aep' => 'application/vnd.audiograph', 'afm' => 'application/x-font-type1', 'afp' => 'application/vnd.ibm.modcap', + 'age' => 'application/vnd.age', 'ahead' => 'application/vnd.ahead.space', 'ai' => 'application/pdf', 'aif' => 'audio/x-aiff', @@ -321,6 +322,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'gca' => 'application/x-gca-compressed', 'gdl' => 'model/vnd.gdl', 'gdoc' => 'application/vnd.google-apps.document', + 'ged' => 'text/vnd.familysearch.gedcom', 'geo' => 'application/vnd.dynageo', 'geojson' => 'application/geo+json', 'gex' => 'application/vnd.geometry-explorer', From 67fb7c55090c39b89a51896f37a30f592a8c6a65 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sun, 21 Nov 2021 12:47:36 +0100 Subject: [PATCH 05/26] Register test script --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 455f8fb..80ca1af 100644 --- a/composer.json +++ b/composer.json @@ -9,6 +9,7 @@ } ], "scripts": { + "test": "vendor/bin/phpunit", "phpstan": "vendor/bin/phpstan analyse -l 6 src" }, "require": { From ef383a28a914512dd86eafb3e3ce248a05577a6b Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sun, 21 Nov 2021 12:48:40 +0100 Subject: [PATCH 06/26] Prepare for 1.9.0 --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad24408..9f296f2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog -## 1.8.0 - 2021-09-25 +## 1.9.0 - 2021-11-21 + +### Updated + +- Updated lookup + +- ## 1.8.0 - 2021-09-25 ### Added From 0a7c93cece32dcb0ba4f521fd5e320f4c886694f Mon Sep 17 00:00:00 2001 From: Phil Davis Date: Sun, 21 Nov 2021 18:04:15 +0545 Subject: [PATCH 07/26] fix 1.8.0 heading in CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f296f2..b9c4814 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ - Updated lookup -- ## 1.8.0 - 2021-09-25 +## 1.8.0 - 2021-09-25 ### Added From 1520a3aec713f32572cdefed4eb4277d00421a3c Mon Sep 17 00:00:00 2001 From: Robin Gustafsson Date: Sat, 27 Nov 2021 00:14:21 +0100 Subject: [PATCH 08/26] Inherit PHPUnit's TestCase instead of PHPStan's One of the test classes inherits PHPStan's UnitTest class instead of the usual PHPUnit TestCase. It seems to give identical behavior in this test, and sticking to the typical PHPUnit class is more consistent. --- src/OverridingExtensionToMimeTypeMapTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OverridingExtensionToMimeTypeMapTest.php b/src/OverridingExtensionToMimeTypeMapTest.php index b156524..4725855 100644 --- a/src/OverridingExtensionToMimeTypeMapTest.php +++ b/src/OverridingExtensionToMimeTypeMapTest.php @@ -2,7 +2,7 @@ namespace League\MimeTypeDetection; -use PHPStan\Testing\TestCase; +use PHPUnit\Framework\TestCase; class OverridingExtensionToMimeTypeMapTest extends TestCase { From 4e61edc8ea5332220e6d79de39a4545c894083ce Mon Sep 17 00:00:00 2001 From: Sergey Romanenko Date: Sun, 2 Jan 2022 13:44:08 +0300 Subject: [PATCH 09/26] Update license year Update license year to 2022 --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 7c1027d..1f01652 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2020 Frank de Jonge +Copyright (c) 2013-2022 Frank de Jonge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From cfc1698aafd8e18121e14d3dcae513ae33c3a154 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Mon, 11 Apr 2022 14:44:39 +0200 Subject: [PATCH 10/26] Update mime-map --- src/GeneratedExtensionToMimeTypeMap.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 3fabdae..575de58 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -66,6 +66,8 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'atomsvc' => 'application/atomsvc+xml', 'atx' => 'application/vnd.antix.game-component', 'au' => 'audio/x-au', + 'avci' => 'image/avci', + 'avcs' => 'image/avcs', 'avi' => 'video/x-msvideo', 'avif' => 'image/avif', 'aw' => 'application/applixware', @@ -160,6 +162,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'com' => 'application/x-msdownload', 'conf' => 'text/plain', 'cpio' => 'application/x-cpio', + 'cpl' => 'application/cpl+xml', 'cpp' => 'text/x-c', 'cpt' => 'application/mac-compactpro', 'crd' => 'application/x-mscardfile', @@ -583,6 +586,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'mpd' => 'application/dash+xml', 'mpe' => 'video/mpeg', 'mpeg' => 'video/mpeg', + 'mpf' => 'application/media-policy-dataset+xml', 'mpg' => 'video/mpeg', 'mpg4' => 'video/mp4', 'mpga' => 'audio/mpeg', @@ -760,7 +764,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12', 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', 'pqa' => 'application/vnd.palm', - 'prc' => 'application/x-pilot', + 'prc' => 'model/prc', 'pre' => 'application/vnd.lotus-freelance', 'prf' => 'application/pics-rules', 'provx' => 'application/provenance+xml', @@ -1000,6 +1004,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'txd' => 'application/vnd.genomatix.tuxedo', 'txf' => 'application/vnd.mobius.txf', 'txt' => 'text/plain', + 'u3d' => 'model/u3d', 'u8dsn' => 'message/global-delivery-status', 'u8hdr' => 'message/global-headers', 'u8mdn' => 'message/global-disposition-notification', @@ -1096,6 +1101,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'webp' => 'image/webp', 'wg' => 'application/vnd.pmi.widget', 'wgt' => 'application/widget', + 'wif' => 'application/watcherinfo+xml', 'wks' => 'application/vnd.ms-works', 'wm' => 'video/x-ms-wm', 'wma' => 'audio/x-ms-wma', From 205cd2c5c7eb3e32f66e5086a4c91aecccbb090e Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Mon, 11 Apr 2022 14:47:31 +0200 Subject: [PATCH 11/26] Expand inconclusive mime-type list and make it configurable. --- src/FinfoMimeTypeDetector.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/FinfoMimeTypeDetector.php b/src/FinfoMimeTypeDetector.php index e2f2e35..ba91938 100644 --- a/src/FinfoMimeTypeDetector.php +++ b/src/FinfoMimeTypeDetector.php @@ -11,7 +11,13 @@ class FinfoMimeTypeDetector implements MimeTypeDetector { - private const INCONCLUSIVE_MIME_TYPES = ['application/x-empty', 'text/plain', 'text/x-asm']; + private const INCONCLUSIVE_MIME_TYPES = [ + 'application/x-empty', + 'text/plain', + 'text/x-asm', + 'application/octet-stream', + 'inode/x-empty', + ]; /** * @var finfo @@ -28,14 +34,21 @@ class FinfoMimeTypeDetector implements MimeTypeDetector */ private $bufferSampleSize; + /** + * @var array + */ + private $inconclusiveMimetypes; + public function __construct( string $magicFile = '', ExtensionToMimeTypeMap $extensionMap = null, - ?int $bufferSampleSize = null + ?int $bufferSampleSize = null, + array $inconclusiveMimetypes = self::INCONCLUSIVE_MIME_TYPES ) { $this->finfo = new finfo(FILEINFO_MIME_TYPE, $magicFile); $this->extensionMap = $extensionMap ?: new GeneratedExtensionToMimeTypeMap(); $this->bufferSampleSize = $bufferSampleSize; + $this->inconclusiveMimetypes = $inconclusiveMimetypes; } public function detectMimeType(string $path, $contents): ?string @@ -44,7 +57,7 @@ public function detectMimeType(string $path, $contents): ?string ? (@$this->finfo->buffer($this->takeSample($contents)) ?: null) : null; - if ($mimeType !== null && ! in_array($mimeType, self::INCONCLUSIVE_MIME_TYPES)) { + if ($mimeType !== null && ! in_array($mimeType, $this->inconclusiveMimetypes)) { return $mimeType; } From ea7c49da112433811748805509a90d5344483b8a Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Mon, 11 Apr 2022 14:49:04 +0200 Subject: [PATCH 12/26] Prep changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9c4814..2264f7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 1.10.0 - 2022-04-11 + +### Fixed + +- Added Flysystem v1 inconclusive mime-types and made it configurable as a constructor parameter. + ## 1.9.0 - 2021-11-21 ### Updated From d0119ae66d960bd62a261191fc176e98fffb0907 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sun, 17 Apr 2022 15:10:28 +0200 Subject: [PATCH 13/26] Added test --- src/FinfoMimeTypeDetectorTest.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/FinfoMimeTypeDetectorTest.php b/src/FinfoMimeTypeDetectorTest.php index 02b6cab..5e3fbd6 100644 --- a/src/FinfoMimeTypeDetectorTest.php +++ b/src/FinfoMimeTypeDetectorTest.php @@ -18,6 +18,16 @@ protected function setUp(): void $this->detector = new FinfoMimeTypeDetector(); } + /** + * @test + */ + public function detecting_a_csv(): void + { + $mimeType = $this->detector->detectMimeType('something.csv', ''); + + $this->assertEquals('text/csv', $mimeType); + } + /** * @test */ From 8df8545584ab59b10278dbc243aaee339747c9e4 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sun, 17 Apr 2022 15:12:02 +0200 Subject: [PATCH 14/26] Added phar as application/octet-stream --- src/GeneratedExtensionToMimeTypeMap.php | 1 + src/Generation/FlysystemProvidedMimeTypeProvider.php | 1 + 2 files changed, 2 insertions(+) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 575de58..b6221e9 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -730,6 +730,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'pgm' => 'image/x-portable-graymap', 'pgn' => 'application/x-chess-pgn', 'pgp' => 'application/pgp', + 'phar' => 'application/octet-stream', 'php' => 'application/x-httpd-php', 'php3' => 'application/x-httpd-php', 'php4' => 'application/x-httpd-php', diff --git a/src/Generation/FlysystemProvidedMimeTypeProvider.php b/src/Generation/FlysystemProvidedMimeTypeProvider.php index da45f0a..a5b2736 100644 --- a/src/Generation/FlysystemProvidedMimeTypeProvider.php +++ b/src/Generation/FlysystemProvidedMimeTypeProvider.php @@ -12,6 +12,7 @@ public function provideMimeTypes(): array new MimeTypeForExtension('application/mac-binhex40', 'hqx'), new MimeTypeForExtension('application/mac-compactpro', 'cpt'), new MimeTypeForExtension('text/csv', 'csv'), + new MimeTypeForExtension('application/octet-stream', 'phar'), new MimeTypeForExtension('application/octet-stream', 'bin'), new MimeTypeForExtension('application/octet-stream', 'dms'), new MimeTypeForExtension('application/octet-stream', 'lha'), From 1271db7652d4ac77091ab5285f191676ec4f2fd7 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Mon, 5 Sep 2022 10:30:00 +0200 Subject: [PATCH 15/26] Updated mimetypes. --- src/GeneratedExtensionToMimeTypeMap.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index b6221e9..16c039f 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -34,6 +34,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'acu' => 'application/vnd.acucobol', 'acutc' => 'application/vnd.acucorp', 'adp' => 'audio/adpcm', + 'adts' => 'audio/aac', 'aep' => 'application/vnd.audiograph', 'afm' => 'application/x-font-type1', 'afp' => 'application/vnd.ibm.modcap', @@ -48,7 +49,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'ami' => 'application/vnd.amiga.ami', 'amr' => 'audio/amr', 'apk' => 'application/vnd.android.package-archive', - 'apng' => 'image/apng', + 'apng' => 'image/vnd.mozilla.apng', 'appcache' => 'text/cache-manifest', 'application' => 'application/x-ms-application', 'apr' => 'application/vnd.lotus-approach', @@ -95,6 +96,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'bpk' => 'application/octet-stream', 'bpmn' => 'application/octet-stream', 'bsp' => 'model/vnd.valve.source.compiled-map', + 'btf' => 'image/prs.btif', 'btif' => 'image/prs.btif', 'buffer' => 'application/octet-stream', 'bz' => 'application/x-bzip', @@ -180,6 +182,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'csv' => 'text/csv', 'cu' => 'application/cu-seeme', 'curl' => 'text/vnd.curl', + 'cwl' => 'application/cwl', 'cww' => 'application/prs.cww', 'cxt' => 'application/x-director', 'cxx' => 'text/x-c', @@ -202,6 +205,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'der' => 'application/x-x509-ca-cert', 'dfac' => 'application/vnd.dreamfactory', 'dgc' => 'application/x-dgc-compressed', + 'dib' => 'image/bmp', 'dic' => 'text/x-c', 'dir' => 'application/x-director', 'dis' => 'application/vnd.mobius.dis', @@ -260,7 +264,6 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'eot' => 'application/vnd.ms-fontobject', 'eps' => 'application/postscript', 'epub' => 'application/epub+zip', - 'es' => 'application/ecmascript', 'es3' => 'application/vnd.eszigno3+xml', 'esa' => 'application/vnd.osgi.subsystem', 'esf' => 'application/vnd.epson.esf', @@ -557,7 +560,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'mime' => 'message/rfc822', 'mj2' => 'video/mj2', 'mjp2' => 'video/mj2', - 'mjs' => 'application/javascript', + 'mjs' => 'text/javascript', 'mk3d' => 'video/x-matroska', 'mka' => 'audio/x-matroska', 'mkd' => 'text/x-markdown', @@ -780,6 +783,8 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'pvb' => 'application/vnd.3gpp.pic-bw-var', 'pwn' => 'application/vnd.3m.post-it-notes', 'pya' => 'audio/vnd.ms-playready.media.pya', + 'pyo' => 'model/vnd.pytha.pyox', + 'pyox' => 'model/vnd.pytha.pyox', 'pyv' => 'video/vnd.ms-playready.media.pyv', 'qam' => 'application/vnd.epson.quickanime', 'qbo' => 'application/vnd.intu.qbo', @@ -1018,6 +1023,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'ulx' => 'application/x-glulx', 'umj' => 'application/vnd.umajin', 'unityweb' => 'application/vnd.unity', + 'uo' => 'application/vnd.uoml+xml', 'uoml' => 'application/vnd.uoml+xml', 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', @@ -1155,9 +1161,10 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'xel' => 'application/xcap-el+xml', 'xenc' => 'application/xenc+xml', 'xer' => 'application/patch-ops-error+xml', - 'xfdf' => 'application/vnd.adobe.xfdf', + 'xfdf' => 'application/xfdf', 'xfdl' => 'application/vnd.xfdl', 'xht' => 'application/xhtml+xml', + 'xhtm' => 'application/vnd.pwg-xhtml-print+xml', 'xhtml' => 'application/xhtml+xml', 'xhvml' => 'application/xv+xml', 'xif' => 'image/vnd.xiff', @@ -1188,6 +1195,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'xpw' => 'application/vnd.intercon.formnet', 'xpx' => 'application/vnd.intercon.formnet', 'xsd' => 'application/xml', + 'xsf' => 'application/prs.xsf+xml', 'xsl' => 'application/xml', 'xslt' => 'application/xslt+xml', 'xsm' => 'application/vnd.syncml+xml', From a436a007e4a21151366ec76b66e53a1b262e0f7c Mon Sep 17 00:00:00 2001 From: Sergey Romanenko Date: Sun, 1 Jan 2023 17:44:52 +0800 Subject: [PATCH 16/26] update year --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1f01652..39d50b5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2022 Frank de Jonge +Copyright (c) 2013-2023 Frank de Jonge Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From b6fb35ef697b6f07ae162a48aa63b5bba3612108 Mon Sep 17 00:00:00 2001 From: Blackbit Date: Wed, 21 Sep 2022 09:50:28 +0200 Subject: [PATCH 17/26] Add stp --- src/GeneratedExtensionToMimeTypeMap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 16c039f..a54fb13 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -937,6 +937,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'sti' => 'application/vnd.sun.xml.impress.template', 'stk' => 'application/hyperstudio', 'stl' => 'model/stl', + 'stp' => 'application/STEP', 'stpx' => 'model/step+xml', 'stpxz' => 'model/step-xml+zip', 'stpz' => 'model/step+zip', From 10f74d72b0b79214f11454f576373c46dba8fe72 Mon Sep 17 00:00:00 2001 From: Blackbit Date: Wed, 21 Sep 2022 09:53:25 +0200 Subject: [PATCH 18/26] Add step file extension --- src/GeneratedExtensionToMimeTypeMap.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index a54fb13..ba84438 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -933,6 +933,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'st' => 'application/vnd.sailingtracker.track', 'stc' => 'application/vnd.sun.xml.calc.template', 'std' => 'application/vnd.sun.xml.draw.template', + 'step' => 'application/STEP', 'stf' => 'application/vnd.wt.stf', 'sti' => 'application/vnd.sun.xml.impress.template', 'stk' => 'application/hyperstudio', From 838489b7e65c716409d3f05f0f3a8b585a611e55 Mon Sep 17 00:00:00 2001 From: Jan Walther Date: Thu, 29 Sep 2022 17:20:05 +0200 Subject: [PATCH 19/26] add .stp + .step for application/STEP --- src/Generation/FlysystemProvidedMimeTypeProvider.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Generation/FlysystemProvidedMimeTypeProvider.php b/src/Generation/FlysystemProvidedMimeTypeProvider.php index a5b2736..a257fac 100644 --- a/src/Generation/FlysystemProvidedMimeTypeProvider.php +++ b/src/Generation/FlysystemProvidedMimeTypeProvider.php @@ -182,6 +182,8 @@ public function provideMimeTypes(): array new MimeTypeForExtension('application/vnd.oasis.opendocument.text-master', 'odm'), new MimeTypeForExtension('application/vnd.oasis.opendocument.database', 'odb'), new MimeTypeForExtension('application/vnd.oasis.opendocument.text-template', 'ott'), + new MimeTypeForExtension('application/STEP', 'step'), + new MimeTypeForExtension('application/STEP', 'stp'), ]; } } From 3c457a18c9eac9f0131f2d7c8ae1919b8283b128 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Thu, 3 Aug 2023 09:11:23 +0200 Subject: [PATCH 20/26] Updated mime-times. --- src/GeneratedExtensionToMimeTypeMap.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index ba84438..6aa3aa7 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -47,11 +47,16 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'air' => 'application/vnd.adobe.air-application-installer-package+zip', 'ait' => 'application/vnd.dvb.ait', 'ami' => 'application/vnd.amiga.ami', + 'aml' => 'application/automationml-aml+xml', + 'amlx' => 'application/automationml-amlx+zip', 'amr' => 'audio/amr', 'apk' => 'application/vnd.android.package-archive', - 'apng' => 'image/vnd.mozilla.apng', + 'apng' => 'image/apng', 'appcache' => 'text/cache-manifest', + 'appinstaller' => 'application/appinstaller', 'application' => 'application/x-ms-application', + 'appx' => 'application/appx', + 'appxbundle' => 'application/appxbundle', 'apr' => 'application/vnd.lotus-approach', 'arc' => 'application/x-freearc', 'arj' => 'application/x-arj', @@ -148,6 +153,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'cjs' => 'application/node', 'cla' => 'application/vnd.claymore', 'class' => 'application/octet-stream', + 'cld' => 'model/vnd.cld', 'clkk' => 'application/vnd.crick.clicker.keyboard', 'clkp' => 'application/vnd.crick.clicker.palette', 'clkt' => 'application/vnd.crick.clicker.template', @@ -228,6 +234,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template', 'dp' => 'application/vnd.osgi.dp', 'dpg' => 'application/vnd.dpgraph', + 'dpx' => 'image/dpx', 'dra' => 'audio/vnd.dra', 'drle' => 'image/dicom-rle', 'dsc' => 'text/prs.lines.tag', @@ -456,6 +463,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'jsonld' => 'application/ld+json', 'jsonml' => 'application/jsonml+json', 'jsx' => 'text/jsx', + 'jt' => 'model/jt', 'jxr' => 'image/jxr', 'jxra' => 'image/jxra', 'jxrs' => 'image/jxrs', @@ -610,6 +618,8 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'msg' => 'application/vnd.ms-outlook', 'msh' => 'model/mesh', 'msi' => 'application/x-msdownload', + 'msix' => 'application/msix', + 'msixbundle' => 'application/msixbundle', 'msl' => 'application/vnd.mobius.msl', 'msm' => 'application/octet-stream', 'msp' => 'application/octet-stream', @@ -1030,6 +1040,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'uri' => 'text/uri-list', 'uris' => 'text/uri-list', 'urls' => 'text/uri-list', + 'usda' => 'model/vnd.usda', 'usdz' => 'model/vnd.usdz+zip', 'ustar' => 'application/x-ustar', 'utz' => 'application/vnd.uiq.theme', @@ -1109,6 +1120,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'webmanifest' => 'application/manifest+json', 'webp' => 'image/webp', 'wg' => 'application/vnd.pmi.widget', + 'wgsl' => 'text/wgsl', 'wgt' => 'application/widget', 'wif' => 'application/watcherinfo+xml', 'wks' => 'application/vnd.ms-works', From d1bb20e0a97a85aab920b2ab2d80be3a7b07ad2d Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Thu, 3 Aug 2023 09:14:11 +0200 Subject: [PATCH 21/26] Prep changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2264f7a..cd80156 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## 1.12.0 - 2022-08-03 + +### Updated + +- Updated lookup + +## 1.11.0 - 2022-04-17 + +### Updated + +- Updated lookup + ## 1.10.0 - 2022-04-11 ### Fixed From 32796d95d017232d661e9dda87368a9d2b8ab35f Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sat, 5 Aug 2023 12:44:47 +0200 Subject: [PATCH 22/26] Provide capability to lookup extensions for mime-types. --- src/FinfoMimeTypeDetector.php | 16 +- src/GeneratedExtensionToMimeTypeMap.php | 1046 ++++++++++++++++- src/GeneratedExtensionToMimeTypeMapTest.php | 9 +- .../ExtensionToMimeTypeMap.php.template | 26 +- .../ExtensionToMimeTypeMapGenerator.php | 12 +- 5 files changed, 1086 insertions(+), 23 deletions(-) diff --git a/src/FinfoMimeTypeDetector.php b/src/FinfoMimeTypeDetector.php index ba91938..8084f92 100644 --- a/src/FinfoMimeTypeDetector.php +++ b/src/FinfoMimeTypeDetector.php @@ -9,7 +9,7 @@ use const PATHINFO_EXTENSION; use finfo; -class FinfoMimeTypeDetector implements MimeTypeDetector +class FinfoMimeTypeDetector implements MimeTypeDetector, ExtensionLookup { private const INCONCLUSIVE_MIME_TYPES = [ 'application/x-empty', @@ -89,4 +89,18 @@ private function takeSample(string $contents): string return (string) substr($contents, 0, $this->bufferSampleSize); } + + public function lookupExtension(string $mimetype): ?string + { + return $this->extensionMap instanceof ExtensionLookup + ? $this->extensionMap->lookupExtension($mimetype) + : null; + } + + public function lookupAllExtensions(string $mimetype): array + { + return $this->extensionMap instanceof ExtensionLookup + ? $this->extensionMap->lookupAllExtensions($mimetype) + : []; + } } diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index 6aa3aa7..eb9f278 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -4,10 +4,10 @@ namespace League\MimeTypeDetection; -class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap +class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap, ExtensionLookup { /** - * @var string[] + * @var array * * @internal */ @@ -1242,20 +1242,1050 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap 'zsh' => 'text/x-scriptzsh', ]; + /** + * @var array + * + * @internal + */ + public const EXTENSIONS_FOR_MIME_TIMES = [ + 'application/andrew-inset' => ['ez'], + 'application/appinstaller' => ['appinstaller'], + 'application/applixware' => ['aw'], + 'application/appx' => ['appx'], + 'application/appxbundle' => ['appxbundle'], + 'application/atom+xml' => ['atom'], + 'application/atomcat+xml' => ['atomcat'], + 'application/atomdeleted+xml' => ['atomdeleted'], + 'application/atomsvc+xml' => ['atomsvc'], + 'application/atsc-dwd+xml' => ['dwd'], + 'application/atsc-held+xml' => ['held'], + 'application/atsc-rsat+xml' => ['rsat'], + 'application/automationml-aml+xml' => ['aml'], + 'application/automationml-amlx+zip' => ['amlx'], + 'application/bdoc' => ['bdoc'], + 'application/calendar+xml' => ['xcs'], + 'application/ccxml+xml' => ['ccxml'], + 'application/cdfx+xml' => ['cdfx'], + 'application/cdmi-capability' => ['cdmia'], + 'application/cdmi-container' => ['cdmic'], + 'application/cdmi-domain' => ['cdmid'], + 'application/cdmi-object' => ['cdmio'], + 'application/cdmi-queue' => ['cdmiq'], + 'application/cpl+xml' => ['cpl'], + 'application/cu-seeme' => ['cu'], + 'application/cwl' => ['cwl'], + 'application/dash+xml' => ['mpd'], + 'application/dash-patch+xml' => ['mpp'], + 'application/davmount+xml' => ['davmount'], + 'application/docbook+xml' => ['dbk'], + 'application/dssc+der' => ['dssc'], + 'application/dssc+xml' => ['xdssc'], + 'application/ecmascript' => ['ecma'], + 'application/emma+xml' => ['emma'], + 'application/emotionml+xml' => ['emotionml'], + 'application/epub+zip' => ['epub'], + 'application/exi' => ['exi'], + 'application/express' => ['exp'], + 'application/fdf' => ['fdf'], + 'application/fdt+xml' => ['fdt'], + 'application/font-tdpfr' => ['pfr'], + 'application/geo+json' => ['geojson'], + 'application/gml+xml' => ['gml'], + 'application/gpx+xml' => ['gpx'], + 'application/gxf' => ['gxf'], + 'application/gzip' => ['gz', 'gzip'], + 'application/hjson' => ['hjson'], + 'application/hyperstudio' => ['stk'], + 'application/inkml+xml' => ['ink', 'inkml'], + 'application/ipfix' => ['ipfix'], + 'application/its+xml' => ['its'], + 'application/java-archive' => ['jar', 'war', 'ear'], + 'application/java-serialized-object' => ['ser'], + 'application/java-vm' => ['class'], + 'application/javascript' => ['js'], + 'application/json' => ['json', 'map'], + 'application/json5' => ['json5'], + 'application/jsonml+json' => ['jsonml'], + 'application/ld+json' => ['jsonld'], + 'application/lgr+xml' => ['lgr'], + 'application/lost+xml' => ['lostxml'], + 'application/mac-binhex40' => ['hqx'], + 'application/mac-compactpro' => ['cpt'], + 'application/mads+xml' => ['mads'], + 'application/manifest+json' => ['webmanifest'], + 'application/marc' => ['mrc'], + 'application/marcxml+xml' => ['mrcx'], + 'application/mathematica' => ['ma', 'nb', 'mb'], + 'application/mathml+xml' => ['mathml'], + 'application/mbox' => ['mbox'], + 'application/media-policy-dataset+xml' => ['mpf'], + 'application/mediaservercontrol+xml' => ['mscml'], + 'application/metalink+xml' => ['metalink'], + 'application/metalink4+xml' => ['meta4'], + 'application/mets+xml' => ['mets'], + 'application/mmt-aei+xml' => ['maei'], + 'application/mmt-usd+xml' => ['musd'], + 'application/mods+xml' => ['mods'], + 'application/mp21' => ['m21', 'mp21'], + 'application/mp4' => ['mp4', 'mpg4', 'mp4s', 'm4p'], + 'application/msix' => ['msix'], + 'application/msixbundle' => ['msixbundle'], + 'application/msword' => ['doc', 'dot', 'word'], + 'application/mxf' => ['mxf'], + 'application/n-quads' => ['nq'], + 'application/n-triples' => ['nt'], + 'application/node' => ['cjs'], + 'application/octet-stream' => ['bin', 'dms', 'lrf', 'mar', 'so', 'dist', 'distz', 'pkg', 'bpk', 'dump', 'elc', 'deploy', 'exe', 'dll', 'deb', 'dmg', 'iso', 'img', 'msi', 'msp', 'msm', 'buffer', 'phar', 'lha', 'lzh', 'class', 'sea', 'dmn', 'bpmn', 'kdb', 'sst', 'csr'], + 'application/oda' => ['oda'], + 'application/oebps-package+xml' => ['opf'], + 'application/ogg' => ['ogx'], + 'application/omdoc+xml' => ['omdoc'], + 'application/onenote' => ['onetoc', 'onetoc2', 'onetmp', 'onepkg'], + 'application/oxps' => ['oxps'], + 'application/p2p-overlay+xml' => ['relo'], + 'application/patch-ops-error+xml' => ['xer'], + 'application/pdf' => ['pdf', 'ai'], + 'application/pgp-encrypted' => ['pgp'], + 'application/pgp-keys' => ['asc'], + 'application/pgp-signature' => ['sig', 'asc'], + 'application/pics-rules' => ['prf'], + 'application/pkcs10' => ['p10'], + 'application/pkcs7-mime' => ['p7m', 'p7c'], + 'application/pkcs7-signature' => ['p7s'], + 'application/pkcs8' => ['p8'], + 'application/pkix-attr-cert' => ['ac'], + 'application/pkix-cert' => ['cer'], + 'application/pkix-crl' => ['crl'], + 'application/pkix-pkipath' => ['pkipath'], + 'application/pkixcmp' => ['pki'], + 'application/pls+xml' => ['pls'], + 'application/postscript' => ['ai', 'eps', 'ps'], + 'application/provenance+xml' => ['provx'], + 'application/prs.cww' => ['cww'], + 'application/prs.xsf+xml' => ['xsf'], + 'application/pskc+xml' => ['pskcxml'], + 'application/raml+yaml' => ['raml'], + 'application/rdf+xml' => ['rdf', 'owl'], + 'application/reginfo+xml' => ['rif'], + 'application/relax-ng-compact-syntax' => ['rnc'], + 'application/resource-lists+xml' => ['rl'], + 'application/resource-lists-diff+xml' => ['rld'], + 'application/rls-services+xml' => ['rs'], + 'application/route-apd+xml' => ['rapd'], + 'application/route-s-tsid+xml' => ['sls'], + 'application/route-usd+xml' => ['rusd'], + 'application/rpki-ghostbusters' => ['gbr'], + 'application/rpki-manifest' => ['mft'], + 'application/rpki-roa' => ['roa'], + 'application/rsd+xml' => ['rsd'], + 'application/rss+xml' => ['rss'], + 'application/rtf' => ['rtf'], + 'application/sbml+xml' => ['sbml'], + 'application/scvp-cv-request' => ['scq'], + 'application/scvp-cv-response' => ['scs'], + 'application/scvp-vp-request' => ['spq'], + 'application/scvp-vp-response' => ['spp'], + 'application/sdp' => ['sdp'], + 'application/senml+xml' => ['senmlx'], + 'application/sensml+xml' => ['sensmlx'], + 'application/set-payment-initiation' => ['setpay'], + 'application/set-registration-initiation' => ['setreg'], + 'application/shf+xml' => ['shf'], + 'application/sieve' => ['siv', 'sieve'], + 'application/smil+xml' => ['smi', 'smil'], + 'application/sparql-query' => ['rq'], + 'application/sparql-results+xml' => ['srx'], + 'application/sql' => ['sql'], + 'application/srgs' => ['gram'], + 'application/srgs+xml' => ['grxml'], + 'application/sru+xml' => ['sru'], + 'application/ssdl+xml' => ['ssdl'], + 'application/ssml+xml' => ['ssml'], + 'application/swid+xml' => ['swidtag'], + 'application/tei+xml' => ['tei', 'teicorpus'], + 'application/thraud+xml' => ['tfi'], + 'application/timestamped-data' => ['tsd'], + 'application/toml' => ['toml'], + 'application/trig' => ['trig'], + 'application/ttml+xml' => ['ttml'], + 'application/ubjson' => ['ubj'], + 'application/urc-ressheet+xml' => ['rsheet'], + 'application/urc-targetdesc+xml' => ['td'], + 'application/vnd.1000minds.decision-model+xml' => ['1km'], + 'application/vnd.3gpp.pic-bw-large' => ['plb'], + 'application/vnd.3gpp.pic-bw-small' => ['psb'], + 'application/vnd.3gpp.pic-bw-var' => ['pvb'], + 'application/vnd.3gpp2.tcap' => ['tcap'], + 'application/vnd.3m.post-it-notes' => ['pwn'], + 'application/vnd.accpac.simply.aso' => ['aso'], + 'application/vnd.accpac.simply.imp' => ['imp'], + 'application/vnd.acucobol' => ['acu'], + 'application/vnd.acucorp' => ['atc', 'acutc'], + 'application/vnd.adobe.air-application-installer-package+zip' => ['air'], + 'application/vnd.adobe.formscentral.fcdt' => ['fcdt'], + 'application/vnd.adobe.fxp' => ['fxp', 'fxpl'], + 'application/vnd.adobe.xdp+xml' => ['xdp'], + 'application/vnd.adobe.xfdf' => ['xfdf'], + 'application/vnd.age' => ['age'], + 'application/vnd.ahead.space' => ['ahead'], + 'application/vnd.airzip.filesecure.azf' => ['azf'], + 'application/vnd.airzip.filesecure.azs' => ['azs'], + 'application/vnd.amazon.ebook' => ['azw'], + 'application/vnd.americandynamics.acc' => ['acc'], + 'application/vnd.amiga.ami' => ['ami'], + 'application/vnd.android.package-archive' => ['apk'], + 'application/vnd.anser-web-certificate-issue-initiation' => ['cii'], + 'application/vnd.anser-web-funds-transfer-initiation' => ['fti'], + 'application/vnd.antix.game-component' => ['atx'], + 'application/vnd.apple.installer+xml' => ['mpkg'], + 'application/vnd.apple.keynote' => ['key'], + 'application/vnd.apple.mpegurl' => ['m3u8'], + 'application/vnd.apple.numbers' => ['numbers'], + 'application/vnd.apple.pages' => ['pages'], + 'application/vnd.apple.pkpass' => ['pkpass'], + 'application/vnd.aristanetworks.swi' => ['swi'], + 'application/vnd.astraea-software.iota' => ['iota'], + 'application/vnd.audiograph' => ['aep'], + 'application/vnd.balsamiq.bmml+xml' => ['bmml'], + 'application/vnd.blueice.multipass' => ['mpm'], + 'application/vnd.bmi' => ['bmi'], + 'application/vnd.businessobjects' => ['rep'], + 'application/vnd.chemdraw+xml' => ['cdxml'], + 'application/vnd.chipnuts.karaoke-mmd' => ['mmd'], + 'application/vnd.cinderella' => ['cdy'], + 'application/vnd.citationstyles.style+xml' => ['csl'], + 'application/vnd.claymore' => ['cla'], + 'application/vnd.cloanto.rp9' => ['rp9'], + 'application/vnd.clonk.c4group' => ['c4g', 'c4d', 'c4f', 'c4p', 'c4u'], + 'application/vnd.cluetrust.cartomobile-config' => ['c11amc'], + 'application/vnd.cluetrust.cartomobile-config-pkg' => ['c11amz'], + 'application/vnd.commonspace' => ['csp'], + 'application/vnd.contact.cmsg' => ['cdbcmsg'], + 'application/vnd.cosmocaller' => ['cmc'], + 'application/vnd.crick.clicker' => ['clkx'], + 'application/vnd.crick.clicker.keyboard' => ['clkk'], + 'application/vnd.crick.clicker.palette' => ['clkp'], + 'application/vnd.crick.clicker.template' => ['clkt'], + 'application/vnd.crick.clicker.wordbank' => ['clkw'], + 'application/vnd.criticaltools.wbs+xml' => ['wbs'], + 'application/vnd.ctc-posml' => ['pml'], + 'application/vnd.cups-ppd' => ['ppd'], + 'application/vnd.curl.car' => ['car'], + 'application/vnd.curl.pcurl' => ['pcurl'], + 'application/vnd.dart' => ['dart'], + 'application/vnd.data-vision.rdz' => ['rdz'], + 'application/vnd.dbf' => ['dbf'], + 'application/vnd.dece.data' => ['uvf', 'uvvf', 'uvd', 'uvvd'], + 'application/vnd.dece.ttml+xml' => ['uvt', 'uvvt'], + 'application/vnd.dece.unspecified' => ['uvx', 'uvvx'], + 'application/vnd.dece.zip' => ['uvz', 'uvvz'], + 'application/vnd.denovo.fcselayout-link' => ['fe_launch'], + 'application/vnd.dna' => ['dna'], + 'application/vnd.dolby.mlp' => ['mlp'], + 'application/vnd.dpgraph' => ['dpg'], + 'application/vnd.dreamfactory' => ['dfac'], + 'application/vnd.ds-keypoint' => ['kpxx'], + 'application/vnd.dvb.ait' => ['ait'], + 'application/vnd.dvb.service' => ['svc'], + 'application/vnd.dynageo' => ['geo'], + 'application/vnd.ecowin.chart' => ['mag'], + 'application/vnd.enliven' => ['nml'], + 'application/vnd.epson.esf' => ['esf'], + 'application/vnd.epson.msf' => ['msf'], + 'application/vnd.epson.quickanime' => ['qam'], + 'application/vnd.epson.salt' => ['slt'], + 'application/vnd.epson.ssf' => ['ssf'], + 'application/vnd.eszigno3+xml' => ['es3', 'et3'], + 'application/vnd.ezpix-album' => ['ez2'], + 'application/vnd.ezpix-package' => ['ez3'], + 'application/vnd.fdf' => ['fdf'], + 'application/vnd.fdsn.mseed' => ['mseed'], + 'application/vnd.fdsn.seed' => ['seed', 'dataless'], + 'application/vnd.flographit' => ['gph'], + 'application/vnd.fluxtime.clip' => ['ftc'], + 'application/vnd.framemaker' => ['fm', 'frame', 'maker', 'book'], + 'application/vnd.frogans.fnc' => ['fnc'], + 'application/vnd.frogans.ltf' => ['ltf'], + 'application/vnd.fsc.weblaunch' => ['fsc'], + 'application/vnd.fujitsu.oasys' => ['oas'], + 'application/vnd.fujitsu.oasys2' => ['oa2'], + 'application/vnd.fujitsu.oasys3' => ['oa3'], + 'application/vnd.fujitsu.oasysgp' => ['fg5'], + 'application/vnd.fujitsu.oasysprs' => ['bh2'], + 'application/vnd.fujixerox.ddd' => ['ddd'], + 'application/vnd.fujixerox.docuworks' => ['xdw'], + 'application/vnd.fujixerox.docuworks.binder' => ['xbd'], + 'application/vnd.fuzzysheet' => ['fzs'], + 'application/vnd.genomatix.tuxedo' => ['txd'], + 'application/vnd.geogebra.file' => ['ggb'], + 'application/vnd.geogebra.tool' => ['ggt'], + 'application/vnd.geometry-explorer' => ['gex', 'gre'], + 'application/vnd.geonext' => ['gxt'], + 'application/vnd.geoplan' => ['g2w'], + 'application/vnd.geospace' => ['g3w'], + 'application/vnd.gmx' => ['gmx'], + 'application/vnd.google-apps.document' => ['gdoc'], + 'application/vnd.google-apps.presentation' => ['gslides'], + 'application/vnd.google-apps.spreadsheet' => ['gsheet'], + 'application/vnd.google-earth.kml+xml' => ['kml'], + 'application/vnd.google-earth.kmz' => ['kmz'], + 'application/vnd.grafeq' => ['gqf', 'gqs'], + 'application/vnd.groove-account' => ['gac'], + 'application/vnd.groove-help' => ['ghf'], + 'application/vnd.groove-identity-message' => ['gim'], + 'application/vnd.groove-injector' => ['grv'], + 'application/vnd.groove-tool-message' => ['gtm'], + 'application/vnd.groove-tool-template' => ['tpl'], + 'application/vnd.groove-vcard' => ['vcg'], + 'application/vnd.hal+xml' => ['hal'], + 'application/vnd.handheld-entertainment+xml' => ['zmm'], + 'application/vnd.hbci' => ['hbci'], + 'application/vnd.hhe.lesson-player' => ['les'], + 'application/vnd.hp-hpgl' => ['hpgl'], + 'application/vnd.hp-hpid' => ['hpid'], + 'application/vnd.hp-hps' => ['hps'], + 'application/vnd.hp-jlyt' => ['jlt'], + 'application/vnd.hp-pcl' => ['pcl'], + 'application/vnd.hp-pclxl' => ['pclxl'], + 'application/vnd.hydrostatix.sof-data' => ['sfd-hdstx'], + 'application/vnd.ibm.minipay' => ['mpy'], + 'application/vnd.ibm.modcap' => ['afp', 'listafp', 'list3820'], + 'application/vnd.ibm.rights-management' => ['irm'], + 'application/vnd.ibm.secure-container' => ['sc'], + 'application/vnd.iccprofile' => ['icc', 'icm'], + 'application/vnd.igloader' => ['igl'], + 'application/vnd.immervision-ivp' => ['ivp'], + 'application/vnd.immervision-ivu' => ['ivu'], + 'application/vnd.insors.igm' => ['igm'], + 'application/vnd.intercon.formnet' => ['xpw', 'xpx'], + 'application/vnd.intergeo' => ['i2g'], + 'application/vnd.intu.qbo' => ['qbo'], + 'application/vnd.intu.qfx' => ['qfx'], + 'application/vnd.ipunplugged.rcprofile' => ['rcprofile'], + 'application/vnd.irepository.package+xml' => ['irp'], + 'application/vnd.is-xpr' => ['xpr'], + 'application/vnd.isac.fcs' => ['fcs'], + 'application/vnd.jam' => ['jam'], + 'application/vnd.jcp.javame.midlet-rms' => ['rms'], + 'application/vnd.jisp' => ['jisp'], + 'application/vnd.joost.joda-archive' => ['joda'], + 'application/vnd.kahootz' => ['ktz', 'ktr'], + 'application/vnd.kde.karbon' => ['karbon'], + 'application/vnd.kde.kchart' => ['chrt'], + 'application/vnd.kde.kformula' => ['kfo'], + 'application/vnd.kde.kivio' => ['flw'], + 'application/vnd.kde.kontour' => ['kon'], + 'application/vnd.kde.kpresenter' => ['kpr', 'kpt'], + 'application/vnd.kde.kspread' => ['ksp'], + 'application/vnd.kde.kword' => ['kwd', 'kwt'], + 'application/vnd.kenameaapp' => ['htke'], + 'application/vnd.kidspiration' => ['kia'], + 'application/vnd.kinar' => ['kne', 'knp'], + 'application/vnd.koan' => ['skp', 'skd', 'skt', 'skm'], + 'application/vnd.kodak-descriptor' => ['sse'], + 'application/vnd.las.las+xml' => ['lasxml'], + 'application/vnd.llamagraphics.life-balance.desktop' => ['lbd'], + 'application/vnd.llamagraphics.life-balance.exchange+xml' => ['lbe'], + 'application/vnd.lotus-1-2-3' => ['123'], + 'application/vnd.lotus-approach' => ['apr'], + 'application/vnd.lotus-freelance' => ['pre'], + 'application/vnd.lotus-notes' => ['nsf'], + 'application/vnd.lotus-organizer' => ['org'], + 'application/vnd.lotus-screencam' => ['scm'], + 'application/vnd.lotus-wordpro' => ['lwp'], + 'application/vnd.macports.portpkg' => ['portpkg'], + 'application/vnd.mapbox-vector-tile' => ['mvt'], + 'application/vnd.mcd' => ['mcd'], + 'application/vnd.medcalcdata' => ['mc1'], + 'application/vnd.mediastation.cdkey' => ['cdkey'], + 'application/vnd.mfer' => ['mwf'], + 'application/vnd.mfmp' => ['mfm'], + 'application/vnd.micrografx.flo' => ['flo'], + 'application/vnd.micrografx.igx' => ['igx'], + 'application/vnd.mif' => ['mif'], + 'application/vnd.mobius.daf' => ['daf'], + 'application/vnd.mobius.dis' => ['dis'], + 'application/vnd.mobius.mbk' => ['mbk'], + 'application/vnd.mobius.mqy' => ['mqy'], + 'application/vnd.mobius.msl' => ['msl'], + 'application/vnd.mobius.plc' => ['plc'], + 'application/vnd.mobius.txf' => ['txf'], + 'application/vnd.mophun.application' => ['mpn'], + 'application/vnd.mophun.certificate' => ['mpc'], + 'application/vnd.mozilla.xul+xml' => ['xul'], + 'application/vnd.ms-artgalry' => ['cil'], + 'application/vnd.ms-cab-compressed' => ['cab'], + 'application/vnd.ms-excel' => ['xls', 'xlm', 'xla', 'xlc', 'xlt', 'xlw'], + 'application/vnd.ms-excel.addin.macroenabled.12' => ['xlam'], + 'application/vnd.ms-excel.sheet.binary.macroenabled.12' => ['xlsb'], + 'application/vnd.ms-excel.sheet.macroenabled.12' => ['xlsm'], + 'application/vnd.ms-excel.template.macroenabled.12' => ['xltm'], + 'application/vnd.ms-fontobject' => ['eot'], + 'application/vnd.ms-htmlhelp' => ['chm'], + 'application/vnd.ms-ims' => ['ims'], + 'application/vnd.ms-lrm' => ['lrm'], + 'application/vnd.ms-officetheme' => ['thmx'], + 'application/vnd.ms-outlook' => ['msg'], + 'application/vnd.ms-pki.seccat' => ['cat'], + 'application/vnd.ms-pki.stl' => ['stl'], + 'application/vnd.ms-powerpoint' => ['ppt', 'pps', 'pot', 'ppa'], + 'application/vnd.ms-powerpoint.addin.macroenabled.12' => ['ppam'], + 'application/vnd.ms-powerpoint.presentation.macroenabled.12' => ['pptm'], + 'application/vnd.ms-powerpoint.slide.macroenabled.12' => ['sldm'], + 'application/vnd.ms-powerpoint.slideshow.macroenabled.12' => ['ppsm'], + 'application/vnd.ms-powerpoint.template.macroenabled.12' => ['potm'], + 'application/vnd.ms-project' => ['mpp', 'mpt'], + 'application/vnd.ms-word.document.macroenabled.12' => ['docm'], + 'application/vnd.ms-word.template.macroenabled.12' => ['dotm'], + 'application/vnd.ms-works' => ['wps', 'wks', 'wcm', 'wdb'], + 'application/vnd.ms-wpl' => ['wpl'], + 'application/vnd.ms-xpsdocument' => ['xps'], + 'application/vnd.mseq' => ['mseq'], + 'application/vnd.musician' => ['mus'], + 'application/vnd.muvee.style' => ['msty'], + 'application/vnd.mynfc' => ['taglet'], + 'application/vnd.neurolanguage.nlu' => ['nlu'], + 'application/vnd.nitf' => ['ntf', 'nitf'], + 'application/vnd.noblenet-directory' => ['nnd'], + 'application/vnd.noblenet-sealer' => ['nns'], + 'application/vnd.noblenet-web' => ['nnw'], + 'application/vnd.nokia.n-gage.ac+xml' => ['ac'], + 'application/vnd.nokia.n-gage.data' => ['ngdat'], + 'application/vnd.nokia.n-gage.symbian.install' => ['n-gage'], + 'application/vnd.nokia.radio-preset' => ['rpst'], + 'application/vnd.nokia.radio-presets' => ['rpss'], + 'application/vnd.novadigm.edm' => ['edm'], + 'application/vnd.novadigm.edx' => ['edx'], + 'application/vnd.novadigm.ext' => ['ext'], + 'application/vnd.oasis.opendocument.chart' => ['odc'], + 'application/vnd.oasis.opendocument.chart-template' => ['otc'], + 'application/vnd.oasis.opendocument.database' => ['odb'], + 'application/vnd.oasis.opendocument.formula' => ['odf'], + 'application/vnd.oasis.opendocument.formula-template' => ['odft'], + 'application/vnd.oasis.opendocument.graphics' => ['odg'], + 'application/vnd.oasis.opendocument.graphics-template' => ['otg'], + 'application/vnd.oasis.opendocument.image' => ['odi'], + 'application/vnd.oasis.opendocument.image-template' => ['oti'], + 'application/vnd.oasis.opendocument.presentation' => ['odp'], + 'application/vnd.oasis.opendocument.presentation-template' => ['otp'], + 'application/vnd.oasis.opendocument.spreadsheet' => ['ods'], + 'application/vnd.oasis.opendocument.spreadsheet-template' => ['ots'], + 'application/vnd.oasis.opendocument.text' => ['odt'], + 'application/vnd.oasis.opendocument.text-master' => ['odm'], + 'application/vnd.oasis.opendocument.text-template' => ['ott'], + 'application/vnd.oasis.opendocument.text-web' => ['oth'], + 'application/vnd.olpc-sugar' => ['xo'], + 'application/vnd.oma.dd2+xml' => ['dd2'], + 'application/vnd.openblox.game+xml' => ['obgx'], + 'application/vnd.openofficeorg.extension' => ['oxt'], + 'application/vnd.openstreetmap.data+xml' => ['osm'], + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' => ['pptx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slide' => ['sldx'], + 'application/vnd.openxmlformats-officedocument.presentationml.slideshow' => ['ppsx'], + 'application/vnd.openxmlformats-officedocument.presentationml.template' => ['potx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => ['xlsx'], + 'application/vnd.openxmlformats-officedocument.spreadsheetml.template' => ['xltx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => ['docx'], + 'application/vnd.openxmlformats-officedocument.wordprocessingml.template' => ['dotx'], + 'application/vnd.osgeo.mapguide.package' => ['mgp'], + 'application/vnd.osgi.dp' => ['dp'], + 'application/vnd.osgi.subsystem' => ['esa'], + 'application/vnd.palm' => ['pdb', 'pqa', 'oprc'], + 'application/vnd.pawaafile' => ['paw'], + 'application/vnd.pg.format' => ['str'], + 'application/vnd.pg.osasli' => ['ei6'], + 'application/vnd.picsel' => ['efif'], + 'application/vnd.pmi.widget' => ['wg'], + 'application/vnd.pocketlearn' => ['plf'], + 'application/vnd.powerbuilder6' => ['pbd'], + 'application/vnd.previewsystems.box' => ['box'], + 'application/vnd.proteus.magazine' => ['mgz'], + 'application/vnd.publishare-delta-tree' => ['qps'], + 'application/vnd.pvi.ptid1' => ['ptid'], + 'application/vnd.pwg-xhtml-print+xml' => ['xhtm'], + 'application/vnd.quark.quarkxpress' => ['qxd', 'qxt', 'qwd', 'qwt', 'qxl', 'qxb'], + 'application/vnd.rar' => ['rar'], + 'application/vnd.realvnc.bed' => ['bed'], + 'application/vnd.recordare.musicxml' => ['mxl'], + 'application/vnd.recordare.musicxml+xml' => ['musicxml'], + 'application/vnd.rig.cryptonote' => ['cryptonote'], + 'application/vnd.rim.cod' => ['cod'], + 'application/vnd.rn-realmedia' => ['rm'], + 'application/vnd.rn-realmedia-vbr' => ['rmvb'], + 'application/vnd.route66.link66+xml' => ['link66'], + 'application/vnd.sailingtracker.track' => ['st'], + 'application/vnd.seemail' => ['see'], + 'application/vnd.sema' => ['sema'], + 'application/vnd.semd' => ['semd'], + 'application/vnd.semf' => ['semf'], + 'application/vnd.shana.informed.formdata' => ['ifm'], + 'application/vnd.shana.informed.formtemplate' => ['itp'], + 'application/vnd.shana.informed.interchange' => ['iif'], + 'application/vnd.shana.informed.package' => ['ipk'], + 'application/vnd.simtech-mindmapper' => ['twd', 'twds'], + 'application/vnd.smaf' => ['mmf'], + 'application/vnd.smart.teacher' => ['teacher'], + 'application/vnd.software602.filler.form+xml' => ['fo'], + 'application/vnd.solent.sdkm+xml' => ['sdkm', 'sdkd'], + 'application/vnd.spotfire.dxp' => ['dxp'], + 'application/vnd.spotfire.sfs' => ['sfs'], + 'application/vnd.stardivision.calc' => ['sdc'], + 'application/vnd.stardivision.draw' => ['sda'], + 'application/vnd.stardivision.impress' => ['sdd'], + 'application/vnd.stardivision.math' => ['smf'], + 'application/vnd.stardivision.writer' => ['sdw', 'vor'], + 'application/vnd.stardivision.writer-global' => ['sgl'], + 'application/vnd.stepmania.package' => ['smzip'], + 'application/vnd.stepmania.stepchart' => ['sm'], + 'application/vnd.sun.wadl+xml' => ['wadl'], + 'application/vnd.sun.xml.calc' => ['sxc'], + 'application/vnd.sun.xml.calc.template' => ['stc'], + 'application/vnd.sun.xml.draw' => ['sxd'], + 'application/vnd.sun.xml.draw.template' => ['std'], + 'application/vnd.sun.xml.impress' => ['sxi'], + 'application/vnd.sun.xml.impress.template' => ['sti'], + 'application/vnd.sun.xml.math' => ['sxm'], + 'application/vnd.sun.xml.writer' => ['sxw'], + 'application/vnd.sun.xml.writer.global' => ['sxg'], + 'application/vnd.sun.xml.writer.template' => ['stw'], + 'application/vnd.sus-calendar' => ['sus', 'susp'], + 'application/vnd.svd' => ['svd'], + 'application/vnd.symbian.install' => ['sis', 'sisx'], + 'application/vnd.syncml+xml' => ['xsm'], + 'application/vnd.syncml.dm+wbxml' => ['bdm'], + 'application/vnd.syncml.dm+xml' => ['xdm'], + 'application/vnd.syncml.dmddf+xml' => ['ddf'], + 'application/vnd.tao.intent-module-archive' => ['tao'], + 'application/vnd.tcpdump.pcap' => ['pcap', 'cap', 'dmp'], + 'application/vnd.tmobile-livetv' => ['tmo'], + 'application/vnd.trid.tpt' => ['tpt'], + 'application/vnd.triscape.mxs' => ['mxs'], + 'application/vnd.trueapp' => ['tra'], + 'application/vnd.ufdl' => ['ufd', 'ufdl'], + 'application/vnd.uiq.theme' => ['utz'], + 'application/vnd.umajin' => ['umj'], + 'application/vnd.unity' => ['unityweb'], + 'application/vnd.uoml+xml' => ['uoml', 'uo'], + 'application/vnd.vcx' => ['vcx'], + 'application/vnd.visio' => ['vsd', 'vst', 'vss', 'vsw'], + 'application/vnd.visionary' => ['vis'], + 'application/vnd.vsf' => ['vsf'], + 'application/vnd.wap.wbxml' => ['wbxml'], + 'application/vnd.wap.wmlc' => ['wmlc'], + 'application/vnd.wap.wmlscriptc' => ['wmlsc'], + 'application/vnd.webturbo' => ['wtb'], + 'application/vnd.wolfram.player' => ['nbp'], + 'application/vnd.wordperfect' => ['wpd'], + 'application/vnd.wqd' => ['wqd'], + 'application/vnd.wt.stf' => ['stf'], + 'application/vnd.xara' => ['xar'], + 'application/vnd.xfdl' => ['xfdl'], + 'application/vnd.yamaha.hv-dic' => ['hvd'], + 'application/vnd.yamaha.hv-script' => ['hvs'], + 'application/vnd.yamaha.hv-voice' => ['hvp'], + 'application/vnd.yamaha.openscoreformat' => ['osf'], + 'application/vnd.yamaha.openscoreformat.osfpvg+xml' => ['osfpvg'], + 'application/vnd.yamaha.smaf-audio' => ['saf'], + 'application/vnd.yamaha.smaf-phrase' => ['spf'], + 'application/vnd.yellowriver-custom-menu' => ['cmp'], + 'application/vnd.zul' => ['zir', 'zirz'], + 'application/vnd.zzazz.deck+xml' => ['zaz'], + 'application/voicexml+xml' => ['vxml'], + 'application/wasm' => ['wasm'], + 'application/watcherinfo+xml' => ['wif'], + 'application/widget' => ['wgt'], + 'application/winhlp' => ['hlp'], + 'application/wsdl+xml' => ['wsdl'], + 'application/wspolicy+xml' => ['wspolicy'], + 'application/x-7z-compressed' => ['7z', '7zip'], + 'application/x-abiword' => ['abw'], + 'application/x-ace-compressed' => ['ace'], + 'application/x-apple-diskimage' => ['dmg'], + 'application/x-arj' => ['arj'], + 'application/x-authorware-bin' => ['aab', 'x32', 'u32', 'vox'], + 'application/x-authorware-map' => ['aam'], + 'application/x-authorware-seg' => ['aas'], + 'application/x-bcpio' => ['bcpio'], + 'application/x-bdoc' => ['bdoc'], + 'application/x-bittorrent' => ['torrent'], + 'application/x-blorb' => ['blb', 'blorb'], + 'application/x-bzip' => ['bz'], + 'application/x-bzip2' => ['bz2', 'boz'], + 'application/x-cbr' => ['cbr', 'cba', 'cbt', 'cbz', 'cb7'], + 'application/x-cdlink' => ['vcd'], + 'application/x-cfs-compressed' => ['cfs'], + 'application/x-chat' => ['chat'], + 'application/x-chess-pgn' => ['pgn'], + 'application/x-chrome-extension' => ['crx'], + 'application/x-cocoa' => ['cco'], + 'application/x-conference' => ['nsc'], + 'application/x-cpio' => ['cpio'], + 'application/x-csh' => ['csh'], + 'application/x-debian-package' => ['deb', 'udeb'], + 'application/x-dgc-compressed' => ['dgc'], + 'application/x-director' => ['dir', 'dcr', 'dxr', 'cst', 'cct', 'cxt', 'w3d', 'fgd', 'swa'], + 'application/x-doom' => ['wad'], + 'application/x-dtbncx+xml' => ['ncx'], + 'application/x-dtbook+xml' => ['dtb'], + 'application/x-dtbresource+xml' => ['res'], + 'application/x-dvi' => ['dvi'], + 'application/x-envoy' => ['evy'], + 'application/x-eva' => ['eva'], + 'application/x-font-bdf' => ['bdf'], + 'application/x-font-ghostscript' => ['gsf'], + 'application/x-font-linux-psf' => ['psf'], + 'application/x-font-pcf' => ['pcf'], + 'application/x-font-snf' => ['snf'], + 'application/x-font-type1' => ['pfa', 'pfb', 'pfm', 'afm'], + 'application/x-freearc' => ['arc'], + 'application/x-futuresplash' => ['spl'], + 'application/x-gca-compressed' => ['gca'], + 'application/x-glulx' => ['ulx'], + 'application/x-gnumeric' => ['gnumeric'], + 'application/x-gramps-xml' => ['gramps'], + 'application/x-gtar' => ['gtar'], + 'application/x-hdf' => ['hdf'], + 'application/x-httpd-php' => ['php', 'php4', 'php3', 'phtml'], + 'application/x-install-instructions' => ['install'], + 'application/x-iso9660-image' => ['iso'], + 'application/x-iwork-keynote-sffkey' => ['key'], + 'application/x-iwork-numbers-sffnumbers' => ['numbers'], + 'application/x-iwork-pages-sffpages' => ['pages'], + 'application/x-java-archive-diff' => ['jardiff'], + 'application/x-java-jnlp-file' => ['jnlp'], + 'application/x-keepass2' => ['kdbx'], + 'application/x-latex' => ['latex'], + 'application/x-lua-bytecode' => ['luac'], + 'application/x-lzh-compressed' => ['lzh', 'lha'], + 'application/x-makeself' => ['run'], + 'application/x-mie' => ['mie'], + 'application/x-mobipocket-ebook' => ['prc', 'mobi'], + 'application/x-ms-application' => ['application'], + 'application/x-ms-shortcut' => ['lnk'], + 'application/x-ms-wmd' => ['wmd'], + 'application/x-ms-wmz' => ['wmz'], + 'application/x-ms-xbap' => ['xbap'], + 'application/x-msaccess' => ['mdb'], + 'application/x-msbinder' => ['obd'], + 'application/x-mscardfile' => ['crd'], + 'application/x-msclip' => ['clp'], + 'application/x-msdos-program' => ['exe'], + 'application/x-msdownload' => ['exe', 'dll', 'com', 'bat', 'msi'], + 'application/x-msmediaview' => ['mvb', 'm13', 'm14'], + 'application/x-msmetafile' => ['wmf', 'wmz', 'emf', 'emz'], + 'application/x-msmoney' => ['mny'], + 'application/x-mspublisher' => ['pub'], + 'application/x-msschedule' => ['scd'], + 'application/x-msterminal' => ['trm'], + 'application/x-mswrite' => ['wri'], + 'application/x-netcdf' => ['nc', 'cdf'], + 'application/x-ns-proxy-autoconfig' => ['pac'], + 'application/x-nzb' => ['nzb'], + 'application/x-perl' => ['pl', 'pm'], + 'application/x-pilot' => ['prc', 'pdb'], + 'application/x-pkcs12' => ['p12', 'pfx'], + 'application/x-pkcs7-certificates' => ['p7b', 'spc'], + 'application/x-pkcs7-certreqresp' => ['p7r'], + 'application/x-rar-compressed' => ['rar'], + 'application/x-redhat-package-manager' => ['rpm'], + 'application/x-research-info-systems' => ['ris'], + 'application/x-sea' => ['sea'], + 'application/x-sh' => ['sh'], + 'application/x-shar' => ['shar'], + 'application/x-shockwave-flash' => ['swf'], + 'application/x-silverlight-app' => ['xap'], + 'application/x-sql' => ['sql'], + 'application/x-stuffit' => ['sit'], + 'application/x-stuffitx' => ['sitx'], + 'application/x-subrip' => ['srt'], + 'application/x-sv4cpio' => ['sv4cpio'], + 'application/x-sv4crc' => ['sv4crc'], + 'application/x-t3vm-image' => ['t3'], + 'application/x-tads' => ['gam'], + 'application/x-tar' => ['tar', 'tgz'], + 'application/x-tcl' => ['tcl', 'tk'], + 'application/x-tex' => ['tex'], + 'application/x-tex-tfm' => ['tfm'], + 'application/x-texinfo' => ['texinfo', 'texi'], + 'application/x-tgif' => ['obj'], + 'application/x-ustar' => ['ustar'], + 'application/x-virtualbox-hdd' => ['hdd'], + 'application/x-virtualbox-ova' => ['ova'], + 'application/x-virtualbox-ovf' => ['ovf'], + 'application/x-virtualbox-vbox' => ['vbox'], + 'application/x-virtualbox-vbox-extpack' => ['vbox-extpack'], + 'application/x-virtualbox-vdi' => ['vdi'], + 'application/x-virtualbox-vhd' => ['vhd'], + 'application/x-virtualbox-vmdk' => ['vmdk'], + 'application/x-wais-source' => ['src'], + 'application/x-web-app-manifest+json' => ['webapp'], + 'application/x-x509-ca-cert' => ['der', 'crt', 'pem'], + 'application/x-xfig' => ['fig'], + 'application/x-xliff+xml' => ['xlf'], + 'application/x-xpinstall' => ['xpi'], + 'application/x-xz' => ['xz'], + 'application/x-zmachine' => ['z1', 'z2', 'z3', 'z4', 'z5', 'z6', 'z7', 'z8'], + 'application/xaml+xml' => ['xaml'], + 'application/xcap-att+xml' => ['xav'], + 'application/xcap-caps+xml' => ['xca'], + 'application/xcap-diff+xml' => ['xdf'], + 'application/xcap-el+xml' => ['xel'], + 'application/xcap-ns+xml' => ['xns'], + 'application/xenc+xml' => ['xenc'], + 'application/xfdf' => ['xfdf'], + 'application/xhtml+xml' => ['xhtml', 'xht'], + 'application/xliff+xml' => ['xlf'], + 'application/xml' => ['xml', 'xsl', 'xsd', 'rng'], + 'application/xml-dtd' => ['dtd'], + 'application/xop+xml' => ['xop'], + 'application/xproc+xml' => ['xpl'], + 'application/xslt+xml' => ['xsl', 'xslt'], + 'application/xspf+xml' => ['xspf'], + 'application/xv+xml' => ['mxml', 'xhvml', 'xvml', 'xvm'], + 'application/yang' => ['yang'], + 'application/yin+xml' => ['yin'], + 'application/zip' => ['zip'], + 'audio/3gpp' => ['3gpp'], + 'audio/aac' => ['adts', 'aac'], + 'audio/adpcm' => ['adp'], + 'audio/amr' => ['amr'], + 'audio/basic' => ['au', 'snd'], + 'audio/midi' => ['mid', 'midi', 'kar', 'rmi'], + 'audio/mobile-xmf' => ['mxmf'], + 'audio/mp3' => ['mp3'], + 'audio/mp4' => ['m4a', 'mp4a'], + 'audio/mpeg' => ['mpga', 'mp2', 'mp2a', 'mp3', 'm2a', 'm3a'], + 'audio/ogg' => ['oga', 'ogg', 'spx', 'opus'], + 'audio/s3m' => ['s3m'], + 'audio/silk' => ['sil'], + 'audio/vnd.dece.audio' => ['uva', 'uvva'], + 'audio/vnd.digital-winds' => ['eol'], + 'audio/vnd.dra' => ['dra'], + 'audio/vnd.dts' => ['dts'], + 'audio/vnd.dts.hd' => ['dtshd'], + 'audio/vnd.lucent.voice' => ['lvp'], + 'audio/vnd.ms-playready.media.pya' => ['pya'], + 'audio/vnd.nuera.ecelp4800' => ['ecelp4800'], + 'audio/vnd.nuera.ecelp7470' => ['ecelp7470'], + 'audio/vnd.nuera.ecelp9600' => ['ecelp9600'], + 'audio/vnd.rip' => ['rip'], + 'audio/wav' => ['wav'], + 'audio/wave' => ['wav'], + 'audio/webm' => ['weba'], + 'audio/x-aac' => ['aac'], + 'audio/x-aiff' => ['aif', 'aiff', 'aifc'], + 'audio/x-caf' => ['caf'], + 'audio/x-flac' => ['flac'], + 'audio/x-m4a' => ['m4a'], + 'audio/x-matroska' => ['mka'], + 'audio/x-mpegurl' => ['m3u'], + 'audio/x-ms-wax' => ['wax'], + 'audio/x-ms-wma' => ['wma'], + 'audio/x-pn-realaudio' => ['ram', 'ra', 'rm'], + 'audio/x-pn-realaudio-plugin' => ['rmp', 'rpm'], + 'audio/x-realaudio' => ['ra'], + 'audio/x-wav' => ['wav'], + 'audio/xm' => ['xm'], + 'chemical/x-cdx' => ['cdx'], + 'chemical/x-cif' => ['cif'], + 'chemical/x-cmdf' => ['cmdf'], + 'chemical/x-cml' => ['cml'], + 'chemical/x-csml' => ['csml'], + 'chemical/x-xyz' => ['xyz'], + 'font/collection' => ['ttc'], + 'font/otf' => ['otf'], + 'font/ttf' => ['ttf'], + 'font/woff' => ['woff'], + 'font/woff2' => ['woff2'], + 'image/aces' => ['exr'], + 'image/apng' => ['apng'], + 'image/avci' => ['avci'], + 'image/avcs' => ['avcs'], + 'image/avif' => ['avif'], + 'image/bmp' => ['bmp', 'dib'], + 'image/cgm' => ['cgm'], + 'image/dicom-rle' => ['drle'], + 'image/dpx' => ['dpx'], + 'image/emf' => ['emf'], + 'image/fits' => ['fits'], + 'image/g3fax' => ['g3'], + 'image/gif' => ['gif'], + 'image/heic' => ['heic'], + 'image/heic-sequence' => ['heics'], + 'image/heif' => ['heif'], + 'image/heif-sequence' => ['heifs'], + 'image/hej2k' => ['hej2'], + 'image/hsj2' => ['hsj2'], + 'image/ief' => ['ief'], + 'image/jls' => ['jls'], + 'image/jp2' => ['jp2', 'jpg2'], + 'image/jpeg' => ['jpeg', 'jpg', 'jpe'], + 'image/jph' => ['jph'], + 'image/jphc' => ['jhc'], + 'image/jpm' => ['jpm', 'jpgm'], + 'image/jpx' => ['jpx', 'jpf'], + 'image/jxr' => ['jxr'], + 'image/jxra' => ['jxra'], + 'image/jxrs' => ['jxrs'], + 'image/jxs' => ['jxs'], + 'image/jxsc' => ['jxsc'], + 'image/jxsi' => ['jxsi'], + 'image/jxss' => ['jxss'], + 'image/ktx' => ['ktx'], + 'image/ktx2' => ['ktx2'], + 'image/png' => ['png'], + 'image/prs.btif' => ['btif', 'btf'], + 'image/prs.pti' => ['pti'], + 'image/sgi' => ['sgi'], + 'image/svg+xml' => ['svg', 'svgz'], + 'image/t38' => ['t38'], + 'image/tiff' => ['tif', 'tiff'], + 'image/tiff-fx' => ['tfx'], + 'image/vnd.adobe.photoshop' => ['psd'], + 'image/vnd.airzip.accelerator.azv' => ['azv'], + 'image/vnd.dece.graphic' => ['uvi', 'uvvi', 'uvg', 'uvvg'], + 'image/vnd.djvu' => ['djvu', 'djv'], + 'image/vnd.dvb.subtitle' => ['sub'], + 'image/vnd.dwg' => ['dwg'], + 'image/vnd.dxf' => ['dxf'], + 'image/vnd.fastbidsheet' => ['fbs'], + 'image/vnd.fpx' => ['fpx'], + 'image/vnd.fst' => ['fst'], + 'image/vnd.fujixerox.edmics-mmr' => ['mmr'], + 'image/vnd.fujixerox.edmics-rlc' => ['rlc'], + 'image/vnd.microsoft.icon' => ['ico'], + 'image/vnd.ms-dds' => ['dds'], + 'image/vnd.ms-modi' => ['mdi'], + 'image/vnd.ms-photo' => ['wdp'], + 'image/vnd.net-fpx' => ['npx'], + 'image/vnd.pco.b16' => ['b16'], + 'image/vnd.tencent.tap' => ['tap'], + 'image/vnd.valve.source.texture' => ['vtf'], + 'image/vnd.wap.wbmp' => ['wbmp'], + 'image/vnd.xiff' => ['xif'], + 'image/vnd.zbrush.pcx' => ['pcx'], + 'image/webp' => ['webp'], + 'image/wmf' => ['wmf'], + 'image/x-3ds' => ['3ds'], + 'image/x-cmu-raster' => ['ras'], + 'image/x-cmx' => ['cmx'], + 'image/x-freehand' => ['fh', 'fhc', 'fh4', 'fh5', 'fh7'], + 'image/x-icon' => ['ico'], + 'image/x-jng' => ['jng'], + 'image/x-mrsid-image' => ['sid'], + 'image/x-ms-bmp' => ['bmp'], + 'image/x-pcx' => ['pcx'], + 'image/x-pict' => ['pic', 'pct'], + 'image/x-portable-anymap' => ['pnm'], + 'image/x-portable-bitmap' => ['pbm'], + 'image/x-portable-graymap' => ['pgm'], + 'image/x-portable-pixmap' => ['ppm'], + 'image/x-rgb' => ['rgb'], + 'image/x-tga' => ['tga'], + 'image/x-xbitmap' => ['xbm'], + 'image/x-xpixmap' => ['xpm'], + 'image/x-xwindowdump' => ['xwd'], + 'message/disposition-notification' => ['disposition-notification'], + 'message/global' => ['u8msg'], + 'message/global-delivery-status' => ['u8dsn'], + 'message/global-disposition-notification' => ['u8mdn'], + 'message/global-headers' => ['u8hdr'], + 'message/rfc822' => ['eml', 'mime'], + 'message/vnd.wfa.wsc' => ['wsc'], + 'model/3mf' => ['3mf'], + 'model/gltf+json' => ['gltf'], + 'model/gltf-binary' => ['glb'], + 'model/iges' => ['igs', 'iges'], + 'model/jt' => ['jt'], + 'model/mesh' => ['msh', 'mesh', 'silo'], + 'model/mtl' => ['mtl'], + 'model/obj' => ['obj'], + 'model/prc' => ['prc'], + 'model/step+xml' => ['stpx'], + 'model/step+zip' => ['stpz'], + 'model/step-xml+zip' => ['stpxz'], + 'model/stl' => ['stl'], + 'model/u3d' => ['u3d'], + 'model/vnd.cld' => ['cld'], + 'model/vnd.collada+xml' => ['dae'], + 'model/vnd.dwf' => ['dwf'], + 'model/vnd.gdl' => ['gdl'], + 'model/vnd.gtw' => ['gtw'], + 'model/vnd.mts' => ['mts'], + 'model/vnd.opengex' => ['ogex'], + 'model/vnd.parasolid.transmit.binary' => ['x_b'], + 'model/vnd.parasolid.transmit.text' => ['x_t'], + 'model/vnd.pytha.pyox' => ['pyo', 'pyox'], + 'model/vnd.sap.vds' => ['vds'], + 'model/vnd.usda' => ['usda'], + 'model/vnd.usdz+zip' => ['usdz'], + 'model/vnd.valve.source.compiled-map' => ['bsp'], + 'model/vnd.vtu' => ['vtu'], + 'model/vrml' => ['wrl', 'vrml'], + 'model/x3d+binary' => ['x3db', 'x3dbz'], + 'model/x3d+fastinfoset' => ['x3db'], + 'model/x3d+vrml' => ['x3dv', 'x3dvz'], + 'model/x3d+xml' => ['x3d', 'x3dz'], + 'model/x3d-vrml' => ['x3dv'], + 'text/cache-manifest' => ['appcache', 'manifest'], + 'text/calendar' => ['ics', 'ifb'], + 'text/coffeescript' => ['coffee', 'litcoffee'], + 'text/css' => ['css'], + 'text/csv' => ['csv'], + 'text/html' => ['html', 'htm', 'shtml'], + 'text/jade' => ['jade'], + 'text/javascript' => ['js', 'mjs'], + 'text/jsx' => ['jsx'], + 'text/less' => ['less'], + 'text/markdown' => ['md', 'markdown'], + 'text/mathml' => ['mml'], + 'text/mdx' => ['mdx'], + 'text/n3' => ['n3'], + 'text/plain' => ['txt', 'text', 'conf', 'def', 'list', 'log', 'in', 'ini', 'm3u'], + 'text/prs.lines.tag' => ['dsc'], + 'text/richtext' => ['rtx'], + 'text/rtf' => ['rtf'], + 'text/sgml' => ['sgml', 'sgm'], + 'text/shex' => ['shex'], + 'text/slim' => ['slim', 'slm'], + 'text/spdx' => ['spdx'], + 'text/stylus' => ['stylus', 'styl'], + 'text/tab-separated-values' => ['tsv'], + 'text/troff' => ['t', 'tr', 'roff', 'man', 'me', 'ms'], + 'text/turtle' => ['ttl'], + 'text/uri-list' => ['uri', 'uris', 'urls'], + 'text/vcard' => ['vcard'], + 'text/vnd.curl' => ['curl'], + 'text/vnd.curl.dcurl' => ['dcurl'], + 'text/vnd.curl.mcurl' => ['mcurl'], + 'text/vnd.curl.scurl' => ['scurl'], + 'text/vnd.dvb.subtitle' => ['sub'], + 'text/vnd.familysearch.gedcom' => ['ged'], + 'text/vnd.fly' => ['fly'], + 'text/vnd.fmi.flexstor' => ['flx'], + 'text/vnd.graphviz' => ['gv'], + 'text/vnd.in3d.3dml' => ['3dml'], + 'text/vnd.in3d.spot' => ['spot'], + 'text/vnd.sun.j2me.app-descriptor' => ['jad'], + 'text/vnd.wap.wml' => ['wml'], + 'text/vnd.wap.wmlscript' => ['wmls'], + 'text/vtt' => ['vtt'], + 'text/wgsl' => ['wgsl'], + 'text/x-asm' => ['s', 'asm'], + 'text/x-c' => ['c', 'cc', 'cxx', 'cpp', 'h', 'hh', 'dic'], + 'text/x-component' => ['htc'], + 'text/x-fortran' => ['f', 'for', 'f77', 'f90'], + 'text/x-handlebars-template' => ['hbs'], + 'text/x-java-source' => ['java'], + 'text/x-lua' => ['lua'], + 'text/x-markdown' => ['mkd'], + 'text/x-nfo' => ['nfo'], + 'text/x-opml' => ['opml'], + 'text/x-org' => ['org'], + 'text/x-pascal' => ['p', 'pas'], + 'text/x-processing' => ['pde'], + 'text/x-sass' => ['sass'], + 'text/x-scss' => ['scss'], + 'text/x-setext' => ['etx'], + 'text/x-sfv' => ['sfv'], + 'text/x-suse-ymp' => ['ymp'], + 'text/x-uuencode' => ['uu'], + 'text/x-vcalendar' => ['vcs'], + 'text/x-vcard' => ['vcf'], + 'text/xml' => ['xml'], + 'text/yaml' => ['yaml', 'yml'], + 'video/3gpp' => ['3gp', '3gpp'], + 'video/3gpp2' => ['3g2'], + 'video/h261' => ['h261'], + 'video/h263' => ['h263'], + 'video/h264' => ['h264'], + 'video/iso.segment' => ['m4s'], + 'video/jpeg' => ['jpgv'], + 'video/jpm' => ['jpm', 'jpgm'], + 'video/mj2' => ['mj2', 'mjp2'], + 'video/mp2t' => ['ts'], + 'video/mp4' => ['mp4', 'mp4v', 'mpg4', 'f4v'], + 'video/mpeg' => ['mpeg', 'mpg', 'mpe', 'm1v', 'm2v'], + 'video/ogg' => ['ogv'], + 'video/quicktime' => ['qt', 'mov'], + 'video/vnd.dece.hd' => ['uvh', 'uvvh'], + 'video/vnd.dece.mobile' => ['uvm', 'uvvm'], + 'video/vnd.dece.pd' => ['uvp', 'uvvp'], + 'video/vnd.dece.sd' => ['uvs', 'uvvs'], + 'video/vnd.dece.video' => ['uvv', 'uvvv'], + 'video/vnd.dvb.file' => ['dvb'], + 'video/vnd.fvt' => ['fvt'], + 'video/vnd.mpegurl' => ['mxu', 'm4u'], + 'video/vnd.ms-playready.media.pyv' => ['pyv'], + 'video/vnd.uvvu.mp4' => ['uvu', 'uvvu'], + 'video/vnd.vivo' => ['viv'], + 'video/webm' => ['webm'], + 'video/x-f4v' => ['f4v'], + 'video/x-fli' => ['fli'], + 'video/x-flv' => ['flv'], + 'video/x-m4v' => ['m4v'], + 'video/x-matroska' => ['mkv', 'mk3d', 'mks'], + 'video/x-mng' => ['mng'], + 'video/x-ms-asf' => ['asf', 'asx'], + 'video/x-ms-vob' => ['vob'], + 'video/x-ms-wm' => ['wm'], + 'video/x-ms-wmv' => ['wmv'], + 'video/x-ms-wmx' => ['wmx'], + 'video/x-ms-wvx' => ['wvx'], + 'video/x-msvideo' => ['avi'], + 'video/x-sgi-movie' => ['movie'], + 'video/x-smv' => ['smv'], + 'x-conference/x-cooltalk' => ['ice'], + 'application/x-photoshop' => ['psd'], + 'application/smil' => ['smi', 'smil'], + 'application/powerpoint' => ['ppt'], + 'application/vnd.ms-powerpoint.addin.macroEnabled.12' => ['ppam'], + 'application/vnd.ms-powerpoint.presentation.macroEnabled.12' => ['pptm', 'potm'], + 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12' => ['ppsm'], + 'application/wbxml' => ['wbxml'], + 'application/wmlc' => ['wmlc'], + 'application/x-httpd-php-source' => ['phps'], + 'application/x-compress' => ['z'], + 'application/x-rar' => ['rar'], + 'video/vnd.rn-realvideo' => ['rv'], + 'application/vnd.ms-word.template.macroEnabled.12' => ['docm', 'dotm'], + 'application/vnd.ms-excel.sheet.macroEnabled.12' => ['xlsm'], + 'application/vnd.ms-excel.template.macroEnabled.12' => ['xltm'], + 'application/vnd.ms-excel.addin.macroEnabled.12' => ['xlam'], + 'application/vnd.ms-excel.sheet.binary.macroEnabled.12' => ['xlsb'], + 'application/excel' => ['xl'], + 'application/x-x509-user-cert' => ['pem'], + 'application/x-pkcs10' => ['p10'], + 'application/x-pkcs7-signature' => ['p7a'], + 'application/pgp' => ['pgp'], + 'application/gpg-keys' => ['gpg'], + 'application/x-pkcs7' => ['rsa'], + 'video/3gp' => ['3gp'], + 'audio/x-acc' => ['aac'], + 'application/vnd.mpegurl' => ['m4u'], + 'application/videolan' => ['vlc'], + 'audio/x-au' => ['au'], + 'audio/ac3' => ['ac3'], + 'text/x-scriptzsh' => ['zsh'], + 'application/cdr' => ['cdr'], + 'application/STEP' => ['step', 'stp'], + ]; + public function lookupMimeType(string $extension): ?string { return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; } + public function lookupExtension(string $mimetype): ?string + { + return self::EXTENSIONS_FOR_MIME_TIMES[$mimetype][0] ?? null; + } + /** - * @param string $mimeType * @return string[] */ - public function lookupExtensions(string $mimeType): array + public function lookupAllExtensions(string $mimetype): array { - return array_keys(array_filter(self::MIME_TYPES_FOR_EXTENSIONS, function ($mimeTypeFromArray) use ($mimeType - ): bool { - return $mimeType === $mimeTypeFromArray; - })); + return self::EXTENSIONS_FOR_MIME_TIMES[$mimetype] ?? []; } } diff --git a/src/GeneratedExtensionToMimeTypeMapTest.php b/src/GeneratedExtensionToMimeTypeMapTest.php index 5ff918e..cf3341b 100644 --- a/src/GeneratedExtensionToMimeTypeMapTest.php +++ b/src/GeneratedExtensionToMimeTypeMapTest.php @@ -58,19 +58,20 @@ public function the_generated_map_should_be_up_to_date(): void */ public function looking_up_extensions(string $mimeType, array $expectedExtensions): void { + // arrange $map = new GeneratedExtensionToMimeTypeMap(); - $actual = $map->lookupExtensions($mimeType); - sort($expectedExtensions); - sort($actual); + // act + $actual = $map->lookupAllExtensions($mimeType); + // assert $this->assertEquals($expectedExtensions, $actual); } public function expectedExtensionResults(): Generator { yield ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', ['docx']]; - yield ['image/jpeg', ['jpg', 'jpeg', 'jpe']]; + yield ['image/jpeg', ['jpeg', 'jpg', 'jpe']]; yield ['image/svg+xml', ['svg', 'svgz']]; yield ['lol/lol', []]; } diff --git a/src/Generation/ExtensionToMimeTypeMap.php.template b/src/Generation/ExtensionToMimeTypeMap.php.template index e581234..e18f305 100644 --- a/src/Generation/ExtensionToMimeTypeMap.php.template +++ b/src/Generation/ExtensionToMimeTypeMap.php.template @@ -4,29 +4,37 @@ declare(strict_types=1); namespace League\MimeTypeDetection; -class ExtensionToMimeTypeMapClass implements ExtensionToMimeTypeMap +class ExtensionToMimeTypeMapClass implements ExtensionToMimeTypeMap, ExtensionLookup { /** - * @var string[] + * @var array * * @internal */ - public const MIME_TYPES_FOR_EXTENSIONS = []; + public const MIME_TYPES_FOR_EXTENSIONS = ['ext2mime']; + + /** + * @var array + * + * @internal + */ + public const EXTENSIONS_FOR_MIME_TIMES = ['mime2ext']; public function lookupMimeType(string $extension): ?string { return self::MIME_TYPES_FOR_EXTENSIONS[$extension] ?? null; } + public function lookupExtension(string $mimetype): ?string + { + return self::EXTENSIONS_FOR_MIME_TIMES[$mimetype][0] ?? null; + } + /** - * @param string $mimeType * @return string[] */ - public function lookupExtensions(string $mimeType): array + public function lookupAllExtensions(string $mimetype): array { - return array_keys(array_filter(self::MIME_TYPES_FOR_EXTENSIONS, function ($mimeTypeFromArray) use ($mimeType - ): bool { - return $mimeType === $mimeTypeFromArray; - })); + return self::EXTENSIONS_FOR_MIME_TIMES[$mimetype] ?? []; } } diff --git a/src/Generation/ExtensionToMimeTypeMapGenerator.php b/src/Generation/ExtensionToMimeTypeMapGenerator.php index 691bc7c..c53046d 100644 --- a/src/Generation/ExtensionToMimeTypeMapGenerator.php +++ b/src/Generation/ExtensionToMimeTypeMapGenerator.php @@ -4,6 +4,8 @@ namespace League\MimeTypeDetection\Generation; +use function array_unique; +use function join; use const PHP_EOL; class ExtensionToMimeTypeMapGenerator @@ -22,16 +24,24 @@ public function dump(string $className): string { /** @var string[] $mimeTypes */ $mimeTypes = []; + $reverseLookup = []; + $compiledReverseLookup = []; foreach ($this->provider->provideMimeTypes() as $mimeTypeForExtension) { $mimeTypes[$mimeTypeForExtension->extension()] = PHP_EOL . " '{$mimeTypeForExtension->extension()}' => '{$mimeTypeForExtension->mimeType()}',"; + $extensions = $reverseLookup[$mimeTypeForExtension->mimeType()] ?? []; + $extensions[] = $mimeTypeForExtension->extension(); + $reverseLookup[$mimeTypeForExtension->mimeType()] = $extensions; + $extensionsAsCode = '[\'' . join('\', \'', array_unique($extensions)) . '\']'; + $compiledReverseLookup[$mimeTypeForExtension->mimeType()] = PHP_EOL . " '{$mimeTypeForExtension->mimeType()}' => $extensionsAsCode,"; } ksort($mimeTypes, SORT_NATURAL); $template = file_get_contents(__DIR__ . '/ExtensionToMimeTypeMap.php.template'); $template = str_replace('ExtensionToMimeTypeMapClass', $className, $template); - $template = str_replace(' = []', ' = [' . join('', $mimeTypes) . PHP_EOL . ' ]', $template); + $template = str_replace(' = [\'ext2mime\']', ' = [' . join('', $mimeTypes) . PHP_EOL . ' ]', $template); + $template = str_replace(' = [\'mime2ext\']', ' = [' . join('', $compiledReverseLookup) . PHP_EOL . ' ]', $template); return $template; } From 86216aeebfd5fc3de348fcf43846e2f531784297 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sat, 5 Aug 2023 12:54:31 +0200 Subject: [PATCH 23/26] Added missing file, make extension based implementation also use the reverse lookup. --- src/ExtensionLookup.php | 14 ++++++++++++++ src/ExtensionMimeTypeDetector.php | 16 +++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 src/ExtensionLookup.php diff --git a/src/ExtensionLookup.php b/src/ExtensionLookup.php new file mode 100644 index 0000000..8b91b27 --- /dev/null +++ b/src/ExtensionLookup.php @@ -0,0 +1,14 @@ +extensions instanceof ExtensionLookup + ? $this->extensions->lookupExtension($mimetype) + : null; + } + + public function lookupAllExtensions(string $mimetype): array + { + return $this->extensions instanceof ExtensionLookup + ? $this->extensions->lookupAllExtensions($mimetype) + : []; + } } From 56b1195adb7fbd01fae2fa56793e5ae775eac00d Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sat, 5 Aug 2023 13:00:57 +0200 Subject: [PATCH 24/26] Updated phpunit and remove very old php versions. --- .github/workflows/quality-assurance.yml | 2 +- composer.json | 6 +++--- src/ExtensionLookup.php | 2 +- src/ExtensionMimeTypeDetectorTest.php | 3 ++- src/GeneratedExtensionToMimeTypeMapTest.php | 7 +++++-- src/Generation/ExtensionToMimeTypeMapGenerator.php | 2 +- 6 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/quality-assurance.yml b/.github/workflows/quality-assurance.yml index 3649ab8..fbab5b4 100644 --- a/.github/workflows/quality-assurance.yml +++ b/.github/workflows/quality-assurance.yml @@ -20,7 +20,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php: [ '7.2', '7.3', '7.4', '8.0' ] + php: [ '7.4', '8.0', '8.1', '8.2' ] composer-flags: [ '' ] upgrade-aws-sdk: [ 'no' ] phpunit-flags: [ '--coverage-text' ] diff --git a/composer.json b/composer.json index 80ca1af..cd75bee 100644 --- a/composer.json +++ b/composer.json @@ -13,11 +13,11 @@ "phpstan": "vendor/bin/phpstan analyse -l 6 src" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "ext-fileinfo": "*" }, "require-dev": { - "phpunit/phpunit": "^8.5.8 || ^9.3", + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0", "phpstan/phpstan": "^0.12.68", "friendsofphp/php-cs-fixer": "^3.2" }, @@ -28,7 +28,7 @@ }, "config": { "platform": { - "php": "7.2.0" + "php": "7.4.0" } } } diff --git a/src/ExtensionLookup.php b/src/ExtensionLookup.php index 8b91b27..14b89df 100644 --- a/src/ExtensionLookup.php +++ b/src/ExtensionLookup.php @@ -11,4 +11,4 @@ public function lookupExtension(string $mimetype): ?string; * @return string[] */ public function lookupAllExtensions(string $mimetype): array; -} \ No newline at end of file +} diff --git a/src/ExtensionMimeTypeDetectorTest.php b/src/ExtensionMimeTypeDetectorTest.php index c47077d..aa1e611 100644 --- a/src/ExtensionMimeTypeDetectorTest.php +++ b/src/ExtensionMimeTypeDetectorTest.php @@ -11,6 +11,7 @@ class ExtensionMimeTypeDetectorTest extends TestCase { /** * @test + * * @dataProvider expectedLookupResults */ public function looking_up_mimetype(string $path, ?string $expectedMimeType): void @@ -35,7 +36,7 @@ public function detecting_from_bugger_always_returns_null(): void $this->assertNull($mimeType); } - public function expectedLookupResults(): Generator + public static function expectedLookupResults(): Generator { yield ['thing.jpg', 'image/jpeg']; yield ['file.svg', 'image/svg+xml']; diff --git a/src/GeneratedExtensionToMimeTypeMapTest.php b/src/GeneratedExtensionToMimeTypeMapTest.php index cf3341b..c703e29 100644 --- a/src/GeneratedExtensionToMimeTypeMapTest.php +++ b/src/GeneratedExtensionToMimeTypeMapTest.php @@ -15,6 +15,7 @@ class GeneratedExtensionToMimeTypeMapTest extends TestCase { /** * @test + * * @dataProvider expectedLookupResults */ public function looking_up_mimetypes(string $extension, ?string $expectedMimeType): void @@ -24,7 +25,7 @@ public function looking_up_mimetypes(string $extension, ?string $expectedMimeTyp $this->assertEquals($expectedMimeType, $actual); } - public function expectedLookupResults(): Generator + public static function expectedLookupResults(): Generator { yield ['jpg', 'image/jpeg']; yield ['svg', 'image/svg+xml']; @@ -52,7 +53,9 @@ public function the_generated_map_should_be_up_to_date(): void /** * @test + * * @dataProvider expectedExtensionResults + * * @param string $mimeType * @param string[] $expectedExtensions */ @@ -68,7 +71,7 @@ public function looking_up_extensions(string $mimeType, array $expectedExtension $this->assertEquals($expectedExtensions, $actual); } - public function expectedExtensionResults(): Generator + public static function expectedExtensionResults(): Generator { yield ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', ['docx']]; yield ['image/jpeg', ['jpeg', 'jpg', 'jpe']]; diff --git a/src/Generation/ExtensionToMimeTypeMapGenerator.php b/src/Generation/ExtensionToMimeTypeMapGenerator.php index c53046d..952b2f7 100644 --- a/src/Generation/ExtensionToMimeTypeMapGenerator.php +++ b/src/Generation/ExtensionToMimeTypeMapGenerator.php @@ -4,9 +4,9 @@ namespace League\MimeTypeDetection\Generation; +use const PHP_EOL; use function array_unique; use function join; -use const PHP_EOL; class ExtensionToMimeTypeMapGenerator { From 9bdcb30ef30deacc90e10ca86f604a2623114494 Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sat, 5 Aug 2023 13:01:44 +0200 Subject: [PATCH 25/26] Use 7.4 as lowest version instead of 7.2 --- .github/workflows/quality-assurance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality-assurance.yml b/.github/workflows/quality-assurance.yml index fbab5b4..6dbdeb1 100644 --- a/.github/workflows/quality-assurance.yml +++ b/.github/workflows/quality-assurance.yml @@ -25,7 +25,7 @@ jobs: upgrade-aws-sdk: [ 'no' ] phpunit-flags: [ '--coverage-text' ] include: - - php: '7.2' + - php: '7.4' composer-flags: '--prefer-lowest' phpunit-flags: '--no-coverage' steps: From 7c26dd1594072c9e73213f5d0e296218c2ecb53d Mon Sep 17 00:00:00 2001 From: Frank de Jonge Date: Sat, 5 Aug 2023 13:43:03 +0200 Subject: [PATCH 26/26] Fixed #23: Corrected aac mimetype --- src/GeneratedExtensionToMimeTypeMap.php | 4 ++-- src/Generation/FlysystemProvidedMimeTypeProvider.php | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/GeneratedExtensionToMimeTypeMap.php b/src/GeneratedExtensionToMimeTypeMap.php index eb9f278..72f515f 100644 --- a/src/GeneratedExtensionToMimeTypeMap.php +++ b/src/GeneratedExtensionToMimeTypeMap.php @@ -23,7 +23,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap, Extensi '7zip' => 'application/x-7z-compressed', '123' => 'application/vnd.lotus-1-2-3', 'aab' => 'application/x-authorware-bin', - 'aac' => 'audio/x-acc', + 'aac' => 'audio/acc', 'aam' => 'application/x-authorware-map', 'aas' => 'application/x-authorware-seg', 'abw' => 'application/x-abiword', @@ -2261,7 +2261,7 @@ class GeneratedExtensionToMimeTypeMap implements ExtensionToMimeTypeMap, Extensi 'application/gpg-keys' => ['gpg'], 'application/x-pkcs7' => ['rsa'], 'video/3gp' => ['3gp'], - 'audio/x-acc' => ['aac'], + 'audio/acc' => ['aac'], 'application/vnd.mpegurl' => ['m4u'], 'application/videolan' => ['vlc'], 'audio/x-au' => ['au'], diff --git a/src/Generation/FlysystemProvidedMimeTypeProvider.php b/src/Generation/FlysystemProvidedMimeTypeProvider.php index a257fac..6d6435b 100644 --- a/src/Generation/FlysystemProvidedMimeTypeProvider.php +++ b/src/Generation/FlysystemProvidedMimeTypeProvider.php @@ -152,7 +152,8 @@ public function provideMimeTypes(): array new MimeTypeForExtension('audio/x-m4a', 'm4a'), new MimeTypeForExtension('video/mp4', 'f4v'), new MimeTypeForExtension('video/webm', 'webm'), - new MimeTypeForExtension('audio/x-acc', 'aac'), + new MimeTypeForExtension('audio/x-aac', 'aac'), + new MimeTypeForExtension('audio/acc', 'aac'), new MimeTypeForExtension('application/vnd.mpegurl', 'm4u'), new MimeTypeForExtension('text/plain', 'm3u'), new MimeTypeForExtension('application/xspf+xml', 'xspf'),