Use Fog with Ruby to generate a Pre-signed URL to PUT a file in Amazon S3

♀尐吖头ヾ 提交于 2019-12-10 04:37:06

问题


I am using the Fog gem to generate presigned urls. I can do this successfully to get read access to the file. Here's what I do:

    fog_s3 = Fog::Storage.new({
          :provider                 => 'AWS',
          :aws_access_key_id        => key,
          :aws_secret_access_key    => secret
    })
    object_path = 'foo.wav' 
    expiry = Date.new(2014,2,1).to_time.to_i
    url = fog_s3.directories.new(:key => bucket).files.new(:key => object_path).url(expiry,path_style: true)

But this doesn't work when I try to upload the file. Is there a way to specify the http verb so it would be a PUT and not a GET?

EDIT I see a method: put_object_url which might help. I don't know how access it.

Thanks

EDIT based upon your suggestion:

It helped - it got me a PUT - not GET. However, I'm still having issues. I added content type:

    headers = { "Content-Type" => "audio/wav" }
    options = { path_style: true }
    object_path = 'foo.wav' 
    expiry = Date.new(2014,2,1).to_time.to_i  
    url = fog_s3.put_object_url(bucket,object_path, expiry, headers, options)

but the url does not contain Content-Type in it. When done from Javascript in HTML I get the Content-Type in the url and that seems to work. Is this an issue with Fog? or is my header incorrect?


回答1:


I think put_object_url is indeed what you want. If you follow the url method back to where it is defined, you can see it uses a similar method underlying it called get_object_url here (https://github.com/fog/fog/blob/dc7c5e285a1a252031d3d1570cbf2289f7137ed0/lib/fog/aws/models/storage/files.rb#L83). You should be able to do something similar and can do so by calling this method from the fog_s3 object you already created above. It should end up just looking like this:

headers = {}
options = { path_style: true }
url = fog_s3.put_object_url(bucket, object_path, expires, headers, options)

Note that unlike get_object_url there is an extra headers option snuck in there (which you can use to do stuff like set Content-Type I believe).

Hope that sorts it for you, but just let me know if you have further questions. Thanks!

Addendum

Hmm, seems there may be a bug related to this after all (I'm wondering now how much this portion of the code has been exercised). I think you should be able to work around it though (but I'm not certain). I suspect you can just duplicate the value in the options as a query param also. Could you try something like this?

headers = query = { 'Content-Type' => 'audio/wav' }
options = { path_style: true, query: query }
url = fog_s3.put_object_url(bucket, object_path, expires, headers, options)

Hopefully that fills in the blanks for you (and if so we can think some more about fixing that behavior within fog if it makes sense to do so). Thanks!




回答2:


Instead of using the *put_object_url* might I suggest that you try using the bucket.files.create action which take a Fog file Hash attributes and return a Fog::Storage::AWS::File.

I prefer to break it down in a bit more steps, here is an example:

fog_s3 = Fog::Storage.new({
   :provider                 => 'AWS',
   :aws_access_key_id        => key,
   :aws_secret_access_key    => secret
})

# Define the filename
ext = :wav
filename = "foo.#{ext.to_s}"

# Path to your audio file?
path ="/"

# Define your expiry in the amount of seconds
expiry = 1.day.to_i

#Initialize the bucket to store too
fog_bucket = connection.directories.get(bucket)

file = {
   :key => "#{filename}",
   :body => IO.read("#{path}#{filename}"),
   :content_type => Mime::Type.lookup_by_extension(ext),
   :cache_control => "public, max-age=#{expiry}",
   :expires => CGI.rfc1123_date(Time.now + expiry),
   :public => true
}

# Returns a Fog::Storage::AWS::File
file = fog_bucket.files.create( file )

# Now to retrieve the public_url
url = file.public_url

Note: For subdir's checkout the :prefix option for a AWS bucket.

Fog File Documentation: Optional attributes... bottom of the page, :) http://rubydoc.info/gems/fog/Fog/Storage/AWS/File

Hopefully the example will help explain the steps in creating a fog file... Cheers! :)



来源:https://stackoverflow.com/questions/21461143/use-fog-with-ruby-to-generate-a-pre-signed-url-to-put-a-file-in-amazon-s3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!