Read more

Rails 3: Sending tempfiles for download

Henning Koch
July 21, 2011Software engineer at makandra GmbH

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
Illustration web development

Do you need DevOps-experts?

Your development team has a full backlog? No time for infrastructure architecture? Our DevOps team is ready to support you!

  • We build reliable cloud solutions with Infrastructure as code
  • We are experts in security, Linux and databases
  • We support your dev team to perform
Read more Show archive.org snapshot

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.

Posted by Henning Koch to makandra dev (2011-07-21 11:40)