Proxy a file from S3 with Heroku and Rails
Asked Answered
P

1

10

I need to send a file stored in S3 through my rails application hosted on heroku. I cannot use a redirect to the URL of the file on S3 as I want to send a sitemap which should be served from the same domain as the links inside.

Ideally, I would use some sort of proxy method to send the file by the rails app, at least, I can download the file in the tmp directory of heroku and send it after.

I would also send the right content-type for the file.

Do you know how can I achieve it ? What will be the best way ?

There is a rack app which is doing that but I'm not sure how to reproduce it in Rails, see the code here

Thanks for your help

Petrina answered 11/1, 2012 at 0:7 Comment(4)
What do you mean by "send a file"? Who are you sending it to? Are you letting a user download it or are you acting as a proxy for another service to download it through your Heroku app?Amygdalate
I want to act as a proxy for another service (S3) to download it through my Heroku app.Petrina
Heroku has a 30 second request timeout so I'm not sure you can reliably use a Heroku server as a proxy.Amygdalate
I'm aware of the 30 seconds timeout on heroku but I'm talking about small files that will take a lot less than 30seconds to transferPetrina
T
3

It looks like this:

blob =  AWS::S3::S3Object.value( filename, bucketname )
send_data( blob,
           { :type => 'image/jpg,
             :disposition => 'inline' } )

the type can be image/jpg, image/gif, etc

Tref answered 11/1, 2012 at 20:25 Comment(4)
This is a possibility but I would prefer to find some sort of streaming if possible. Also, even if the file is stored on S3, it is on a public URL so I do not need to use the S3 library to get the file, not sure if there is reason to choose to get the file from the S3 lib or directly by the URL ?Petrina
well, if you don't want to redirect to the s3 url, the rails app will have to serve the image directly. You may be able to stream it by using the render :text => proc {} construct but if you get a cache involved (varnish or memcache) just pulling it from s3 and sending it along is a reasonable solution.Tref
I'm not sure how to use render :text => proc {} to stream the file. Also I would like to set the content/type dynamically from the file on S3. Do you have some idea with that ? Thanks for your help.Petrina
any content produced in the proc {} will be streamed to the client. See apidock.com/rails/ActionController/Base/render. As for dynamically determining the content type -- either store the content type in a model on the app server, in the filename or path of the s3 object, or in the metadata for the s3 object.Tref

© 2022 - 2024 — McMap. All rights reserved.