def key_response(uri_info, method, body, headers): key_name = uri_info.path.lstrip('/') hostname = uri_info.hostname headers = headers_to_dict(headers) bucket_name = bucket_name_from_hostname(hostname) if method == 'GET': key = s3_backend.get_key(bucket_name, key_name) if key: return key.value else: return "", dict(status=404) if method == 'PUT': if 'x-amz-copy-source' in headers: # Copy key src_bucket, src_key = headers.get("x-amz-copy-source").split("/") s3_backend.copy_key(src_bucket, src_key, bucket_name, key_name) template = Template(S3_OBJECT_COPY_RESPONSE) return template.render(key=src_key) content_length = int(headers.get('Content-Length', 0)) if body or (body == '' and content_length == 0): # We want to write the key in once of two circumstances. # - Anytime we are given a truthy body value # - We are given an empty body value and the content length is zero. # The reason we do not set the key to an empty string if the # content length is not zero is because we are sometimes sent an # empty string as part of closing the connection. new_key = s3_backend.set_key(bucket_name, key_name, body) template = Template(S3_OBJECT_RESPONSE) return template.render(key=new_key), new_key.response_dict key = s3_backend.get_key(bucket_name, key_name) if key: return "", key.response_dict elif method == 'HEAD': key = s3_backend.get_key(bucket_name, key_name) if key: return S3_OBJECT_RESPONSE, key.response_dict else: return "", dict(status=404) elif method == 'DELETE': removed_key = s3_backend.delete_key(bucket_name, key_name) template = Template(S3_DELETE_OBJECT_SUCCESS) return template.render(bucket=removed_key), dict(status=204) else: raise NotImplementedError("Method {0} has not been impelemented in the S3 backend yet".format(method))
def dispatch(self, uri, method, body, headers): if body: querystring = parse_qs(body) else: querystring = headers_to_dict(headers) self.path = uri.path self.querystring = querystring action = querystring.get('Action', [""])[0] action = camelcase_to_underscores(action) method_names = method_names_from_class(self.__class__) if action in method_names: method = getattr(self, action) return method() raise NotImplementedError("The {} action has not been implemented".format(action))
def key_response(uri_info, method, body, headers): key_name = uri_info.path.lstrip('/') hostname = uri_info.hostname headers = headers_to_dict(headers) bucket_name = bucket_name_from_hostname(hostname) if method == 'GET': key = s3_backend.get_key(bucket_name, key_name) if key: return key.value else: return "", dict(status=404) if method == 'PUT': if 'x-amz-copy-source' in headers: # Copy key src_bucket, src_key = headers.get("x-amz-copy-source").split("/") s3_backend.copy_key(src_bucket, src_key, bucket_name, key_name) template = Template(S3_OBJECT_COPY_RESPONSE) return template.render(key=src_key) if body: new_key = s3_backend.set_key(bucket_name, key_name, body) template = Template(S3_OBJECT_RESPONSE) return template.render(key=new_key), dict(etag=new_key.etag) key = s3_backend.get_key(bucket_name, key_name) if key: return "", dict(etag=key.etag) elif method == 'HEAD': key = s3_backend.get_key(bucket_name, key_name) if key: return S3_OBJECT_RESPONSE, dict(etag=key.etag) else: return "", dict(status=404) elif method == 'DELETE': removed_key = s3_backend.delete_key(bucket_name, key_name) template = Template(S3_DELETE_OBJECT_SUCCESS) return template.render(bucket=removed_key), dict(status=204) else: raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method))
def handler(uri, method, body, headers): if 'GetSessionToken' in body: return sts_handler(uri, method, body, headers) body = json.loads(body or '{}') return DynamoHandler(uri, method, body, headers_to_dict(headers)).dispatch()
def key_response(uri_info, method, body, headers): key_name = uri_info.path.lstrip('/') hostname = uri_info.hostname headers = headers_to_dict(headers) query = parse_qs(uri_info.query) bucket_name = bucket_name_from_hostname(hostname) if method == 'GET': key = s3_backend.get_key(bucket_name, key_name) if key: return key.value else: return "", dict(status=404) 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: # Copy key src_bucket, src_key = headers.get("x-amz-copy-source").split("/") s3_backend.copy_key(src_bucket, src_key, bucket_name, key_name) template = Template(S3_OBJECT_COPY_RESPONSE) return template.render(key=src_key) if body is not None: key = s3_backend.get_key(bucket_name, key_name) if not key or body: # We want to write the key in once of two circumstances. # - The key does not currently exist. # - The key already exists, but body is a truthy value. # This allows us to write empty strings to keys for the first # write, but not subsequent. This is because HTTPretty sends # an empty string on connection close. This is a temporary fix # while HTTPretty gets fixed. new_key = s3_backend.set_key(bucket_name, key_name, body) template = Template(S3_OBJECT_RESPONSE) return template.render(key=new_key), dict(etag=new_key.etag) key = s3_backend.get_key(bucket_name, key_name) if key: return "", dict(etag=key.etag) elif method == 'HEAD': key = s3_backend.get_key(bucket_name, key_name) if key: return S3_OBJECT_RESPONSE, dict(etag=key.etag) else: return "", dict(status=404) elif method == 'DELETE': removed_key = s3_backend.delete_key(bucket_name, key_name) template = Template(S3_DELETE_OBJECT_SUCCESS) return template.render(bucket=removed_key), dict(status=204) elif method == 'POST': import pdb; pdb.set_trace() if body == '' and uri_info.query == 'uploads': multipart = s3_backend.initiate_multipart(bucket_name, key_name) template = Template(S3_MULTIPART_INITIATE_RESPONSE) response = template.render( bucket_name=bucket_name, key_name=key_name, multipart_id=multipart.id, ) 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: raise NotImplementedError("Method POST had only been implemented for multipart uploads so far") else: raise NotImplementedError("Method {} has not been impelemented in the S3 backend yet".format(method))