views:

30

answers:

2

I have some very large mp3's stored at a remote location and I presently link to them like so:

= link_to "mp3", "http://website-where-file-is-stored.com/file-123456.mp3"

When a user clicks the link, the file starts to play in the browser. I would like the file to download to the users hard-drive after they click the link.

I've read a number of articles like this one and this one which promote methods that work in different situations to my own.

I have multiple files. Each file is stored on a remote server which does not have a rails app running.

I don't require users to be authorized prior to downloading anything so I don't want my rails app to be called into action in any way as I need to be conservative with my rails processes.

Is this something I need to do in config.ru? Is there a guide or tutorial detailing the best way to do this?

I know that I need to set the Content-Disposition header but as I said, I can't figure out how to do that I do not have a rails app running on the remote server, it's just a bunch of server space.

+1  A: 

You can make a controller action somewhere that is dedicated to file downloads.

So, the link_to goes to that action, which somehow knows which file the user wants (either by dropping the entire url into a query variable or some other method appropriate to your application).

That action does a redirect_to http://website-where-file-is-stored.com/file-123456.mp3

When most modern browsers encounter such a situation, they won't render a blank page and start a download -- they will start the download, but then keep the user on the original page with the link_to. Perfect!

To have the file download as an attachment and not render in the browser (if it's a movie or pdf for example), website-where-file-is-stored.com has to serve the file with the header Content-disposition: attachment. See more info here: http://www.boutell.com/newfaq/creating/forcedownload.html

John
Hi thanks a lot for the suggestion. I tried it but because I have the quicktime plugin installed the file just starts playing. I'm currently looking into ways to get rack to take care of this for me so that my rails controllers are free to do more work, but thanks a lot for the suggestion, it was worth a shot.
stephenmurdoch
you have to set the Content-disposition header to fix that -- I edited my answer above.
John
thanks - i figured that I needed to fix the content-disposition header but was having problems setting it on the remote server. it can't be done from the calling application, it needs to be done on the server. Anyway, I've fixed the problem by creating a perl script in the cgi bin on the remote server which sets the Content-Disposition header. thanks anyway
stephenmurdoch
A: 

OK, I fixed this by adding the following cgi script to the cgi-bin on my remote server. the script sets the Content-Disposition header. In my case, the script is named "download.cgi".

#!/usr/local/bin/perl -wT

use CGI ':standard';
use CGI::Carp qw(fatalsToBrowser);

my $files_location;
my $ID;
my @fileholder;

$files_location = "../";

$ID = param('ID');

open(DLFILE, "<$files_location/$ID") || Error('open', 'file');
@fileholder = <DLFILE>;
close (DLFILE) || Error ('close', 'file');

print "Content-Type:application/x-download\n";
print "Content-Disposition:attachment;filename=$ID\n\n";
print @fileholder

And instead of doing link_to 'Download', "http://path/to/filename.mp3" I do this:

link_to 'Download' "http://path/to/cgi-bin/download.cgi?ID=filename.mp3"

If you want to use the same script, just bear in mind that the line: $files_location = "../" is a relative path.

stephenmurdoch