diff --git a/swift3/controllers/obj.py b/swift3/controllers/obj.py index 97d511bd..9b55c913 100644 --- a/swift3/controllers/obj.py +++ b/swift3/controllers/obj.py @@ -13,13 +13,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from swift.common.http import HTTP_OK, is_success +from swift.common.http import HTTP_OK from swift.common.swob import Range, content_range_header_value -from swift.proxy.controllers.base import get_container_info from swift3.controllers.base import Controller from swift3.response import S3NotImplemented, InvalidRange, \ - HTTPPartialContent, NoSuchBucket, NoSuchKey + HTTPPartialContent, NoSuchKey class ObjectController(Controller): @@ -113,11 +112,7 @@ class ObjectController(Controller): try: resp = req.get_response(self.app) except NoSuchKey: - sw_req = req.to_swift_req( - self.app, req.container_name, req.object_name) - info = get_container_info(sw_req.environ, self.app) - if is_success(info['status']): - raise - else: - raise NoSuchBucket(req.container_name) + # expect to raise NoSuchBucket when the bucket doesn't exist + req.get_container_info(self.app) + raise return resp diff --git a/swift3/request.py b/swift3/request.py index e550dc1b..59ba36f1 100644 --- a/swift3/request.py +++ b/swift3/request.py @@ -27,9 +27,10 @@ from swift.common.http import HTTP_OK, HTTP_CREATED, HTTP_ACCEPTED, \ HTTP_CONFLICT, HTTP_UNPROCESSABLE_ENTITY, HTTP_REQUEST_ENTITY_TOO_LARGE, \ HTTP_PARTIAL_CONTENT, HTTP_NOT_MODIFIED, HTTP_PRECONDITION_FAILED, \ HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, HTTP_LENGTH_REQUIRED, \ - HTTP_BAD_REQUEST, HTTP_REQUEST_TIMEOUT + HTTP_BAD_REQUEST, HTTP_REQUEST_TIMEOUT, is_success from swift.common.constraints import check_utf8 +from swift.proxy.controllers.base import get_container_info from swift3.controllers import ServiceController, BucketController, \ ObjectController, AclController, MultiObjectDeleteController, \ @@ -680,6 +681,25 @@ class Request(swob.Request): return value + def get_container_info(self, app): + """ + get_container_info will return a result dict of get_container_info + from the backend Swift. + + :returns: a dictionary of container info from + swift.controllers.base.get_container_info + :raises: NoSuchBucket when the container doesn't exist + :raises: InternalError when the request failed without 404 + """ + sw_req = self.to_swift_req(app, self.container_name, None) + info = get_container_info(sw_req.environ, app) + if is_success(info['status']): + return info + elif info['status'] == 404: + raise NoSuchBucket(self.container_name) + else: + raise InternalError('unexpected status code %d' % info['status']) + class S3AclRequest(Request): """ diff --git a/swift3/test/unit/test_obj.py b/swift3/test/unit/test_obj.py index bd796df7..5d568452 100644 --- a/swift3/test/unit/test_obj.py +++ b/swift3/test/unit/test_obj.py @@ -567,13 +567,13 @@ class TestSwift3Obj(Swift3TestCase): swob.HTTPServiceUnavailable) self.assertEquals(code, 'InternalError') - with patch('swift3.controllers.obj.get_container_info', + with patch('swift3.request.get_container_info', return_value={'status': 204}): code = self._test_method_error('DELETE', '/bucket/object', swob.HTTPNotFound) self.assertEquals(code, 'NoSuchKey') - with patch('swift3.controllers.obj.get_container_info', + with patch('swift3.request.get_container_info', return_value={'status': 404}): code = self._test_method_error('DELETE', '/bucket/object', swob.HTTPNotFound) diff --git a/swift3/test/unit/test_request.py b/swift3/test/unit/test_request.py index 4396a1bb..a0859471 100644 --- a/swift3/test/unit/test_request.py +++ b/swift3/test/unit/test_request.py @@ -24,7 +24,7 @@ from swift3.test.unit.test_middleware import Swift3TestCase from swift3.cfg import CONF from swift3.request import Request as S3_Request from swift3.request import S3AclRequest -from swift3.response import InvalidArgument +from swift3.response import InvalidArgument, NoSuchBucket, InternalError Fake_ACL_MAP = { @@ -276,6 +276,23 @@ class TestRequest(Swift3TestCase): sw_req = s3_req.to_swift_req(method, container, obj) self.assertTrue(sw_req.environ['swift.proxy_access_log_made']) + def test_get_container_info(self): + req = Request.blank('/bucket', environ={'REQUEST_METHOD': 'GET'}, + headers={'Authorization': 'AWS test:tester:hmac'}) + s3_req = S3_Request(req.environ, True) + with patch('swift3.request.get_container_info', + return_value={'status': 204}): + info = s3_req.get_container_info(MagicMock()) + self.assertTrue('status' in info) + self.assertEquals(204, info['status']) + + expected_errors = [(404, NoSuchBucket), (0, InternalError)] + for status, expected_error in expected_errors: + with patch('swift3.request.get_container_info', + return_value={'status': status}): + self.assertRaises( + expected_error, s3_req.get_container_info, MagicMock()) + if __name__ == '__main__': unittest.main()