diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index d7d893b726..caf27967b1 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -438,6 +438,11 @@ def get_container_info(env, app, swift_source=None): account = wsgi_to_str(wsgi_account) container = wsgi_to_str(wsgi_container) + # Try to cut through all the layers to the proxy app + try: + app = app._pipeline_final_app + except AttributeError: + pass # Check in environment cache and in memcache (in that order) info = _get_info_from_caches(app, env, account, container) @@ -526,6 +531,11 @@ def get_account_info(env, app, swift_source=None): account = wsgi_to_str(wsgi_account) + # Try to cut through all the layers to the proxy app + try: + app = app._pipeline_final_app + except AttributeError: + pass # Check in environment cache and in memcache (in that order) info = _get_info_from_caches(app, env, account) diff --git a/test/unit/proxy/controllers/test_base.py b/test/unit/proxy/controllers/test_base.py index 8ed3528422..a2d134f434 100644 --- a/test/unit/proxy/controllers/test_base.py +++ b/test/unit/proxy/controllers/test_base.py @@ -152,7 +152,10 @@ class ZeroCacheDynamicResponseFactory(DynamicResponseFactory): class FakeApp(object): recheck_container_existence = 30 + container_existence_skip_cache = 0 recheck_account_existence = 30 + account_existence_skip_cache = 0 + logger = None def __init__(self, response_factory=None, statuses=None): self.responses = response_factory or \ @@ -352,6 +355,29 @@ class TestFuncs(BaseTest): self.assertEqual([e['swift.source'] for e in app.captured_envs], ['MC', 'MC']) + def test_get_container_info_in_pipeline(self): + final_app = FakeApp() + + def factory(app): + def wsgi_filter(env, start_response): + # lots of middlewares get info... + if env['PATH_INFO'].count('/') > 2: + get_container_info(env, app) + else: + get_account_info(env, app) + # ...then decide to no-op based on the result + return app(env, start_response) + + wsgi_filter._pipeline_final_app = final_app + return wsgi_filter + + # build up a pipeline + filtered_app = factory(factory(factory(final_app))) + req = Request.blank("/v1/a/c/o", environ={'swift.cache': FakeCache()}) + req.get_response(filtered_app) + self.assertEqual([e['PATH_INFO'] for e in final_app.captured_envs], + ['/v1/a', '/v1/a/c', '/v1/a/c/o']) + def test_get_object_info_swift_source(self): app = FakeApp() req = Request.blank("/v1/a/c/o", diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index 5ac90171dc..e6de595529 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -513,7 +513,8 @@ class TestController(unittest.TestCase): def test_get_account_info_returns_values_as_strings(self): app = mock.MagicMock() - app._pipeline_final_app.account_existence_skip_cache = 0.0 + app._pipeline_final_app = app + app.account_existence_skip_cache = 0.0 memcache = mock.MagicMock() memcache.get = mock.MagicMock() memcache.get.return_value = { @@ -539,7 +540,8 @@ class TestController(unittest.TestCase): def test_get_container_info_returns_values_as_strings(self): app = mock.MagicMock() - app._pipeline_final_app.container_existence_skip_cache = 0.0 + app._pipeline_final_app = app + app.container_existence_skip_cache = 0.0 memcache = mock.MagicMock() memcache.get = mock.MagicMock() memcache.get.return_value = {