Send_file and remote files

Hello,

My first post here. I’m quite new to Ruby.

I’m making a Flash application that loads external files
from other servers onto the user’s hard disk.
That’s why I need a way to connect to the remote locations
over absolute http links; so I can monitor the progress inside
my Flash app. So this code should act as a file serving proxy.
Flash has some security restrictions, that will not allow the
loading of external files from other domains.

What I’ve got is this (not working, throws an error).
I used this file as an example:

“Cannot read file http://www.twin-diamonds.com/pic/rubies.jpg

class StreamDataController < ApplicationController
def index
send_file(params[:file],:filename => params[:name],
:stream => ‘true’, :buffer_size => ‘4096’)
end
end

No one ?

Mister T. wrote:

What I’ve got is this (not working, throws an error).
I used this file as an example:

“Cannot read file http://www.twin-diamonds.com/pic/rubies.jpg

class StreamDataController < ApplicationController
def index
send_file(params[:file],:filename => params[:name],
:stream => ‘true’, :buffer_size => ‘4096’)
end
end

send_file is meant to work with local files. So ruby tries to open that
string as a local filename. You might try send_data with a string of
data instead.

#environment.rb
require ‘open-uri’

#controller
def index
data = open(params[:file])
send_data data, :filename => params[:name], …
end

Alex W. wrote:

#environment.rb
require ‘open-uri’

#controller
def index
data = open(params[:file])
send_data data, :filename => params[:name], …
end

Oops, I think that should be:

#controller
def index
data = open(params[:file]).read
send_data data, :filename => params[:name], …
end

Mister T. wrote:

That way I cannot set the buffer.
That’s kind of anoying, because now it takes
a while to load the files ( > 10mb ) into
the memory of the server machine.

I’ve got code working like that, but I really
want to make use of the buffer.

Then you may want to write the file to a temp directory and then send it
with send_file

data = open(params[:file])
filename = “#{RAILS_ROOT}/tmp/my_temp_file”

File.open(filename, ‘r+’) do |f|
f.write data.read
end

send_file filename, …options…

That way I cannot set the buffer.
That’s kind of anoying, because now it takes
a while to load the files ( > 10mb ) into
the memory of the server machine.

I’ve got code working like that, but I really
want to make use of the buffer.

I think that leaves me with the same issue, no ?

I will have to download the file first to my own server.
And then serve them to my clients.
The same thing happens with send_data, but only to the
server’s memory, in stead of writing the data to the hard disk.

The good thing is that I can cache the files this way.

I tried your code but it gives:

No such file or directory - “http://www…”

Mister T. wrote:

I think that leaves me with the same issue, no ?

I will have to download the file first to my own server.
And then serve them to my clients.
The same thing happens with send_data, but only to the
server’s memory, in stead of writing the data to the hard disk.

The good thing is that I can cache the files this way.

I don’t think you will be able to do this from a rails app. I just
don’t see a way that you can download the file the file in chunks and
sending those chunks back out before the file has downloaded completely.

Maybe some other background process on your server could handle a
request like this, but I don’t think it will work from within Rails.

Although, it’s disturbing that I think that is the first time I have
ever said that.

Mister T. wrote:

I’ve added those lines too now. sorry about that.

I have another error now.

No such file or directory - /var/www/vhosts/…/railsapp/tmp/download

Well that path isn’t vary well formed. That ‘…’ should probably be
‘…/…’, so adjust the way you are constructing that path accordingly.

When I send it to tmp/downloads ( I created that folder ),
then it says:

Is a directory - /var/www/vhosts/…/railsapp/tmp/downloads

You must supply the full filename of the file to write with File.open.
If you want to use the same filename as the one being downloaded, try
something like this, which will get everything to the right of the last
‘/’ in the url.

url = ‘http://foo.com/index.html
filename = url.split(‘/’).last
full_path = “#{RAILS_ROOT}/tmp/#{filename}”

File.open(full_path, ‘r+’) {|f| … }

Mister T. wrote:

I tried your code but it gives:

No such file or directory - “http://www…”

did you remember this from my previous post?

#environment.rb
require ‘open-uri’

open-uri lets the “open” method work with urls.

I’ve added those lines too now. sorry about that.

I have another error now.

No such file or directory - /var/www/vhosts/…/railsapp/tmp/download

When I send it to tmp/downloads ( I created that folder ),
then it says:

Is a directory - /var/www/vhosts/…/railsapp/tmp/downloads

The error still occurs.

No such file or directory -
/var/www/vhosts/…obfuscatedPath…/railsapp/tmp/downloads/rubies.jpg

The … is for obfuscating my paths.
The path is correct.

I’ll try it now.

Tnx Alex ; )

Mister T. wrote:

The error still occurs.

No such file or directory -
/var/www/vhosts/…obfuscatedPath…/railsapp/tmp/downloads/rubies.jpg

Are you sure that this path resolves to an existing directory?

/var/www/vhosts/…obfuscatedPath…/railsapp/tmp/downloads/

The File.open method will not create directories, only files. So all
directories must be in place.

If it still doesn’t work, I dont know what else to tell you besides to
read up on file reading and writing in ruby.

Alex, is this a typo ?

File.open(filename, ‘r+’) do |f|
f.write data.read
end

shouldn’t this be:

File.open(filename, ‘w’) do |f|
f.write data.read
end

When I try this it gives me “can’t convert String into Integer”

I just started a brand new SSH session.
I typed in the path and it fully resolves ( excluding rubies.jpg off
course ).

I even chowned the tmp/downloads dir to 777

I changed the “r+” attribute to “w”
and also discovered that buffer_size=>‘4096’ had to be buffer_size=>4096
without the quotes.

Thanks Alex !