From c68a1d3e9dc8ef55bec1e593ed0d9eb20b737ae8 Mon Sep 17 00:00:00 2001 From: Konstantinos Koukopoulos Date: Fri, 21 Mar 2014 17:33:10 +0200 Subject: [PATCH] support x-amz-copy-source in multipart uploads --- moto/s3/models.py | 8 ++++++++ moto/s3/responses.py | 18 ++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/moto/s3/models.py b/moto/s3/models.py index e6f6af9d9..2def8db00 100644 --- a/moto/s3/models.py +++ b/moto/s3/models.py @@ -182,6 +182,14 @@ class S3Backend(BaseBackend): multipart = bucket.multiparts[multipart_id] return multipart.set_part(part_id, value) + def copy_part(self, dest_bucket_name, multipart_id, part_id, + src_bucket_name, src_key_name): + src_key_name = clean_key_name(src_key_name) + src_bucket = self.buckets[src_bucket_name] + dest_bucket = self.buckets[dest_bucket_name] + multipart = dest_bucket.multiparts[multipart_id] + return multipart.set_part(part_id, src_bucket.keys[src_key_name].value) + def prefix_query(self, bucket, prefix, delimiter): key_results = set() folder_results = set() diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 127d61faa..27aa0118d 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -160,13 +160,23 @@ class ResponseObject(object): else: return 404, headers, "" if method == 'PUT': - if 'uploadId' in query and 'partNumber' in query and body: + if 'uploadId' in query and 'partNumber' in query: upload_id = query['uploadId'][0] part_number = int(query['partNumber'][0]) - key = self.backend.set_part(bucket_name, upload_id, part_number, body) - template = Template(S3_MULTIPART_UPLOAD_RESPONSE) + if 'x-amz-copy-source' in request.headers: + src = request.headers.get("x-amz-copy-source") + src_bucket, src_key = src.split("/", 1) + key = self.backend.copy_part( + bucket_name, upload_id, part_number, src_bucket, + src_key) + template = Template(S3_MULTIPART_UPLOAD_RESPONSE) + response = template.render(part=key) + else: + key = self.backend.set_part( + bucket_name, upload_id, part_number, body) + response = "" headers.update(key.response_dict) - return 200, headers, template.render(part=key) + return 200, headers, response if 'x-amz-copy-source' in request.headers: # Copy key