2

I wanted to copy a file from one folder to another in the same bucket using aws-sdk gem (version 3). I was able to copy the file successfully.

The code as follows Controller:

    saved_file = path for the source file   
    source_bucket_name = 'bucket-name'
    target_bucket_name = 'same as source bucket'
    source_key = "#{saved_file.path.path}"
     target_key = "path of the target"       
     s3 = Aws::S3::Client.new(credentials)
     byebug
  obj = s3.copy_object({bucket: target_bucket_name, copy_source: source_bucket_name + '/' + source_key, key: target_key})

ps: Don't bother about the source_key and path, since i've used carrierwave for that. How can i get the path/url of the copied object. I need the url because if i delete file in source bucket after copying, the destination has to have the copy independently. and that file can be accessed through the url. This is the output of obj in command line

, expiration=nil, copy_source_version_id=nil, version_id=nil, server_side_encryption="AES256", sse_customer_algorithm=nil, sse_customer_key_md5=nil, ssekms_key_id=nil, request_charged=nil>

Any help would be great and TIA.

UPDATE:

aws_client = Aws::S3::Client.new('aws credentials')                              
 s3 = Aws::S3::Client.new('aws credentials')                 
 s3.copy_object({bucket: target_bucket_name, copy_source: source_bucket_name + '/' 
 + source_key, key: target_key}, options = {acl: :public_read})                   
 s3 = Aws::S3::Resource.new(client: aws_client)                               
 bucket = s3.bucket('bucket-name')                                        
 obj = bucket.object("#{target_key}")                                            
 url = obj.presigned_url(:get)

used that url to view/access the copied object. This worked for me.

raven
  • 33
  • 1
  • 8

1 Answers1

0

The object URL is just the bucket URL + the filename, so you already have the information you need. You can also generate a public URL or a pre-signed URL if you need.

Also keep in mind that copying an object doesn't copy the access control policy. So you may not have access because you haven't defined permissions for the new object. https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#copy_from-instance_method

bwest
  • 9,182
  • 3
  • 28
  • 58
  • Thank for your response. I have tried to get the url as you mentioned like bucket url+ file name. i got more like https://bucketname.s3.amazonaws.com/folder1/folder2/folder3/3/e-prescribing.png Even though the path is correct i could not open that file. – raven Jan 15 '19 at 16:53
  • You might want to read up on naming conventions to make sure your object names are valid https://stackoverflow.com/a/30575074/401096 – bwest Jan 15 '19 at 17:04
  • Also keep in mind that copying an object doesn't copy the access control policy. So you may not have access because you haven't defined permissions for the new object. https://docs.aws.amazon.com/AWSRubySDK/latest/AWS/S3/S3Object.html#copy_from-instance_method – bwest Jan 15 '19 at 17:05
  • Sure Than You! I will see and let you know if it works. – raven Jan 15 '19 at 17:09
  • No problem. I think if you specify the access control policy on your `copy_object` command it will fix the issue. – bwest Jan 15 '19 at 17:10
  • does this syntax is correct for acl options? obj = s3.copy_object({bucket: target_bucket_name, copy_source: source_bucket_name + '/' + source_key, key: target_key}, options = {acl: :public_read}) – raven Jan 15 '19 at 18:05
  • Yes that looks right to me. Or use `s3.public_url(obj)` – bwest Jan 15 '19 at 18:43
  • Can you provide more information? Is the copy operation succeeding? Does the new object show up in the bucket? Do you get an error when you get a public url? – bwest Jan 15 '19 at 21:01
  • Yes i can see the files in the bucket, it does have an object url as well. I get error when i use public_url , undefined method public_url. – raven Jan 15 '19 at 21:04
  • You are using the AWS SDK for Ruby right? Which gem and version do you have installed? – bwest Jan 15 '19 at 21:56
  • AWS SDK version3. Today i have tried something like aws_client = Aws::S3::Client.new( region: 'code of region', #or any other region access_key_id: 'key1', secret_access_key: 'key2' ) s3 = Aws::S3::Resource.new(client: aws_client) bucket = s3.bucket('bucket-name') obj = bucket.object("key value of the object") url = obj.presigned_url(:put) I thought the error will be resolved if i authentication method for the S3 URLs. But it did not work well. there is a signature mismatch – raven Jan 16 '19 at 14:19
  • Thank you so much for your time @bwest, The above way of authenticating S3 URL worked for me or working for now :) – raven Jan 16 '19 at 15:51
  • Glad to hear it! If you don't mind accepting the answer and upvoting it I'd appreciate it :) – bwest Jan 16 '19 at 16:13