I'm looking for a way to stream temporary files and make sure they are 
deleted after they are sent.

With Mongrel I can do something like this

  Tempfile.open('ue-basket-') do |zip|
    Zip::ZipOutputStream.open(zip.path) do |zos|
      items.each do |item|
        zos.put_next_entry(item.filename)
        zos.write(item.data)
      end
    end

    send_file zip.path, :type => 'application/zip',
     :filename => item.filename

    zip.unlink
  end

By Unix filesystem semantics, zip.unlink does not free the blocks 
(inodes) that make up the file. As long as there still is a reference to 
it, the file still exists. However, the directory entry for the file is 
deleted. The nice effect is that the file is no longer visible, but can 
still be streamed. As soon as the last file descriptor referencing it is 
closed, the file is finally deleted for good.

This doesn't work anymore, when serving files is offloaded to the web-
server. The default Rails 3 (Rack-)middleware detects that a file is 
being send (respond_to?(:to_path)), adds the file's path as a special 
header, which in turn is interpreted by the web server to serve that 
particular file. Of course this can only work if the file is still 
visible in the filesystem. Therefore the unlink trick doesn't apply.

As a last resort, I can set up a cron job that removes temporary files 
after they've reached a certain age. I'm still hoping for a more elegant 
solution. Say, a hook that is executed after the server has finished 
sending the file.

I'm using apache 2.2 and mod_xsendfile 0.9.

Michael

-- 
Michael Schuerig
mailto:[email protected]
http://www.schuerig.de/michael/

-- 
You received this message because you are subscribed to the Google Groups "Ruby 
on Rails: Talk" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/rubyonrails-talk?hl=en.

Reply via email to