Mike K.
Mike K.

Reputation: 3789

read data from a url and stream it back to client with ruby on rails

I'm still new to Ruby and Rails so please excuse my question if the answer is obvious. I have an application running with a controller called bucket which when passed an id connects to a non-routable subnet (10.0.0.xx) and returns data assuming some conditions are met. I'm currently using the send_data method in the bucket controller but since this expects a local file I'm reading the contents of the url into a string and then returning that.

This is good enough for very small files but for large binaries it's too slow. What I really want to be able to do is stream the data back using /bucket as a proxy.

Here is the code from the controller I'm currently using:

fileName = "somename.dat"        
content = open(link) {|f| f.read() }
send_data content, :disposition=>'attachment', :filename=>fileName

I was hoping someone may have some advice on how to improve this. Ideally, I could read the data in chunks and return it as I received it.

Upvotes: 0

Views: 2001

Answers (1)

Alec Wenzowski
Alec Wenzowski

Reputation: 3908

Check out rack-proxy, which will read from the private server and pass on the data for you.

Install by adding gem 'rack-proxy' to your Bundle

To configure, subclass.

Example:

class FooBar < Rack::Proxy

  def rewrite_env(env)
    env["HTTP_HOST"] = "example.com"

    env
  end

  def rewrite_response(triplet)
    status, headers, body = triplet

    headers["X-Foo"] = "Bar"

    triplet
  end

end

For more examples, read the tests.

As a rack app, rack-proxy can be mounted in your rails 3 app as simply as:

mount FooBar, :at => "/foo_bar"

If you want to find out more about the role rack plays in the Rails ecosystem, here are the docs.

If you don't like this proxy, or you want some more ideas, check out a different implementation.

Upvotes: 1

Related Questions