Rewrite redirection in cname_lookup & domain_remap

cname_lookup and domain_remap are currently not catching redirections
(eg: staticweb). This behavior makes the domain to change when a call
through cname_lookup and domain_remap end up being redirected. Example:
commit fixes it.
 - original request: http://mysite.com/subdir
 - redirected:  http://cont.acct.storage.domain.com/v1/AUTH_acct/cont/subdir/
 - expected: http://mysite.com/subdir/

This patch is fixing this.

Closes-Bug: #1190625
Co-Authored-By: Tim Burke <tim.burke@gmail.com>
Change-Id: I67f642b8b070bc21e7760477d0a1e3b902ba7896
This commit is contained in:
Romain LE DISEZ 2017-02-18 16:22:11 +01:00
parent 6db12b87ff
commit 107ba79770
5 changed files with 155 additions and 48 deletions

View File

@ -0,0 +1,36 @@
# Copyright (c) 2010-2017 OpenStack Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re
from swift.common.wsgi import WSGIContext
class RewriteContext(WSGIContext):
base_re = None
def __init__(self, app, requested, rewritten):
super(RewriteContext, self).__init__(app)
self.requested = requested
self.rewritten_re = re.compile(self.base_re % re.escape(rewritten))
def handle_request(self, env, start_response):
resp_iter = self._app_call(env)
for i, (header, value) in enumerate(self._response_headers):
if header.lower() in ('location', 'content-location'):
self._response_headers[i] = (header, self.rewritten_re.sub(
r'\1%s\2' % self.requested, value))
start_response(self._response_status, self._response_headers,
self._response_exc_info)
return resp_iter

View File

@ -41,6 +41,7 @@ except ImportError:
else: # executed if the try block finishes with no errors else: # executed if the try block finishes with no errors
MODULE_DEPENDENCY_MET = True MODULE_DEPENDENCY_MET = True
from swift.common.middleware import RewriteContext
from swift.common.swob import Request, HTTPBadRequest from swift.common.swob import Request, HTTPBadRequest
from swift.common.utils import cache_from_env, get_logger, list_from_csv, \ from swift.common.utils import cache_from_env, get_logger, list_from_csv, \
register_swift_info register_swift_info
@ -80,6 +81,10 @@ def is_ip(domain):
return False return False
class _CnameLookupContext(RewriteContext):
base_re = r'^(https?://)%s(/.*)?$'
class CNAMELookupMiddleware(object): class CNAMELookupMiddleware(object):
""" """
CNAME Lookup Middleware CNAME Lookup Middleware
@ -117,9 +122,9 @@ class CNAMELookupMiddleware(object):
if not self.storage_domain: if not self.storage_domain:
return self.app(env, start_response) return self.app(env, start_response)
if 'HTTP_HOST' in env: if 'HTTP_HOST' in env:
given_domain = env['HTTP_HOST'] requested_host = given_domain = env['HTTP_HOST']
else: else:
given_domain = env['SERVER_NAME'] requested_host = given_domain = env['SERVER_NAME']
port = '' port = ''
if ':' in given_domain: if ':' in given_domain:
given_domain, port = given_domain.rsplit(':', 1) given_domain, port = given_domain.rsplit(':', 1)
@ -175,6 +180,11 @@ class CNAMELookupMiddleware(object):
resp = HTTPBadRequest(request=Request(env), body=msg, resp = HTTPBadRequest(request=Request(env), body=msg,
content_type='text/plain') content_type='text/plain')
return resp(env, start_response) return resp(env, start_response)
else:
context = _CnameLookupContext(self.app, requested_host,
env['HTTP_HOST'])
return context.handle_request(env, start_response)
return self.app(env, start_response) return self.app(env, start_response)

View File

