检测Ruby中上传文件的MIME类型

时间:2011-01-05 03:52:10

标签: ruby-on-rails ruby file-upload swfupload

是否有一种防弹方法可以在Ruby或Ruby on Rails中检测上传文件的MIME类型?我正在使用SWFupload上传JPEG和PNG,而content_type始终是"application/octet-stream"

8 个答案:

答案 0 :(得分:45)

ruby-filemagic gem将会这样做:

require 'filemagic'

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

这个gem根本不会查看文件扩展名。它读取一些文件内容并使用它来猜测文件的类型。

答案 1 :(得分:38)

在Ruby on Rails中,你可以这样做:

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

答案 2 :(得分:21)

您可以根据文件的魔术标头使用这种可靠的方法:

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

答案 3 :(得分:11)

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" 

答案 4 :(得分:6)

filemagic gem是很好的解决方案,但取决于许多不必要的宝石。 (rails,aws-sdk-core,...)

如果您的应用很小且仅在Linux或OSX中运行,请考虑使用file程序:

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

注意:将__FILE__替换为任何包含文件路径的expr。

答案 5 :(得分:4)

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...

答案 6 :(得分:0)

如果您是从头开始执行此操作,请安装 mimemagic gem

gem 'mimemagic'

打开流(目标图像的字节数)

url="https://i.ebayimg.com/images/g/rbIAAOSwojpgyQz1/s-l500.jpg"
result = URI.parse(url).open

然后检查数据流的文件类型,例如:

MimeMagic.by_magic(result).type == "image/jpeg"

尽管如上所述

%w(JPEG GIF TIFF PNG).include?(MimeMagic.by_magic(result).type)

这可能更优雅

答案 7 :(得分:-5)

您可以使用

默:: Type.lookup_by_extension(extention_name)

由于