Rails 3: Sending tempfiles for download

Updated . Posted . Visible to the public.

When you create a temporary file (e.g. to store a generated Excel sheet) and try to send it to the browser from a controller, it won't work by default. Take this controller action:

class FoosController < ApplicationController
  def download
    file = Tempfile.new('foo')
    file.puts 'foo'
    file.close
    send_file file.path
  end
end

Accessing this controller action will usually raise a 404 not found in the browser and the Apache log will say:

The given path was above the root path: xsendfile: unable to find file: /tmp/foo20110721-28050-1h104da-0

The reason for this is that Rails 3 uses X-Sendfile for file downloads and Apache is only allowed to transfer files from a whitelist of paths that should not include /tmp.

One solution for this is to save the tempfile in your project directory's tmp instead:

file = Tempfile.new('foo', 'tmp')

Note that depending on your setup, you might need to change that file's permissions so Apache can read it.

Henning Koch
Last edit
License
Source code in this card is licensed under the MIT License.
Posted by Henning Koch to makandra dev (2011-07-21 09:40)