@ -50,10 +50,15 @@ advised. With container sync, you should use the true storage end points as
sync destinations. sync destinations.
""" """
from swift.common.middleware import RewriteContext
from swift.common.swob import Request, HTTPBadRequest from swift.common.swob import Request, HTTPBadRequest
from swift.common.utils import list_from_csv, register_swift_info from swift.common.utils import list_from_csv, register_swift_info
class _DomainRemapContext(RewriteContext):
base_re = r'^(https?://[^/]+)%s(.*)$'
class DomainRemapMiddleware(object): class DomainRemapMiddleware(object):
""" """
Domain Remap Middleware Domain Remap Middleware
@ -124,7 +129,7 @@ class DomainRemapMiddleware(object):
# account prefix is not in config list. bail. # account prefix is not in config list. bail.
return self.app(env, start_response) return self.app(env, start_response)
path = env['PATH_INFO'] requested_path = path = env['PATH_INFO']
new_path_parts = [self.path_root, account] new_path_parts = [self.path_root, account]
if container: if container:
new_path_parts.append(container) new_path_parts.append(container)
@ -135,6 +140,10 @@ class DomainRemapMiddleware(object):
new_path_parts.append(path) new_path_parts.append(path)
new_path = '/'.join(new_path_parts) new_path = '/'.join(new_path_parts)
env['PATH_INFO'] = new_path env['PATH_INFO'] = new_path
context = _DomainRemapContext(self.app, requested_path, new_path)
return context.handle_request(env, start_response)
return self.app(env, start_response) return self.app(env, start_response)

View File

