Как проверить допустимые типы файлов для нестандартных типов MIME? - PullRequest
0 голосов
/ 09 апреля 2020

Типы файлов MIME более надежны, чем расширения файлов, когда мы говорим о проверке допустимых типов файлов. Мы создаем функцию загрузки файлов в Laravel (5.8) с зависимостями Laravel Файловая система и интервенция / изображение. Но проблема ни с одним из них. Вот сокращенная версия нашего кода:

Фон

Шаг 1: Настройка

Типы MIME

У нас есть все типы MIME для каждого из расширения в функции, как показано ниже:

// Standard MIME types.
function mime_types() {
    return array(
        'zip' => 'application/zip',
        'mp3' => 'audio/mpeg',
    );
}

Принятые расширения

Мы принимаем пользовательский ввод для принятых типов файлов (расширений) в виде строки через запятую:

$accepted_extensions = '.mp3, .zip';

Принятые типы MIME

Используя функцию, подобную приведенной ниже, мы получаем определенные пользователем принятые типы MIME:

function get_mime_types_from_extensions($fileExtensions) {
    $fileTypes = explode(',', $fileExtensions);
    $mimeTypes = array();
    foreach ($fileTypes as $fileExtension) {
        $fileExtension = preg_replace('/\s+/', '', $fileExtension);
        $fileExtension = strtr($fileExtension, array('.' => ''));
        $mimeTypes[$fileExtension] = self::mimeTypeFromExtension($fileExtension);
    }
    return $mimeTypes;
}

Шаг 2: Обработка загрузки

Теперь мы Вы решаете, подходит ли файл для go, иначе выдает ошибку:

function handle_upload(Request $request) {
    $file = $request->file;
    $file_mime_type = $file->getClientMimeType();
    $accepted_MIME_types = get_mime_types_from_extensions($accepted_extensions);

    // The issue is down below...
    if (! in_array($file_mime_type, $accepted_MIME_types)) {
        // Thow error 'File Type not accepted'.
        return false;
    }

    // Upload the file.
}

Вся установка работает отлично для всех случаев.

Проблема

Но недавно мы только что узнали, что некоторые браузеры не возвращают надлежащие типы MIME для определенных расширений. В этой ветке SO это подробно описано.

+------------+-----------------+-------------------------------------+
| Extensions | Standard MIMEs  | Exceptions                          |
+------------+-----------------+-------------------------------------+
| mp3        | audio/mpeg      | audio/mp3 (Chromium)                |
| zip        | application/zip | application/octet-stream (Chromium) |
| zip        | application/zip | application/x-zip-compressed (IE)   |
...
+------------+-----------------+-------------------------------------+

Теперь, когда я пытаюсь загрузить файл .mp3 из браузера Chromium (Google Chrome, Edge (Chromium) , et c.) $file_mime_type возвращает 'audio/mp3' (вместо 'audio/mpeg'), а функция загрузки выдает ошибку неприятия. Несмотря на то, что это действительный mp3-файл с правильным типом MIME, потому что он загружается в Mozilla Firefox. (Мы попробовали с примером файла mp3 из здесь )

То, что мы попробовали до сих пор

Laravel API проверки

После обсуждения с нашей командой, Один из наших коллег, г-н Рубель, предложил нам go с Laravel API проверки. Итак, мы попробовали:

function handle_upload(Request $request) {
    $validator = Validator::make($request->all(), ['file' => 'mimes:mp3,zip']);

    if ($validator->fails()) {
        return redirect()->back()
            ->withErrors($validator)
            ->withInput($request->all);
    }

    // Upload the file.
}

Но, к сожалению, это ограничивает нас для загрузки действительного файла .mp3 во все браузеры, даже в Firefox.

Error with Laravel Validation - uploading mp3

И глубоко внутри Laravel также есть аналогичная структура для обработки проверки файлов, как мы уже нашли / поняли.

Консультирование WordPress

Консультирование WordPress не было , что просто, потому что они могут использовать другой подход. Но мы нашли кое-что, что заинтересовало нас - в /wp-includes/functions.php, в строке #2869 (по состоянию на WP 5.4) - комментарий PHP:

Если $ real_mime не соответствует типу содержимого, которое мы ожидаем от расширения файла, нам нужно выполнить дополнительную проверку. Типы мультимедиа и перечисленные в $ nonspecific_types допускаются с некоторой задержкой, но все остальное должно точно соответствовать реальному типу контента.

Мы не нашли там никакого конкретного решения, в нашей работе но может гарантировать, что WordPress сможет загрузить этот конкретный действительный файл mp3 даже в Chrome / Edge.

Вопрос

Как проверить допустимые типы файлов для нестандартных типов MIME?

...