Uploading CSS files using “Shrine” gem

I have recently switched from carrierwave to shrine in my Rails app and i thought i follow the advice of Alan Richardson, saying when you learn something new, irregardless of how trivial it might seem to you, share it and save someone else that headache.

So in the Yangah application, we upload a number of files to amazon s3 which include images, font files and css files for these fonts. However, i have found that with shrine, out of the box it was not able to correctly set the mime type for the uploaded file on s3.

I actually did try to fix this myself and eventually reach out to the Shrine google group and Janko, the author of the Shrine gem was able to provided a suggestion which worked first time and i am grateful for that.

Here is a link to the actual thread but just incase it gets deleted; this is extract of the message sent by Janko.

The `determine_mime_type` plugin uses the “file” utility by default for recognizing the MIME type, and it seems to recognize .css files as “text/plain” (and it’s the same for .js files). As noted in the `determine_mime_type` plugin documentation, one analyzer won’t be able to correctly detect correctly all types of files.

For text-based file formats (non-binary) it’s probably better to use the “mime_types” analyzer, which uses the mime-types gem to determine the MIME type from the file extension directly (rather than file content). So you could built a custom analyzer that mixes and matches “file” and “mime_types” analyzers; trying the “file” analyzer first, and if the best MIME type that it could come up with was “text/plain” (which is technically correct), then you can call the “mime_types” analyzer to determine which text-based format is it exactly.
This way you still get the benefits of the `file` utility preventing someone from uploading a binary file with a .css extension, and use the precision of determining from file extension when needed.

I installed the gem “mime_type” and update the FileUploader class with code snippet below.

plugin :determine_mime_type, analyzer: ->(io, analyzers) do

mime_type = analyzers[:file].call(io)

mime_type = analyzers[:mime_types].call(io) if mime_type == “text/plain”




And that’s it!!! i have the css file now being uploaded correctly with the mime type of “text/css”.





This entry was posted in Programming and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s