@ -27,13 +27,21 @@ else: # executed if the try has no errors
skip = False skip = False
from swift.common import utils from swift.common import utils
from swift.common.middleware import cname_lookup from swift.common.middleware import cname_lookup
from swift.common.swob import Request from swift.common.swob import Request, HTTPMovedPermanently
class FakeApp(object): class FakeApp(object):
def __call__(self, env, start_response): def __call__(self, env, start_response):
return "FAKE APP" start_response('200 OK', [])
return ["FAKE APP"]
class RedirectSlashApp(object):
def __call__(self, env, start_response):
loc = env['PATH_INFO'] + '/'
return HTTPMovedPermanently(location=loc)(env, start_response)
def start_response(*args): def start_response(*args):
@ -52,12 +60,12 @@ class TestCNAMELookup(unittest.TestCase):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': '10.134.23.198'}) headers={'Host': '10.134.23.198'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'fc00:7ea1:f155::6321:8841'}) headers={'Host': 'fc00:7ea1:f155::6321:8841'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
@mock.patch('swift.common.middleware.cname_lookup.lookup_cname', @mock.patch('swift.common.middleware.cname_lookup.lookup_cname',
new=lambda d: (0, d)) new=lambda d: (0, d))
@ -65,16 +73,16 @@ class TestCNAMELookup(unittest.TestCase):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'foo.example.com'}) headers={'Host': 'foo.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'foo.example.com:8080'}) headers={'Host': 'foo.example.com:8080'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET', req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
'SERVER_NAME': 'foo.example.com'}, 'SERVER_NAME': 'foo.example.com'},
headers={'Host': None}) headers={'Host': None})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
@mock.patch('swift.common.middleware.cname_lookup.lookup_cname', @mock.patch('swift.common.middleware.cname_lookup.lookup_cname',
new=lambda d: (0, '%s.example.com' % d)) new=lambda d: (0, '%s.example.com' % d))
@ -82,16 +90,16 @@ class TestCNAMELookup(unittest.TestCase):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'mysite.com'}) headers={'Host': 'mysite.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'mysite.com:8080'}) headers={'Host': 'mysite.com:8080'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET', req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
'SERVER_NAME': 'mysite.com'}, 'SERVER_NAME': 'mysite.com'},
headers={'Host': None}) headers={'Host': None})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
def test_lookup_chain_too_long(self): def test_lookup_chain_too_long(self):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
@ -146,12 +154,12 @@ class TestCNAMELookup(unittest.TestCase):
'swift.cache': memcache}, 'swift.cache': memcache},
headers={'Host': 'mysite.com'}) headers={'Host': 'mysite.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET', req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
'swift.cache': memcache}, 'swift.cache': memcache},
headers={'Host': 'mysite.com'}) headers={'Host': 'mysite.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
def test_caching(self): def test_caching(self):
fail_to_resolve = ['CNAME lookup failed to resolve to a valid domain'] fail_to_resolve = ['CNAME lookup failed to resolve to a valid domain']
@ -176,7 +184,7 @@ class TestCNAMELookup(unittest.TestCase):
'swift.cache': memcache}, 'swift.cache': memcache},
headers={'Host': 'mysite2.com'}) headers={'Host': 'mysite2.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
self.assertEqual(m.call_count, 1) self.assertEqual(m.call_count, 1)
self.assertEqual(memcache.cache.get('cname-mysite2.com'), self.assertEqual(memcache.cache.get('cname-mysite2.com'),
'c.example.com') 'c.example.com')
@ -184,7 +192,7 @@ class TestCNAMELookup(unittest.TestCase):
'swift.cache': memcache}, 'swift.cache': memcache},
headers={'Host': 'mysite2.com'}) headers={'Host': 'mysite2.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
self.assertEqual(m.call_count, 1) self.assertEqual(m.call_count, 1)
self.assertEqual(memcache.cache.get('cname-mysite2.com'), self.assertEqual(memcache.cache.get('cname-mysite2.com'),
'c.example.com') 'c.example.com')
@ -245,7 +253,7 @@ class TestCNAMELookup(unittest.TestCase):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.a.example.com'}) headers={'Host': 'c.a.example.com'})
resp = app(req.environ, start_response) resp = app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
def test_storage_domains_conf_format(self): def test_storage_domains_conf_format(self):
conf = {'storage_domain': 'foo.com'} conf = {'storage_domain': 'foo.com'}
@ -281,10 +289,10 @@ class TestCNAMELookup(unittest.TestCase):
return app(req.environ, start_response) return app(req.environ, start_response)
resp = do_test('c.storage1.com') resp = do_test('c.storage1.com')
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
resp = do_test('c.storage2.com') resp = do_test('c.storage2.com')
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
bad_domain = ['CNAME lookup failed to resolve to a valid domain'] bad_domain = ['CNAME lookup failed to resolve to a valid domain']
resp = do_test('c.badtest.com') resp = do_test('c.badtest.com')
@ -305,7 +313,7 @@ class TestCNAMELookup(unittest.TestCase):
self.assertEqual(resp, bad_domain) self.assertEqual(resp, bad_domain)
resp = do_test('storage.example.com') resp = do_test('storage.example.com')
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
def test_resolution_to_storage_domain_exactly(self): def test_resolution_to_storage_domain_exactly(self):
conf = {'storage_domain': 'example.com', conf = {'storage_domain': 'example.com',
@ -317,7 +325,19 @@ class TestCNAMELookup(unittest.TestCase):
module = 'swift.common.middleware.cname_lookup.lookup_cname' module = 'swift.common.middleware.cname_lookup.lookup_cname'
with mock.patch(module, lambda x: (0, 'example.com')): with mock.patch(module, lambda x: (0, 'example.com')):
resp = app(req.environ, start_response) resp = app(req.environ, start_response)
self.assertEqual(resp, 'FAKE APP') self.assertEqual(resp, ['FAKE APP'])
def test_redirect(self):
app = cname_lookup.CNAMELookupMiddleware(RedirectSlashApp(), {})
module = 'swift.common.middleware.cname_lookup.lookup_cname'
with mock.patch(module, lambda x: (0, 'cont.acct.example.com')):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'mysite.com'})
resp = req.get_response(app)
self.assertEqual(resp.status_int, 301)
self.assertEqual(resp.headers.get('Location'),
'http://mysite.com/test/')
class TestSwiftInfo(unittest.TestCase): class TestSwiftInfo(unittest.TestCase):

View File

@ -15,7 +15,7 @@
import unittest import unittest
from swift.common.swob import Request from swift.common.swob import Request, HTTPMovedPermanently
from swift.common.middleware import domain_remap from swift.common.middleware import domain_remap
from swift.common import utils from swift.common import utils
@ -23,7 +23,15 @@ from swift.common import utils
class FakeApp(object): class FakeApp(object):
def __call__(self, env, start_response): def __call__(self, env, start_response):
return env['PATH_INFO'] start_response('200 OK', [])
return [env['PATH_INFO']]
class RedirectSlashApp(object):
def __call__(self, env, start_response):
loc = env['PATH_INFO'] + '/'
return HTTPMovedPermanently(location=loc)(env, start_response)
def start_response(*args): def start_response(*args):
@ -40,36 +48,36 @@ class TestDomainRemap(unittest.TestCase):
'SERVER_NAME': 'example.com'}, 'SERVER_NAME': 'example.com'},
headers={'Host': None}) headers={'Host': None})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/') self.assertEqual(resp, ['/'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'example.com'}) headers={'Host': 'example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/') self.assertEqual(resp, ['/'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'example.com:8080'}) headers={'Host': 'example.com:8080'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/') self.assertEqual(resp, ['/'])
def test_domain_remap_account(self): def test_domain_remap_account(self):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET', req = Request.blank('/', environ={'REQUEST_METHOD': 'GET',
'SERVER_NAME': 'AUTH_a.example.com'}, 'SERVER_NAME': 'AUTH_a.example.com'},
headers={'Host': None}) headers={'Host': None})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/') self.assertEqual(resp, ['/v1/AUTH_a/'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'AUTH_a.example.com'}) headers={'Host': 'AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/') self.assertEqual(resp, ['/v1/AUTH_a/'])
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'AUTH-uuid.example.com'}) headers={'Host': 'AUTH-uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_uuid/') self.assertEqual(resp, ['/v1/AUTH_uuid/'])
def test_domain_remap_account_container(self): def test_domain_remap_account_container(self):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c/') self.assertEqual(resp, ['/v1/AUTH_a/c/'])
def test_domain_remap_extra_subdomains(self): def test_domain_remap_extra_subdomains(self):
req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'},
@ -81,13 +89,13 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'AUTH_a.example.com'}) headers={'Host': 'AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/') self.assertEqual(resp, ['/v1/AUTH_a/'])
def test_domain_remap_account_container_with_path_root(self): def test_domain_remap_account_container_with_path_root(self):
req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c/') self.assertEqual(resp, ['/v1/AUTH_a/c/'])
def test_domain_remap_account_container_with_path_obj_slash_v1(self): def test_domain_remap_account_container_with_path_obj_slash_v1(self):
# Include http://localhost because urlparse used in Request.__init__ # Include http://localhost because urlparse used in Request.__init__
@ -96,38 +104,38 @@ class TestDomainRemap(unittest.TestCase):
environ={'REQUEST_METHOD': 'GET'}, environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c//v1') self.assertEqual(resp, ['/v1/AUTH_a/c//v1'])
def test_domain_remap_account_container_with_root_path_obj_slash_v1(self): def test_domain_remap_account_container_with_root_path_obj_slash_v1(self):
req = Request.blank('/v1//v1', req = Request.blank('/v1//v1',
environ={'REQUEST_METHOD': 'GET'}, environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c//v1') self.assertEqual(resp, ['/v1/AUTH_a/c//v1'])
def test_domain_remap_account_container_with_path_trailing_slash(self): def test_domain_remap_account_container_with_path_trailing_slash(self):
req = Request.blank('/obj/', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/obj/', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c/obj/') self.assertEqual(resp, ['/v1/AUTH_a/c/obj/'])
def test_domain_remap_account_container_with_path(self): def test_domain_remap_account_container_with_path(self):
req = Request.blank('/obj', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/obj', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c/obj') self.assertEqual(resp, ['/v1/AUTH_a/c/obj'])
def test_domain_remap_account_container_with_path_root_and_path(self): def test_domain_remap_account_container_with_path_root_and_path(self):
req = Request.blank('/v1/obj', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/v1/obj', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_a/c/obj') self.assertEqual(resp, ['/v1/AUTH_a/c/obj'])
def test_domain_remap_account_matching_ending_not_domain(self): def test_domain_remap_account_matching_ending_not_domain(self):
req = Request.blank('/dontchange', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/dontchange', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.aexample.com'}) headers={'Host': 'c.aexample.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/dontchange') self.assertEqual(resp, ['/dontchange'])
def test_domain_remap_configured_with_empty_storage_domain(self): def test_domain_remap_configured_with_empty_storage_domain(self):
self.app = domain_remap.DomainRemapMiddleware(FakeApp(), self.app = domain_remap.DomainRemapMiddleware(FakeApp(),
@ -135,7 +143,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.AUTH_a.example.com'}) headers={'Host': 'c.AUTH_a.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/test') self.assertEqual(resp, ['/test'])
def test_storage_domains_conf_format(self): def test_storage_domains_conf_format(self):
conf = {'storage_domain': 'foo.com'} conf = {'storage_domain': 'foo.com'}
@ -164,7 +172,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.prefix_uuid.example.com'}) headers={'Host': 'c.prefix_uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/PREFIX_uuid/c/test') self.assertEqual(resp, ['/v1/PREFIX_uuid/c/test'])
def test_domain_remap_configured_with_bad_prefixes(self): def test_domain_remap_configured_with_bad_prefixes(self):
conf = {'reseller_prefixes': 'UNKNOWN'} conf = {'reseller_prefixes': 'UNKNOWN'}
@ -172,7 +180,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.prefix_uuid.example.com'}) headers={'Host': 'c.prefix_uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/test') self.assertEqual(resp, ['/test'])
def test_domain_remap_configured_with_no_prefixes(self): def test_domain_remap_configured_with_no_prefixes(self):
conf = {'reseller_prefixes': ''} conf = {'reseller_prefixes': ''}
@ -180,7 +188,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'c.uuid.example.com'}) headers={'Host': 'c.uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/uuid/c/test') self.assertEqual(resp, ['/v1/uuid/c/test'])
def test_domain_remap_add_prefix(self): def test_domain_remap_add_prefix(self):
conf = {'default_reseller_prefix': 'FOO'} conf = {'default_reseller_prefix': 'FOO'}
@ -188,7 +196,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'uuid.example.com'}) headers={'Host': 'uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/FOO_uuid/test') self.assertEqual(resp, ['/v1/FOO_uuid/test'])
def test_domain_remap_add_prefix_already_there(self): def test_domain_remap_add_prefix_already_there(self):
conf = {'default_reseller_prefix': 'AUTH'} conf = {'default_reseller_prefix': 'AUTH'}
@ -196,7 +204,7 @@ class TestDomainRemap(unittest.TestCase):
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'auth-uuid.example.com'}) headers={'Host': 'auth-uuid.example.com'})
resp = self.app(req.environ, start_response) resp = self.app(req.environ, start_response)
self.assertEqual(resp, '/v1/AUTH_uuid/test') self.assertEqual(resp, ['/v1/AUTH_uuid/test'])
def test_multiple_storage_domains(self): def test_multiple_storage_domains(self):
conf = {'storage_domain': 'storage1.com, storage2.com'} conf = {'storage_domain': 'storage1.com, storage2.com'}
@ -208,13 +216,37 @@ class TestDomainRemap(unittest.TestCase):
return self.app(req.environ, start_response) return self.app(req.environ, start_response)
resp = do_test('auth-uuid.storage1.com') resp = do_test('auth-uuid.storage1.com')
self.assertEqual(resp, '/v1/AUTH_uuid/test') self.assertEqual(resp, ['/v1/AUTH_uuid/test'])
resp = do_test('auth-uuid.storage2.com') resp = do_test('auth-uuid.storage2.com')
self.assertEqual(resp, '/v1/AUTH_uuid/test') self.assertEqual(resp, ['/v1/AUTH_uuid/test'])
resp = do_test('auth-uuid.storage3.com') resp = do_test('auth-uuid.storage3.com')
self.assertEqual(resp, '/test') self.assertEqual(resp, ['/test'])
def test_domain_remap_redirect(self):
app = domain_remap.DomainRemapMiddleware(RedirectSlashApp(), {})
req = Request.blank('/cont', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'auth-uuid.example.com'})
resp = req.get_response(app)
self.assertEqual(resp.status_int, 301)
self.assertEqual(resp.headers.get('Location'),
'http://auth-uuid.example.com/cont/')
req = Request.blank('/cont/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'auth-uuid.example.com'})
resp = req.get_response(app)
self.assertEqual(resp.status_int, 301)
self.assertEqual(resp.headers.get('Location'),
'http://auth-uuid.example.com/cont/test/')
req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'},
headers={'Host': 'cont.auth-uuid.example.com'})
resp = req.get_response(app)
self.assertEqual(resp.status_int, 301)
self.assertEqual(resp.headers.get('Location'),
'http://cont.auth-uuid.example.com/test/')
class TestSwiftInfo(unittest.TestCase): class TestSwiftInfo(unittest.TestCase):