2

We're upgrading to Fedora 18. We've deployed our Rails app, and it works as expected, except for downloading zip files of reports. It works on our existing production server (Fedora 15).

We're using XSendFile to send the zip files. It doesn't work when the files are located in /tmp, but it works in other circumstances.

Details

The zip files are generated using Tempfile.open in Ruby, which creates a file in /tmp by default. However, Apache gives us a 404 and an error like this in error_log:

[Thu May 02 11:33:18.010388 2013] [:error] [pid ...] (2)No such file or directory: [client ...] xsendfile: cannot open file: /tmp/..., referer: https://...

The first thing we checked is our configuration. This is what we have:

XSendFile on
XSendFilePath /tmp

That seems to be correct given the docs -- /tmp is even used in the example.

We started trying to narrow down the problem. We started forcing the Rails app to serve other files by hardcoding the path. Each time, we'd change the directory for XSendFilePath in the Apache config and the file path used in the Rails app.

Results:

fails: /tmp/hello.zip
works: /var/www/html/rails_production/current/public/hello.zip
works: /home/capistrano/hello2.zip
fails: /tmp/test-xsendfile/hello3.zip
works: /tmp2/hello4.zip

In the failing cases, the permissions were set to 777 apache:apache, which would seem liberal enough. The working cases didn't require those permissions, though.

Because we are suspecting the /tmp path to be the issue, we made /tmp2 with the same permissions and ownership (drwxrwxrwt. and root:root). The SELinux context for /tmp2 was changed to be identical using chcon.

Even with those changes, XSendFile works with /tmp2. That makes the problem seem to be an Apache config issue. We can work around this, but we'd prefer not to.

What are we missing that lets /tmp2 work, but not /tmp?

Versions

  • Apache 2.4.4
  • mod_xsendfile 0.12 (RPM from Fedora 18, not something we compiled)

NOTE: We're using mod_security, but it isn't in enforcing mode.

  • I don't know XSendFile but maybe 777 is too liberal? Was it 777 in /tmp2, too? You may attach to apache with strace (strace -p $PID -f -e trace=file) to get a better understanding of what happens at the system level. – Hauke Laging May 2 '13 at 16:41
  • In don't know why only /tmp/ doesn't work, but you shouldn't use Tempfile with XSendFile. Tempfile unlinks the file as soon as it's garbage collected, so XSendFile may not have the chance to grab the file before it's removed. You should use regular File to create the temporary file. – Lie Ryan May 2 '13 at 17:00
  • @Lie That's definitely a possible race condition. I think Tempfile may have been used for convenience. Ideally, we could use X-SendFile-Temporary, but that feature hasn't been released yet. tn123.org/mod_xsendfile/beta – Benjamin Oakes May 2 '13 at 20:07
  • Yes, X-SendFile-Temporary would be great when it's released, but for the moment you should just run a cron job to delete old temporaries. Also, I presume that opening regular File also still give you the same issue on /tmp/? – Lie Ryan May 3 '13 at 1:52
  • Yes, it would be the same issue with /tmp. Thanks for your input, I think this is about the route we'll be taking... – Benjamin Oakes May 3 '13 at 15:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.