From 11e5c4adf0e02c8fdab0d8584fc943d96e1165cd Mon Sep 17 00:00:00 2001 From: Koert van der Veer Date: Tue, 16 Dec 2014 11:15:19 +0100 Subject: [PATCH] Allow default reseller prefix in domain_remap middleware Previously, the reseller prefix needed to be provided in the host name even when the domain was unique to that reseller. With the default_reseller_prefix, any domain which matches in this middleware, will will be passed on with a reseller prefix, whether or not it was provided. Change-Id: I5aa5ce78ad1ee2e3660cce4c3e07306f8999f02a Implements: blueprint domainremap-reseller-domains --- doc/manpages/proxy-server.conf.5 | 10 +++++-- etc/proxy-server.conf-sample | 9 ++++++ swift/common/middleware/domain_remap.py | 28 ++++++++++++------- .../common/middleware/test_domain_remap.py | 16 +++++++++++ 4 files changed, 50 insertions(+), 13 deletions(-) diff --git a/doc/manpages/proxy-server.conf.5 b/doc/manpages/proxy-server.conf.5 index 17197453ac..7ce480b0ca 100644 --- a/doc/manpages/proxy-server.conf.5 +++ b/doc/manpages/proxy-server.conf.5 @@ -296,9 +296,13 @@ Browsers can convert a host header to lowercase, so check that reseller prefix on the account is the correct case. This is done by comparing the items in the reseller_prefixes config option to the found prefix. If they match except for case, the item from reseller_prefixes will be used -instead of the found reseller prefix. The reseller_prefixes list is exclusive. -If defined, any request with an account prefix not in that list will be ignored -by this middleware. Defaults to 'AUTH'. +instead of the found reseller prefix. When none match, the default reseller +prefix is used. When no default reseller prefix is configured, any request with +an account prefix not in that list will be ignored by this middleware. +Defaults to 'AUTH'. +.IP \fBdefault_reseller_prefix\fR +The default reseller prefix. This is used when none of the configured +reseller_prefixes match. When not set, no reseller prefix is added. .RE diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index 37fc7d4564..55b6137ae0 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -460,7 +460,16 @@ use = egg:swift#domain_remap # # storage_domain = example.com # path_root = v1 + +# Browsers can convert a host header to lowercase, so check that reseller +# prefix on the account is the correct case. This is done by comparing the +# items in the reseller_prefixes config option to the found prefix. If they +# match except for case, the item from reseller_prefixes will be used +# instead of the found reseller prefix. When none match, the default reseller +# prefix is used. When no default reseller prefix is configured, any request +# with an account prefix not in that list will be ignored by this middleware. # reseller_prefixes = AUTH +# default_reseller_prefix = [filter:catch_errors] use = egg:swift#catch_errors diff --git a/swift/common/middleware/domain_remap.py b/swift/common/middleware/domain_remap.py index cabd32aca7..052f7728df 100644 --- a/swift/common/middleware/domain_remap.py +++ b/swift/common/middleware/domain_remap.py @@ -30,9 +30,10 @@ Browsers can convert a host header to lowercase, so check that reseller prefix on the account is the correct case. This is done by comparing the items in the reseller_prefixes config option to the found prefix. If they match except for case, the item from reseller_prefixes will be used -instead of the found reseller prefix. The reseller_prefixes list is -exclusive. If defined, any request with an account prefix not in that list -will be ignored by this middleware. reseller_prefixes defaults to 'AUTH'. +instead of the found reseller prefix. When none match, the default reseller +prefix is used. When no default reseller prefix is configured, any request with +an account prefix not in that list will be ignored by this middleware. +reseller_prefixes defaults to 'AUTH'. Note that this middleware requires that container names and account names (except as described above) must be DNS-compatible. This means that the @@ -74,6 +75,7 @@ class DomainRemapMiddleware(object): if x.strip()] self.reseller_prefixes_lower = [x.lower() for x in self.reseller_prefixes] + self.default_reseller_prefix = conf.get('default_reseller_prefix') def __call__(self, env, start_response): if not self.storage_domain: @@ -102,15 +104,21 @@ class DomainRemapMiddleware(object): if '_' not in account and '-' in account: account = account.replace('-', '_', 1) account_reseller_prefix = account.split('_', 1)[0].lower() - if account_reseller_prefix not in self.reseller_prefixes_lower: + + if account_reseller_prefix in self.reseller_prefixes_lower: + prefix_index = self.reseller_prefixes_lower.index( + account_reseller_prefix) + real_prefix = self.reseller_prefixes[prefix_index] + if not account.startswith(real_prefix): + account_suffix = account[len(real_prefix):] + account = real_prefix + account_suffix + elif self.default_reseller_prefix: + # account prefix is not in config list. Add default one. + account = "%s_%s" % (self.default_reseller_prefix, account) + else: # account prefix is not in config list. bail. return self.app(env, start_response) - prefix_index = self.reseller_prefixes_lower.index( - account_reseller_prefix) - real_prefix = self.reseller_prefixes[prefix_index] - if not account.startswith(real_prefix): - account_suffix = account[len(real_prefix):] - account = real_prefix + account_suffix + path = env['PATH_INFO'].strip('/') new_path_parts = ['', self.path_root, account] if container: diff --git a/test/unit/common/middleware/test_domain_remap.py b/test/unit/common/middleware/test_domain_remap.py index dd86da633f..b14dfbcb2e 100644 --- a/test/unit/common/middleware/test_domain_remap.py +++ b/test/unit/common/middleware/test_domain_remap.py @@ -138,6 +138,22 @@ class TestDomainRemap(unittest.TestCase): resp = self.app(req.environ, start_response) self.assertEquals(resp, '/v1/uuid/c/test') + def test_domain_remap_add_prefix(self): + conf = {'default_reseller_prefix': 'FOO'} + self.app = domain_remap.DomainRemapMiddleware(FakeApp(), conf) + req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, + headers={'Host': 'uuid.example.com'}) + resp = self.app(req.environ, start_response) + self.assertEquals(resp, '/v1/FOO_uuid/test') + + def test_domain_remap_add_prefix_already_there(self): + conf = {'default_reseller_prefix': 'AUTH'} + self.app = domain_remap.DomainRemapMiddleware(FakeApp(), conf) + req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, + headers={'Host': 'auth-uuid.example.com'}) + resp = self.app(req.environ, start_response) + self.assertEquals(resp, '/v1/AUTH_uuid/test') + if __name__ == '__main__': unittest.main()