Downloading Files


#1

I’m building a rails app that will create .xml documents for the users
of a particular intranet.

My question is two fold

  1. The files are in /public/files/something.xml, etc…
    How can I create a link_to in rails to access these files?

  2. How I can I force the file to be downloaded (bring up a save dialog)
    as opposed to displaying in the browser?

Thanks for hte help.


#2

downloading files wrote:

I’m building a rails app that will create .xml documents for the users
of a particular intranet.

My question is two fold

  1. The files are in /public/files/something.xml, etc…
    How can I create a link_to in rails to access these files?

Yes. The /public directory is the webroot of your app… in other words
that’s where all
publicly accessible files should go. Since /public is the root, your url
would be
http://yourhost.com/files/something.xml” or just
“/files/something.xml”.

  1. How I can I force the file to be downloaded (bring up a save dialog)
    as opposed to displaying in the browser?

Have a look at the “Content-Disposition” header… I think you set it to
“attachment” to
force the save dialog. I haven’t had occasion to use it, so I can’t tell
you much more
than that. I’m also not sure how you go about telling your webserver to
set that header
when it serves a static file. Maybe someone else around here knows.

b


#3

I tried going to:

http://localhost:3000/files/test.xml

and that gives a routing error.

as far as setting the “Content-Dispotion” I don’t know how to do that.
ANyone know?


#4

If it gives you an error, that means that there is no such file as
/public/files/test.xml


Kent

http://www.datanoise.com


#5

i tried it with a file that does exist and it works. now how can i use a

<%=link_to %> to link to /files/filename?


#6

You should use link_to helper method only to create a link to a
controller action, for anything else you better use direct html ahref.


Kent

http://www.datanoise.com


#7

On Monday 20 Feb 2006 02:41, downloading files wrote:

I tried going to:
http://localhost:3000/files/test.xml
and that gives a routing error.

You’ll need to fix that first - perhaps drop off the “.xml”, and go to
just:

http://localhost:3000/files/test

… assuming your controller is called “files” and the action is “test”.

as far as setting the “Content-Dispotion” I don’t know how to do that.
ANyone know?

I use something like this to export xml as a download from my database:

def exportxml
headers[‘Content-Type’] = “application/xml”
headers[‘Pragma’] = “no-cache”
headers[‘Cache-Control’] = “no-cache, must-revalidate”
headers[‘Expires’] = “0”
filename = Time.now.strftime(“my_xml_download_%Y%m%d_%H%M.xml”)
headers[‘Content-Disposition’] = “attachment; filename=” + filename
@thedata_to_export = Yourmodel.find(:all)
end

Assuming you want to export a bunch of xml from your model, although it
looks
like you possibly just want to download ready-existing xml files from
your
public directory, in which case you don’t really need the above… heh,
oh
well!

OK, now I’ve re-read your email (d’oh) - you have existing xml files to
download, and you’ve put them in public/files and you simply want to
force
them to download, rather than display in the browser.

Not sure how to do this with WEBrick or Lighttpd, but with Apache,
there’s
quite a cheap and dirty method you could use, if you really want to
force
download rather than display in the browser (assuming the browser
accepts and
displays XML, which most do).

Make a file called “.htaccess” (that’s “dot htaccess”) in your files
directory, and in it put the following line:

ForceType application/octet-stream

I’ve never tried this exact line myself (though have used this directive
for
other purposes), but I can’t see why it wouldn’t work. Any file placed
in
that directory will use the (generic binary, so very unspecific) mime
type
octet-stream, which always results in a download. This will get you
what you
want, but is a bit of a brutal approach.

There’s probably much nicer ways to achieve this with Rails (using the
correct
mimetype and still giving the download), but you’d have to make a
controller
that deals with the files to download, and in that you’d have to set the
content-disposition (as above) to have the files attached.

Perhaps this page will help you (at least with opening the file…
http://pleac.sourceforge.net/pleac_ruby/fileaccess.html
… and then all you’d have to do is spit it out again as your data, as
an
attachment from the controller action. Shouldn’t be too hard. :wink:

Sorry this is a bit of a ramble, I’m hoping somewhere in there is a
solution
for you, though it’s late and I have too much to do, so… back to the
grindstone for me!

Cheers,

~Dave

Dave S.
Rent-A-Monkey Website Development
http://www.rentamonkey.com/

PGP Key: http://www.rentamonkey.com/pgpkey.asc


#8

Bill W. wrote:

Best I can make out from the subject line of your message, this may
be what
you’re looking for:

http://api.rubyonrails.org/classes/ActionController/Streaming.html#M000044

If not, try to articulate your problem in a little more detail.

Best regards,
Bill

Right. So, looking at the rdoc Bill mentioned, it seems that one way to
send the xml files
and make sure they trigger the save dialog instead of being rendered in
the browser is to
have an action like this in your controller:

def download_file
file = “files\” + @params[:file]
# BE SURE TO CHECK THE PARAM FOR HANKY-PANKY!
send_file(file)
end

And a link_to in your view like this:

<%= link_to “Download xml file”, {:action => “download_file”, :file =>
“test.xml”} %>

That puts ?file=test.xml on the end of the link url and the
download_file method gets that
param and looks for a file in the files dir. Be sure to check what was
submitted because
anyone could start playing around with that param and see what they can
download. Or you
could just hardcode the filename in the controller if you don’t have a
lot different files
to download.

From a little investigating, it appears that the working directory of
rails is the
project root, not the /public dir. So, I put my “files” folder in my
project root and this
works. If you just want the files to be publicly accessible, you can
still put the files
in /public. But then you’d need to configure the server to set the
Content-Disposition
header… or change your path in your action to “public\files\”.

hope that helps,

b

PS: the “\” is cuz I’m on windows… there’s probably a “system file
separator” property
in Ruby…


#9

Best I can make out from the subject line of your message, this may be
what
you’re looking for:

http://api.rubyonrails.org/classes/ActionController/Streaming.html#M000044

If not, try to articulate your problem in a little more detail.

Best regards,
Bill

----- Original Message -----
From: “downloading files” removed_email_address@domain.invalid
To: removed_email_address@domain.invalid
Sent: Sunday, February 19, 2006 8:41 PM
Subject: [Rails] Re: Downloading Files