Get the MIME Type of a Random Upload in Rails
It’s surprisingly hard to find info on getting the MIME type of a file
in Rails. Rails has
MIME::Type (and
the confusing and undocumented MIME::Types). You can call
Mime::Type.lookup
on a filename or Mime::Type.lookup_by_extension
on an extension (without a leading .
) but a lot
of common types aren’t registered by default. You can enable
additional types in config/initializers/mime_types.rb
but that’s
really for configuring what respond_to
knows about. I want to be
able to get the MIME type of a random upload so I can handle it
properly. Having to manually define types defeats the purpose.
So, here’s the quick and dirty way. Under the hood, Rails uses
Rack::Mime
and Rack::Mime.mime_type
takes a file extension (with
the leading .
!!!) and returns the MIME type for a much wider range
of files. Grab the extension with File.extname
and put to
together like this:
mime_type = Rack::Mime.mime_type(File.extname(filename))
Then throw it in a case statement:
mime_type = Rack::Mime.mime_type(File.extname(filename))
case mime_type
when /^image/
# Something
when /^video/
# Something
when /^audio/
# Something
else
# Handle the unknown
end
Just don’t for get the else
statement to handle any unrecognized
types.
I use this in two ways:
First, to validate the an upload is of a type I want. You can use
accept=
on your HTML file input field, however you’re trusting the
browser to enforce your restrictions. Your app should do so as well.
Second, in cases where the user is allowed to upload more than one
type of thing, say an image or a video, to set the appropriate display
code (image_tag
vs video_tag
).
One last trick, straight from the [Rack::Mime docs]http://www.rubydoc.info/github/rack/rack/Rack/Mime). If you need even more types, you can pull in the system mime.types file:
require 'webrick/httputils'
mime_types = '/etc/mime.types' # '/etc/apache2/mime.types' on OS/X
list = WEBrick::HTTPUtils.load_mime_types(mime_types)
Rack::Mime::MIME*TYPES.merge!(list)
On OS/X this takes you from ~600 know types to ~1600, most of which I’ve never heard of. Now you’re truly covered.
Comments