Upload part and complete upload. Somehow, boto doesn't like output I send it, even though it's copy-pasted from its own logs.

This commit is contained in:
Lucian Branescu Mihaila 2013-03-26 15:50:18 +00:00
parent f557487e06
commit 5854219a4c
2 changed files with 40 additions and 15 deletions

View File

@ -37,7 +37,7 @@ class FakeMultipart(object):
if part_id != index: if part_id != index:
return return
total.extend(self.parts[part_id]) total.extend(self.parts[part_id].value)
if len(total) < 5242880: if len(total) < 5242880:
return return
@ -46,10 +46,11 @@ class FakeMultipart(object):
def set_part(self, part_id, value): def set_part(self, part_id, value):
if part_id < 1: if part_id < 1:
return False return
self.parts[part_id] = value key = FakeKey(part_id, value)
return True self.parts[part_id] = key
return key
class FakeBucket(object): class FakeBucket(object):
@ -109,9 +110,10 @@ class S3Backend(BaseBackend):
multipart = bucket.multiparts[multipart_id] multipart = bucket.multiparts[multipart_id]
value = multipart.complete() value = multipart.complete()
if value is None: if value is None:
return False return
del bucket.multiparts[multipart_id]
self.set_key(bucket_name, multipart.key_name, value) return self.set_key(bucket_name, multipart.key_name, value)
def set_part(self, bucket_name, multipart_id, part_id, value): def set_part(self, bucket_name, multipart_id, part_id, value):
bucket = self.buckets[bucket_name] bucket = self.buckets[bucket_name]

View File

@ -64,6 +64,7 @@ def key_response(uri_info, method, body, headers):
key_name = uri_info.path.lstrip('/') key_name = uri_info.path.lstrip('/')
hostname = uri_info.hostname hostname = uri_info.hostname
headers = headers_to_dict(headers) headers = headers_to_dict(headers)
query = parse_qs(uri_info.query)
bucket_name = bucket_name_from_hostname(hostname) bucket_name = bucket_name_from_hostname(hostname)
@ -74,12 +75,20 @@ def key_response(uri_info, method, body, headers):
else: else:
return "", dict(status=404) return "", dict(status=404)
if method == 'PUT': if method == 'PUT':
if 'uploadId' in query and 'partNumber' in query and body:
upload_id = query['uploadId'][0]
part_number = int(query['partNumber'][0])
key = s3_backend.set_part(bucket_name, upload_id, part_number, body)
return '', dict(etag=key.etag)
if 'x-amz-copy-source' in headers: if 'x-amz-copy-source' in headers:
# Copy key # Copy key
src_bucket, src_key = headers.get("x-amz-copy-source").split("/") src_bucket, src_key = headers.get("x-amz-copy-source").split("/")
s3_backend.copy_key(src_bucket, src_key, bucket_name, key_name) s3_backend.copy_key(src_bucket, src_key, bucket_name, key_name)
template = Template(S3_OBJECT_COPY_RESPONSE) template = Template(S3_OBJECT_COPY_RESPONSE)
return template.render(key=src_key) return template.render(key=src_key)
if body is not None: if body is not None:
key = s3_backend.get_key(bucket_name, key_name) key = s3_backend.get_key(bucket_name, key_name)
if not key or body: if not key or body:
@ -107,19 +116,30 @@ def key_response(uri_info, method, body, headers):
template = Template(S3_DELETE_OBJECT_SUCCESS) template = Template(S3_DELETE_OBJECT_SUCCESS)
return template.render(bucket=removed_key), dict(status=204) return template.render(bucket=removed_key), dict(status=204)
elif method == 'POST': elif method == 'POST':
import pdb; pdb.set_trace()
if body == '' and uri_info.query == 'uploads': if body == '' and uri_info.query == 'uploads':
multipart = s3_backend.initiate_multipart(bucket_name, key_name) multipart = s3_backend.initiate_multipart(bucket_name, key_name)
template = Template(S3_MULTIPART_RESPONSE) template = Template(S3_MULTIPART_INITIATE_RESPONSE)
response = template.render( response = template.render(
bucket_name=bucket_name, bucket_name=bucket_name,
key_name=key_name, key_name=key_name,
multipart_id=multipart.id, multipart_id=multipart.id,
) )
print response
return response, dict() return response, dict()
if body == '' and 'uploadId' in query:
upload_id = query['uploadId'][0]
key = s3_backend.complete_multipart(bucket_name, upload_id)
if key is not None:
template = Template(S3_MULTIPART_COMPLETE_RESPONSE)
return template.render(
bucket_name=bucket_name,
key_name=key.name,
etag=key.etag,
)
else: else:
import pdb; pdb.set_trace() raise NotImplementedError("Method POST had only been implemented for multipart uploads so far")
raise NotImplementedError("POST is only allowed for multipart uploads")
else: else:
raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method)) raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method))
@ -217,15 +237,18 @@ S3_OBJECT_COPY_RESPONSE = """<CopyObjectResponse xmlns="http://doc.s3.amazonaws.
</CopyObjectResponse> </CopyObjectResponse>
</CopyObjectResponse>""" </CopyObjectResponse>"""
S3_MULTIPART_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?> S3_MULTIPART_INITIATE_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?>
<InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <InitiateMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Bucket>{{ bucket_name }}</Bucket> <Bucket>{{ bucket_name }}</Bucket>
<Key>{{ key_name }}</Key> <Key>{{ key_name }}</Key>
<UploadId>{{ upload_id }}</UploadId> <UploadId>{{ upload_id }}</UploadId>
</InitiateMultipartUploadResult>""" </InitiateMultipartUploadResult>"""
S3_MULTIPART_COMPLETE_RESPONSE = """ S3_MULTIPART_COMPLETE_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?>
""" <CompleteMultipartUploadResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Location>http://{{ bucket_name }}.s3.amazonaws.com/{{ key_name }}</Location>
S3_MULTIPART_ERROR_RESPONSE = """ <Bucket>{{ bucket_name }}</Bucket>
<Key>{{ key_name }}</Key>
<ETag>{{ etag }}</ETag>
</CompleteMultipartUploadResult>
""" """