diff --git a/lib/fog/aws/requests/s3/copy_object.rb b/lib/fog/aws/requests/s3/copy_object.rb index 9b9e8a513..858c815c8 100644 --- a/lib/fog/aws/requests/s3/copy_object.rb +++ b/lib/fog/aws/requests/s3/copy_object.rb @@ -9,6 +9,12 @@ module Fog # * source_object_name<~String> - Name of source object # * destination_bucket_name<~String> - Name of bucket to create copy in # * destination_object_name<~String> - Name for new copy of object + # * options<~Hash>: + # * :x_amz_metadata_directive<~String> - Specifies whether to copy metadata from source or replace with data in request. Must be in ['COPY', 'REPLACE'] + # * :x_amz_copy_source_if_match<~String> - Copies object if its etag matches this value + # * :x_amz_copy_source_if_modified_since<~Time> - Copies object it it has been modified since this time + # * :x_amz_copy_source_if_none_match<~String> - Copies object if its etag does not match this value + # * :x_amz_copy_source_if_unmodified_since<~Time> - Copies object it it has not been modified since this time # # ==== Returns # * response<~Fog::AWS::Response>: @@ -16,11 +22,27 @@ module Fog # * :etag<~String> - etag of new object # * :last_modified<~Time> - date object was last modified # - # FIXME: allow for optional params, see aws docs - def copy_object(source_bucket_name, source_object_name, destination_bucket_name, destination_object_name) + # TODO: allow specifying new metadata (support all/some of put_object?) + def copy_object(source_bucket_name, source_object_name, destination_bucket_name, destination_object_name, options = {}) + headers = { 'x-amz-copy-source' => "/#{source_bucket_name}/#{source_object_name}" } + if options[:x_amz_metadata_directive] + headers['x-amz-metadata-directive'] = options[:x_amz_metadata_directive] + end + if options[:x_amz_copy_source_if_match] + headers['x-amz-copy-source-if-match'] = options[:x_amz_copy_source_if_match] + end + if options[:x_amz_copy_source_if_modified_since] + headers['x-amz-copy-source-if-modified-since'] = options[:x_amz_copy_source_if_modified_since].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") + end + if options[:x_amz_copy_source_if_none_match] + headers['x-amz-copy-source-if-none-match'] = options[:x_amz_copy_source_if_none_match] + end + if options[:x_amz_copy_source_if_unmodified_since] + headers['x-amz-copy-source-if-unmodified-since'] = options[:x_amz_copy_source_if_unmodified_since].utc.strftime("%a, %d %b %Y %H:%M:%S +0000") + end request({ :expects => 200, - :headers => { 'x-amz-copy-source' => "/#{source_bucket_name}/#{source_object_name}" }, + :headers => headers, :host => "#{destination_bucket_name}.#{@host}", :method => 'PUT', :parser => Fog::Parsers::AWS::S3::CopyObject.new, diff --git a/lib/fog/aws/requests/s3/put_object.rb b/lib/fog/aws/requests/s3/put_object.rb index afbd35a85..758da8447 100644 --- a/lib/fog/aws/requests/s3/put_object.rb +++ b/lib/fog/aws/requests/s3/put_object.rb @@ -16,6 +16,7 @@ module Fog # * :content_md5<~String> - Base64 encoded 128-bit MD5 digest of message (defaults to Base64 encoded MD5 of object.read) # * :content_type<~String> - Standard MIME type describing contents (defaults to MIME::Types.of.first) # * :x_amz_acl<~String> - Permissions, must be in ['private', 'public-read', 'public-read-write', 'authenticated-read'] + # * :"x-amz-meta-#{name} - Headers to be returned with object, note total size of request without body must be less than 8 KB. # FIXME: deal with x-amz-meta- headers # # ==== Returns @@ -26,25 +27,30 @@ module Fog file = parse_file(object) headers = file[:headers] if options[:cache_control] - headers['Cache-Control'] = options[:cache_control] + headers['Cache-Control'] = options.delete(:cache_control) end if options[:content_disposition] - headers['Content-Disposition'] = options[:content_disposition] + headers['Content-Disposition'] = options.delete(:content_disposition) end if options[:content_encoding] - headers['Content-Encoding'] = options[:content_encoding] + headers['Content-Encoding'] = options.delete(:content_encoding) end if options[:content_length] - headers['Content-Length'] = options[:content_length] + headers['Content-Length'] = options.delete(:content_length) end if options[:content_md5] - headers['Content-MD5'] = options[:content_md5] + headers['Content-MD5'] = options.delete(:content_md5) end if options[:content_type] - headers['Content-Type'] = options[:content_type] + headers['Content-Type'] = options.delete(:content_type) end if options[:x_amz_acl] - headers['x-amz-acl'] = options[:x_amz_acl] + headers['x-amz-acl'] = options.delete(:x_amz_acl) + end + for key, value in options + if key[0..10] == 'x-amz-meta-' + headers[key] = value + end end request({ :body => file[:body],