1
0
Fork 0
mirror of https://github.com/fog/fog-aws.git synced 2022-11-09 13:50:52 -05:00

Merge pull request #50 from lautis/customer-encryption-headers

Support customer encryption headers in multipart uploads
This commit is contained in:
Josh Lane 2015-02-10 08:45:56 -08:00
commit d1fa078da5
2 changed files with 57 additions and 3 deletions

View file

@ -23,6 +23,7 @@ module Fog
attribute :owner, :aliases => 'Owner'
attribute :storage_class, :aliases => ['x-amz-storage-class', 'StorageClass']
attribute :encryption, :aliases => 'x-amz-server-side-encryption'
attribute :encryption_key, :aliases => 'x-amz-server-side-encryption-customer-key'
attribute :version, :aliases => 'x-amz-version-id'
# @note Chunk size to use for multipart uploads.
@ -199,7 +200,7 @@ module Fog
options['Expires'] = expires if expires
options.merge!(metadata)
options['x-amz-storage-class'] = storage_class if storage_class
options['x-amz-server-side-encryption'] = encryption if encryption
options.merge!(encryption_headers)
if multipart_chunk_size && body.respond_to?(:read)
data = multipart_save(options)
@ -261,8 +262,7 @@ module Fog
body.rewind rescue nil
end
while (chunk = body.read(multipart_chunk_size)) do
md5 = Base64.encode64(Digest::MD5.digest(chunk)).strip
part_upload = service.upload_part(directory.key, key, upload_id, part_tags.size + 1, chunk, 'Content-MD5' => md5 )
part_upload = service.upload_part(directory.key, key, upload_id, part_tags.size + 1, chunk, part_headers(chunk, options))
part_tags << part_upload.headers["ETag"]
end
@ -274,6 +274,31 @@ module Fog
# Complete the upload
service.complete_multipart_upload(directory.key, key, upload_id, part_tags)
end
def encryption_headers
if encryption && encryption_key
encryption_customer_key_headers
elsif encryption
{ 'x-amz-server-side-encryption' => encryption }
else
{}
end
end
def part_headers(chunk, options)
md5 = Base64.encode64(Digest::MD5.digest(chunk)).strip
encryption_keys = encryption_customer_key_headers.keys
encryption_headers = options.select { |key| encryption_keys.include?(key) }
{ 'Content-MD5' => md5 }.merge(encryption_headers)
end
def encryption_customer_key_headers
{
'x-amz-server-side-encryption-customer-algorithm' => encryption,
'x-amz-server-side-encryption-customer-key' => Base64.encode64(encryption_key.to_s).chomp!,
'x-amz-server-side-encryption-customer-key-md5' => Base64.encode64(Digest::MD5.digest(encryption_key.to_s)).chomp!
}
end
end
end
end

View file

@ -74,6 +74,35 @@ Shindo.tests("Storage[:aws] | file", ["aws"]) do
end
tests("multipart upload with customer encryption").returns(true) do
pending if Fog.mocking?
encryption_key = OpenSSL::Cipher.new("AES-256-ECB").random_key
# A 6MB file
@large_file = Tempfile.new("fog-test-aws-s3-multipart")
6.times { @large_file.write("x" * (1024**2)) }
@large_file.rewind
tests("#save(:multipart_chunk_size => 5242880)").succeeds do
@directory.files.create(
:key => 'multipart-encrypted-upload',
:body => @large_file,
:multipart_chunk_size => 5242880,
:encryption => "AES256",
:encryption_key => encryption_key
)
end
@large_file.close
@directory.files.get('multipart-encrypted-upload',
'x-amz-server-side-encryption-customer-algorithm' => 'AES256',
'x-amz-server-side-encryption-customer-key' => Base64.encode64(encryption_key).chomp!,
'x-amz-server-side-encryption-customer-key-MD5' => Base64.encode64(Digest::MD5.digest(encryption_key.to_s)).chomp!
).body == "x" * 6*1024**2
end
acl = Fog::Storage[:aws].get_object_acl(@directory.key, @instance.key).body["AccessControlList"]
tests("#acl").returns(acl) do