Почему я построил downldr | Кодементор

Проблема, которую я хотел решить

Я хотел, чтобы загрузчик файлов проверял, что загружаемый файл соответствует типу файла, который я хотел загрузить, чтобы избежать сохранения недействительных файлов. действительный тип файла, а не то, что Content-Type заголовок говорит!

В любом случае, я не нашел пакета, позволяющего фильтровать, даже с Content-Type заголовок, поэтому я решил построить один!

Если вы знаете какой-либо, пожалуйста, оставьте комментарий с названием пакета.

Что такое даунлдр?

Это загрузчик файлов, который позволяет фильтровать типы файлов и условную конвейерную передачу, поэтому, если загруженный файл неверен или запрос не выполнен, вы не получите пустой файл.

Где я могу получить это?

Вы можете получить его от нпм

npm install downldr

Как работает фильтрация

Используя расширение или Content-Type заголовок для определения типа файла не является пуленепробиваемым, поскольку для заголовка может быть установлено любое значение, и обычно по умолчанию используется тип, обнаруженный расширением, и если расширение отсутствует, оно может выглядеть как application/octet-stream

Все мы знаем, что можем сделать следующее:

mv video.mp4 image.jpg

Теперь у нас есть видео, с jpg расширение, но это видео в конце.

Поэтому, если бы мы загрузили этот файл, чтобы позже использовать его в нашем приложении, мы бы получили неожиданные результаты.

downldr('
  .pipe(fs.createWriteStream(path.join(__dirname, 'images', 'image.jpg'));

К счастью для нас downldr поставляется с filter опция, которая позволяет нам фильтровать, какие файлы мы хотим загрузить, и не использует Content-Type ни расширение для его обнаружения 😃.

Большинство файлов имеют подпись, которая позволяет нам идентифицировать или проверить содержимое. Эту подпись часто называют магическими числами или магическими байтами. downldr использует file-type пакет под капотом, чтобы обеспечить эту функциональность.

Но если вы хотите реализовать это самостоятельно, для определенного типа файлов, это не так сложно сделать.

Например, шестнадцатеричная подпись для png файл: 89 50 4E 47 0D 0A 1A 0A

В Node.js это означает: Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);

Итак, код для реализации детектора png выглядит следующим образом:

function isPNG(buffer) {
    const magicBytes = Buffer.from([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);    
    return buffer.indexOf(magicBytes) === 0;
}

fs.createReadStream('image.png') 
    .once('data', chunk => {
        console.log(`png: ${isPNG(chunk)}`); 
    });
    
fs.readFile('image.jpg', (err, content) => {
    console.log(`png: ${isPNG(chunk)}`); 
});

Обратите внимание, что нам нужно всего несколько байтов, поэтому достаточно отправить первую часть потока!

Теперь давайте посмотрим, как осуществляется фильтрация файлов в downldr.

downldr(' {
    filter: (type, chunk, statusCode) => {
    	// type.mime may be undefined for some files
        console.log(type.contentType); // image/jpg
        console.log(type.mime); // video/mp4
        return type.mime === 'image/jpeg';
    },
    // For the above filtering, it will be out.jpg
    target: (ext) => fs.createWriteStream(`out.${ext}`)
})
// Error: Invalid type: video/mp4 - Status Code: 200
.on('error', console.error)
.on('complete', () => console.log('done!'));

Когда используешь target вариант вместо .pipe он работает как условная труба.
Он создаст файловый поток только после того, как filter функция возвращает true, таким образом мы избегаем создания пустого файла!


Вы можете проверить документация для большего количества опций и расширенного использования!

Похожие записи

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *