I'm writing an importation function from a remote service to our app which uses S3. I connect to an api using OAuth as authentication, so every request I make I need to attach the token in the header. The attachments must be copied to S3 and the model is using paperclip.
I read the file from the api (say origin) with a GET method which returns a response with the body filled in with the content and the header with filename and other information.
Q: Now that I have the body of the file in plain text, how do I store it in S3 (destination) with paperclip?
Alternatively
Q: I could upload the file to S3 (destination) using remote URL(as described here), but how do I attach the token to the paperclip request to the (origin) api?
thanks
You need to create an s3.yml in your config directory... Here's a detailed tutorial in setting up paper clip with rails 3: http://doganberktas.com/2010/09/14/amazon-s3-and-paperclip-rails-3/
I would suggest you use a conversion tool to generate either a PDF or an editable document, then upload that to s3... Here's a good PDF gem: http://ruby-pdf.rubyforge.org/pdf-writer/ and even a railscast to help: http://railscasts.com/episodes/78-generating-pdf-documents
and here's an rtf gem: https://rubygems.org/gems/rtf
Since you have the raw data that should work.
Related
How can I upload a file from an external service or app (iOS App, Go App, etc) to a Rails REST API which uses Active Storage local file storage?
All the tutorials I can find use HTML forms. I'd like to upload my files via a POST request to the Rails API. The main thing I am uncertain about is what headers and what kind of format I need to send the files in to the backend.
The solution was to just send normal form-data. I used Postman for testing which works great for file uploads as well http://getpostman.com
Base64 is useful for you, You can decode base64 then generate temp file and upload that file.
I want to upload large files on S3. I know there is an option multipart upload by which I can upload large file in parts. I read the documentation (http://docs.aws.amazon.com/mobile/sdkforios/developerguide/s3transfermanager.html) but didn't find any code for the multipart upload. I have successfully uploaded a file on server as a single file but I want to use multipart for large file.
Thanks.
IF you're still looking for a solution, you can check out my blog post on this subject: Taming the AWS framework to upload a large file to S3. For large files you will have to skip using the AWSTransferManager as it uses cognito credentials which are limited to an hour validity.
For my Rails application, I download a bunch of files from a remote URL to my application. I would like to directly upload them to Amazon S3, without needing a form to do the upload, since I will temporarily cache the file I downloaded on the EC2 instance.
I would also like to retain the links to the files I uploaded so I can download them later.
I am essentially reposting the files I downloaded.
I looked around, but most of the solution seem to involve form uploading to S3 with a user.
Is there s direct upload solution?
You can upload directly to S3 using the AWS SDK for Ruby. The easiest way is:
require 'aws-sdk'
s3 = Aws::S3::Resource.new(region:'us-west-2')
obj = s3.bucket('bucket-name').object('key')
obj.upload_file('/path/to/source/file')
Or you can find a couple other options here.
You can simply use EvaporateJS to achieve this. You can also take advantage of sending ajax request to update file name to the database after each file upload. Though javascript exposes few details your bucket is not vulnerable to hack as S3 service provide a bucket policy.
Just set the <AllowedOrigin>*</AllowedOrigin> to <AllowedOrigin>specificwebsite.com</AllowedOrigin> in production mode.
My website generates a file in javascript (audio recording) and I then want it to be uploaded to Amazon S3.
I first managed to get the uploading part working by sending the generated file to my server, where it is uploaded. However I would like now to upload the file directly to S3, without going through my server.
So I started to use the s3_direct_upload gem, which works great when using a file_field. However my file is generated by the javascript and :
- The value of a file field has to be set by the user for security reasons
- I do not want the user to have to interact with the upload
I tried to play with the S3Uploader class and to directly add data, without any success for now, it seems that I do not use the correct method.
Does anyone has any idea on how to achieve S3 direct upload without a file field ?
Thanks
Never mind, I found out that the S3Uploader class used by the s3_direct_upload gem has the same methods as the jQuery-File-Upload from which it is derived.
So one can call $("#s3_uploader").fileupload('send', {files: [f]});
And the f File will be uploaded to S3 directly
I'm writing a Rails application that serves files stored on a remote server to the end user.
In my case the files are stored on S3 but the user requests the file via the Rails-application (hiding the actual URL). If the file was on my servers local file-system, I could use the Apache header X-Sendfile to free up the Ruby process for other requests while Apache took over the task of sending the file to the client. But in my case - where the file is not on the local file-system, but on S3 - it seems that I'm forced to download it temporarily inside Rails before sending it to the client.
Isn't there a way for Apache to serve a "remote" file to the client that is not actually on the server it self. I don't mind if Apache has to download the file for this to work, as long as I don't have to tie up the Ruby process while it's going on.
Any suggestions?
Thomas, I have similar requirements/issues and I think I can answer your problem. First (and I'm not 100% sure you care for this part), hiding the S3 url is quite easy as Amazon allows you to point CNAMES to your bucket and use a custom URL instead of the amazon URL. To do that, you need to point your DNS to the correct amazon URL. When I set mine up it was similar to this: files.domain.com points to files.domain.com.s3.amazonaws.com. Then you need to create the bucket with the name of your custom URL (files.domain.com in this example). How to call that URL will be different depending on which gem you use, but a word of warning was that the attachment_fu plugin I was using was incorrectly sending me to files.domain.com/files.domain.com/name_of_file.... I couldn't find the setting to fix it, so a simple .sub method for the S3 portion of the plugin fixed it.
On to your other questions, to execute some rails code (like recording the hit in the db) before downloading you can simply do this:
def download
file = File.find(...
# code to record 'hit' to database
redirect_to 3Object.url_for(file.filename,
bucket,
:expires_in => 3.hours)
end
That code will still cause the file to be served by S3, but and still give you the ability to run some ruby. (Of course the above code won't work as is, you will need to point it to the correct file and bucket and my amazon keys are saved in a config file. The above is also using the syntax for the AWS::S3 gem - http://amazon.rubyforge.org/).
Second, the Content-Disposition: attachment issue is a bit more tricky. Hopefully, your situation is a bit more simple than mine and the following solution can work. Assuming the object 'file' (in this example) is the correct S3 object, you can set the disposition to attachment by
file.content_disposition = "attachment"
file.save
The above code can be executed after the file exists on the S3 server (unlike some other headers and permissions), which is nice and it can also be added when you upload the file (syntax depends on your plugin). I'm still trying to find a way to tell S3 to send it as an attachment and only when requested (not every time), and if you find that, please let me know your solution. I need to be able to sometimes download it and other times save embed images (for example) into HTML. I'm not using the above mentioned redirect but fortunately it seems that if you embed (such as a HTML image tag) a file with the content-disposition/attachment header, and the browser still displays the image normally (but I haven't throughly tested that across enough browsers to send it in the wild).
Hope that helps! Good luck.