I was having a issue where after uploading a file to S3, it wouldn’t allow any user to view the file with a browser, but only download the file. The issue turned out to be that S3 defaults to binary/octet-stream as the content-type. I realized, I needed to set the content-type / mime-type when uploading files to preserve their mime-type and how they are treated in the browser for the user.

I am using the Fog.io library to upload files and manage EC2 servers. It turns out that the ruby std lib File object doesn’t have any methods to help with mime type. While there are many gems to help with the task I didn’t really want to add another gem dependency or me around with what seem to be a large list of not recently maintained gems. After some quick google-fu, I found a solution that would work well enough on any unix like system. I just shelled out and called file -Ib and parsed it to get a mime type.

   directory = connection.directories.create(
                                              :key    => "a-bucket-name",
                                              :public => true
   filename = './somefile.txt'
   content = File.read(filename)
   mimetype = `file -Ib #{filename}`.gsub(/\n/,"")
   file_options = {
      :key    => filename,
      :body   => content,
      :content_type => mime_type,
      :public => true
    file = directory.files.new(file_options)

After preserving and uploading correct mime types, the files worked as expected. If a user clicks a txt file they see the contents in browser, same with images, etc. Anyways, that solved the issue for me. I am kind of surprised S3 doesn’t have some sort of auto-detect mime type option.

blog comments powered by Disqus
Dan Mayer Profile Pic

I primary write about Ruby development, distributed teams, & dev/PM process. The archives go back to my first CS classes during college when I was learning to write software. I contribute to a few OSS projects and often work on my own projects. You can find my code on github.

Twitter @danmayer

Github @danmayer