Existe-t-il un moyen à toute épreuve de détecter le type MIME de fichier téléchargé dans Ruby ou Ruby on Rails? Je télécharge des fichiers JPEG et PNG à l'aide de SWFupload et content_type
est toujours "application/octet-stream"
Le Ruby-filemagic gem le fera:
require 'filemagic'
puts FileMagic.new(FileMagic::MAGIC_MIME).file(__FILE__)
# => text/x-Ruby; charset=us-ascii
Cette gemme ne regarde pas du tout l'extension du fichier. Il lit un peu du contenu du fichier et l'utilise pour deviner le type du fichier.
Dans Ruby on Rails vous pouvez faire:
MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
Vous pouvez utiliser cette base de méthode fiable sur l'en-tête magique du fichier:
def get_image_extension(local_file_path)
png = Regexp.new("\x89PNG".force_encoding("binary"))
jpg = Regexp.new("\xff\xd8\xff\xe0\x00\x10JFIF".force_encoding("binary"))
jpg2 = Regexp.new("\xff\xd8\xff\xe1(.*){2}Exif".force_encoding("binary"))
case IO.read(local_file_path, 10)
when /^GIF8/
'gif'
when /^#{png}/
'png'
when /^#{jpg}/
'jpg'
when /^#{jpg2}/
'jpg'
else
mime_type = `file #{local_file_path} --mime-type`.gsub("\n", '') # Works on linux and mac
raise UnprocessableEntity, "unknown file type" if !mime_type
mime_type.split(':')[1].split('/')[1].gsub('x-', '').gsub(/jpeg/, 'jpg').gsub(/text/, 'txt').gsub(/x-/, '')
end
end
La gemme Ruby-filemagic est une bonne solution, mais nécessite des dépendances supplémentaires sur libmagic (récemment supprimé de CarrierWave dans le cadre de Suppression de CarrierWave :: MagicMimeTypes ).
Si vous êtes intéressé par une pure implémentation Ruby, considérez la gemme MimeMagic ! Cela fonctionne bien pour les types de fichiers répertoriés dans la base de données mime freedesktop.org:
require 'mimemagic'
MimeMagic.by_magic(File.open('Table-Flip-Guy.jpg')).type # => "image/jpeg"
Pour les formats Microsoft Office 2007+ (xlsx, docx et pptx), exigez la superposition (sauf si vous êtes d'accord avec le type MIME générique "application/Zip" pour ces fichiers)
require 'mimemagic'
require 'mimemagic/overlay'
MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
filemagic gem est une bonne solution mais dépend de beaucoup de gemmes inutiles. (Rails, aws-sdk-core, ...)
Si votre application est petite et ne fonctionne que sous Linux ou OSX, pensez à utiliser le programme file
:
require 'shellwords'
mimetype = `file --brief --mime-type - < #{Shellwords.shellescape(__FILE__)}`.strip
Remarque: remplacez __FILE__
avec tout expr contient le chemin du fichier.
bijou mimémagique le fera aussi
https://github.com/minad/mimemagic
de la documentation officielle
MimeMagic est une bibliothèque pour détecter le type mime d'un fichier par extension ou par contenu. Il utilise la base de données mime fournie par freedesktop.org (voir http://freedesktop.org/wiki/Software/shared-mime-info/ ).
require 'mimemagic' MimeMagic.by_extension('html').text? MimeMagic.by_extension('.html').child_of? 'text/plain' MimeMagic.by_path('filename.txt') MimeMagic.by_magic(File.open('test.html')) # etc...