From 04b1af215e152ed559a72fe5a521fae753944f65 Mon Sep 17 00:00:00 2001 From: David Goetz Date: Tue, 14 Jan 2014 12:51:40 -0800 Subject: [PATCH] Drop origin from get_info calls The reason for this is that having origin in the get_info calls causes an infinite loop. The way that code was written it relies on GETorHEAD_base to populate the data- the only problem is that the HEAD call is wrapped by cors_validation which calls get_info and round and round we go. imo get_info should be refactored to not work this way (relying on this other call to do stuff behind scenes and then magically your stuff is there) because it seems pretty prone to breaking. But I'll let somebody else do that :). Fixes bug 1270039 Change-Id: Idad3cedd965e0d5fb068b062fe8fef301c87b75a --- swift/proxy/controllers/base.py | 3 +++ test/unit/proxy/test_server.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/swift/proxy/controllers/base.py b/swift/proxy/controllers/base.py index ff1a950494..daa6abe826 100644 --- a/swift/proxy/controllers/base.py +++ b/swift/proxy/controllers/base.py @@ -437,6 +437,9 @@ def _prepare_pre_auth_info_request(env, path, swift_source): # Set the env for the pre_authed call without a query string newenv = make_pre_authed_env(env, 'HEAD', path, agent='Swift', query_string='', swift_source=swift_source) + # This is a sub request for container metadata- drop the Origin header from + # the request so the it is not treated as a CORS request. + newenv.pop('HTTP_ORIGIN', None) # Note that Request.blank expects quoted path return Request.blank(quote(path), environ=newenv) diff --git a/test/unit/proxy/test_server.py b/test/unit/proxy/test_server.py index 7b00c56a60..14c7f9cc0c 100644 --- a/test/unit/proxy/test_server.py +++ b/test/unit/proxy/test_server.py @@ -50,6 +50,7 @@ from swift.common import utils from swift.common.utils import mkdirs, normalize_timestamp, NullLogger from swift.common.wsgi import monkey_patch_mimetools from swift.proxy.controllers.obj import SegmentedIterable +from swift.proxy.controllers import base as proxy_base from swift.proxy.controllers.base import get_container_memcache_key, \ get_account_memcache_key, cors_validation import swift.proxy.controllers @@ -5693,6 +5694,33 @@ class TestContainerController(unittest.TestCase): controller.HEAD(req) self.assert_(called[0]) + def test_OPTIONS_get_info_drops_origin(self): + with save_globals(): + controller = proxy_server.ContainerController(self.app, 'a', 'c') + + count = [0] + + def my_get_info(app, env, account, container=None, + ret_not_found=False, swift_source=None): + if count[0] > 11: + return {} + count[0] += 1 + if not container: + return {'some': 'stuff'} + return proxy_base.was_get_info( + app, env, account, container, ret_not_found, swift_source) + + proxy_base.was_get_info = proxy_base.get_info + with mock.patch.object(proxy_base, 'get_info', my_get_info): + proxy_base.get_info = my_get_info + req = Request.blank( + '/v1/a/c', + {'REQUEST_METHOD': 'OPTIONS'}, + headers={'Origin': 'http://foo.com', + 'Access-Control-Request-Method': 'GET'}) + controller.OPTIONS(req) + self.assertTrue(count[0] < 11) + def test_OPTIONS(self): with save_globals(): controller = proxy_server.ContainerController(self.app, 'a', 'c')