Send_file and locking files after download?


#1

Hello,

I’m working on a download service which grants users a one-time-download
access to files. The idea is to write an entry to a database table after
a successful download that “locks” the download link for the user.

After doing some quick tests with send_file I noticed that send_file
does not block until the user has downloaded the full file, but proceeds
with the rest of the controller code. For example:

send_file fullpath, :stream => false, :disposition => ‘attachment’,
:filename => filename
logger.info “*********** LOCK DOWNLOAD!! **************”

After send_file starts the file transfer, I can immediately see the
“LOCK DOWNLOAD” entry in the log files. This would mean that if the user
interrupts a big file download, it would still be locked.

What would be the solution? Do I have to somehow (…how?) write my own
buffering file sending which blocks the control and breaks out of the
controller if the user interrupts the transfer?

I would imagine :stream => true could be a step closer to my needs, but
it doesn’t seem to work since all I get is “Rails application failed to
start properly”.

Any ideas?


#2

On Mon, 2006-05-15 at 01:08 +0200, Markku Mäkelä wrote:

Hello,

I’m working on a download service which grants users a one-time-download
access to files. The idea is to write an entry to a database table after
a successful download that “locks” the download link for the user.

You should google “X-Sendfile”. It might help.


Zed A. Shaw


http://mongrel.rubyforge.org/


#3

Zed S. wrote:

You should google “X-Sendfile”. It might help.

Hmm I don’t see how? My problem is that I want to execute code in the
controller after a successful download, but not if the download was
interrupted.

mod_xsendfile just seems to replace Rails’ send_file, but doesn’t allow
the control to return to the controller after download.

Nice looking little module anyway, might prove useful in some other
project, so thanks anyway.

-markku


#4

To be more exact, what I’m looking for is

  • first looping through a file send: block until user has downloaded the
    last byte of the file, or interrupts the transfer

  • then check if the connection was aborted, like PHP’s if(
    connection_status() == 0 ) { lock_the_file(); }

The problem is that send_file seems to be non-blocking.