first working version of s3 refactor.

This commit is contained in:
Steve Pulec 2015-11-27 13:49:44 -05:00
commit 1df454a632
6 changed files with 86 additions and 35 deletions

View file

@ -8,6 +8,9 @@ import xmltodict
from moto.core.responses import _TemplateEnvironmentMixin
from moto.s3bucket_path.utils import bucket_name_from_url as bucketpath_bucket_name_from_url, parse_key_name as bucketpath_parse_key_name, is_delete_keys as bucketpath_is_delete_keys
from .exceptions import BucketAlreadyExists, S3ClientError, InvalidPartOrder
from .models import s3_backend, get_canned_acl, FakeGrantee, FakeGrant, FakeAcl
from .utils import bucket_name_from_url, metadata_from_headers
@ -21,19 +24,25 @@ def parse_key_name(pth):
return pth.lstrip("/")
def is_delete_keys(path, bucket_name):
return path == u'/?delete'
class ResponseObject(_TemplateEnvironmentMixin):
def __init__(self, backend, bucket_name_from_url, parse_key_name,
def __init__(self, backend, parse_key_name, bucket_name_from_url,
is_delete_keys=None):
super(ResponseObject, self).__init__()
self.backend = backend
self.bucket_name_from_url = bucket_name_from_url
self.parse_key_name = parse_key_name
if is_delete_keys:
self.is_delete_keys = is_delete_keys
# self.bucket_name_from_url = bucket_name_from_url
# self.parse_key_name = parse_key_name
# if is_delete_keys:
# self.is_delete_keys = is_delete_keys
@staticmethod
def is_delete_keys(path, bucket_name):
return path == u'/?delete'
def is_delete_keys(self, request, path, bucket_name):
if self.is_path_based_buckets(request):
return bucketpath_is_delete_keys(path, bucket_name)
else:
return is_delete_keys(path, bucket_name)
def all_buckets(self):
# No bucket specified. Listing all buckets
@ -41,6 +50,30 @@ class ResponseObject(_TemplateEnvironmentMixin):
template = self.response_template(S3_ALL_BUCKETS)
return template.render(buckets=all_buckets)
def is_path_based_buckets(self, request):
return request.headers['host'] == 's3.amazonaws.com'
def parse_bucket_name_from_url(self, request, url):
if self.is_path_based_buckets(request):
return bucketpath_bucket_name_from_url(url)
else:
return bucket_name_from_url(url)
def parse_key_name(self, request, url):
if self.is_path_based_buckets(request):
return bucketpath_parse_key_name(url)
else:
return parse_key_name(url)
def response(self, request, full_url, headers):
# Depending on which calling format the client is using, we don't know
# if this is a bucket or key request so we have to check
if self.is_path_based_buckets(request):
# Using path-based buckets
return self.bucket_response(request, full_url, headers)
else:
return self.key_response(request, full_url, headers)
def bucket_response(self, request, full_url, headers):
try:
response = self._bucket_response(request, full_url, headers)
@ -62,7 +95,7 @@ class ResponseObject(_TemplateEnvironmentMixin):
if region_match:
region_name = region_match.groups()[0]
bucket_name = self.bucket_name_from_url(full_url)
bucket_name = self.parse_bucket_name_from_url(request, full_url)
if not bucket_name:
# If no bucket specified, list all buckets
return self.all_buckets()
@ -232,7 +265,7 @@ class ResponseObject(_TemplateEnvironmentMixin):
return 409, headers, template.render(bucket=removed_bucket)
def _bucket_response_post(self, request, bucket_name, headers):
if self.is_delete_keys(request.path, bucket_name):
if self.is_delete_keys(request, request.path, bucket_name):
return self._bucket_response_delete_keys(request, bucket_name, headers)
# POST to bucket-url should create file from form
@ -320,8 +353,8 @@ class ResponseObject(_TemplateEnvironmentMixin):
query = parse_qs(parsed_url.query, keep_blank_values=True)
method = request.method
key_name = self.parse_key_name(parsed_url.path)
bucket_name = self.bucket_name_from_url(full_url)
key_name = self.parse_key_name(request, parsed_url.path)
bucket_name = self.parse_bucket_name_from_url(request, full_url)
if hasattr(request, 'body'):
# Boto

View file

@ -2,10 +2,23 @@ from __future__ import unicode_literals
from .responses import S3ResponseInstance
url_bases = [
"https?://s3(.*).amazonaws.com",
"https?://(?P<bucket_name>[a-zA-Z0-9\-_.]*)\.?s3(.*).amazonaws.com"
]
url_paths = {
# subdomain bucket
'{0}/$': S3ResponseInstance.bucket_response,
'{0}/(?P<key_name>.+)': S3ResponseInstance.key_response,
# subdomain key of path-based bucket
'{0}/(?P<key_name>.+)': S3ResponseInstance.response,
# path-based bucket + key
'{0}/(?P<bucket_name_path>[a-zA-Z0-9\-_./]+)/(?P<key_name>.+)': S3ResponseInstance.key_response,
# '{0}/(?P<bucket_name>[a-zA-Z0-9\-_.]+)$': ro.bucket_response,
# '{0}/(?P<bucket_name>[a-zA-Z0-9\-_.]+)/$': bucket_response2,
}