web-dev-qa-db-ja.com

RubyでアップロードされたファイルのMIMEタイプを検出

Ruby or Ruby on Rails?SWFuploadとcontent_typeを使用してJPEGとPNGをアップロードしています。常に"application/octet-stream"

43
Vincent

Ruby-filemagic gemがそれを行います:

require 'filemagic'

puts FileMagic.new(FileMagic::MAGIC_MIME).file(__FILE__)
# => text/x-Ruby; charset=us-ascii

このgemは、ファイル拡張子をまったく見ません。ファイルの内容の一部を読み取り、それを使用してファイルのタイプを推測します。

47
Wayne Conrad

In Ruby on Railsできること:

MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
39
NARKOZ

ファイルのマジックヘッダーに基づいて、この信頼できるメソッドを使用できます。

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
21
Alain Beauvois

Ruby-filemagic gemは適切なソリューションですが、libmagicに追加の依存関係が必要です(の一部としてCarrierWaveから削除されました) CarrierWave :: MagicMimeTypes削除)。

純粋なRubyの実装に興味がある場合は、 MimeMagic gemを検討してください!freedesktop.org mimeデータベースにリストされているファイルタイプに適しています:

require 'mimemagic'

MimeMagic.by_magic(File.open('Table-Flip-Guy.jpg')).type # => "image/jpeg" 

Microsoft Office 2007+形式(xlsx、docx、およびpptx)の場合、オーバーレイが必要です(これらのファイルの一般的な「application/Zip」MIMEタイプに問題がない場合)

require 'mimemagic'    
require 'mimemagic/overlay'

MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
11
Marc

filemagic gemは良い解決策ですが、多くの不要なgemに依存しています。 (レール、aws-sdk-core、...)

アプリが小さく、LinuxまたはOSXでのみ実行される場合は、fileプログラムの使用を検討してください。

require 'shellwords'
mimetype = `file --brief --mime-type - < #{Shellwords.shellescape(__FILE__)}`.strip

注:__FILE__任意のexprにはファイルパスが含まれます。

6
kaorukobo

mimemagic gemもそれを行います

https://github.com/minad/mimemagic

公式文書から

MimeMagicは、拡張子またはコンテンツによってファイルのMIMEタイプを検出するライブラリです。 freedesktop.orgが提供するmimeデータベースを使用します( 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...
4
priki