Detect MIME type of uploaded file in Ruby

后端 未结 7 995
刺人心
刺人心 2020-12-02 09:45

Is there a bullet proof way to detect MIME type of uploaded file in Ruby or Ruby on Rails? I\'m uploading JPEGs and PNGs using SWFupload and content_type is alw

相关标签:
7条回答
  • 2020-12-02 10:22

    The ruby-filemagic gem will do it:

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

    This gem does not look at the file extension at all. It reads a bit of the file contents and uses that to guess the file's type.

    0 讨论(0)
  • 2020-12-02 10:22

    You can use this reliable method base on the magic header of the file :

    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
    
    0 讨论(0)
  • 2020-12-02 10:22

    The ruby-filemagic gem is good solution, but requires additional dependencies on libmagic (recently removed from CarrierWave as part of CarrierWave::MagicMimeTypes removal).

    If you're interested in a pure ruby implementation, consider the MimeMagic gem! It works well for file types listed in the freedesktop.org mime database:

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

    For Microsoft Office 2007+ formats (xlsx, docx, and pptx), require the overlay (unless you're okay with the generic "application/zip" MIME type for these files)

    require 'mimemagic'    
    require 'mimemagic/overlay'
    
    MimeMagic.by_magic(File.open('big_spreadsheet.xlsx')).type # => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" 
    
    0 讨论(0)
  • 2020-12-02 10:29

    filemagic gem is good solution but depends lots of unnecessary gems. (rails, aws-sdk-core, ...)

    If your app is small and only runs in Linux or OSX, consider to use file program:

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

    Note: Replace __FILE__ with any expr contains the filepath.

    0 讨论(0)
  • 2020-12-02 10:32

    In Ruby on Rails you can do:

    MIME::Types.type_for("filename.gif").first.content_type # => "image/gif"
    
    0 讨论(0)
  • 2020-12-02 10:32

    mimemagic gem will also do it

    https://github.com/minad/mimemagic

    from the oficial documentation

    MimeMagic is a library to detect the mime type of a file by extension or by content. It uses the mime database provided by freedesktop.org (see 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...
    
    0 讨论(0)
提交回复
热议问题