diff --git a/doc/manpages/proxy-server.conf.5 b/doc/manpages/proxy-server.conf.5 index 9ab793dbc7..85593e6f60 100644 --- a/doc/manpages/proxy-server.conf.5 +++ b/doc/manpages/proxy-server.conf.5 @@ -256,40 +256,6 @@ to r. Will limit PUT, DELETE, and POST requests to /a/c/o. The default is ''. -.RS 0 -.IP "\fB[filter:domain_remap]\fR" -.RE - -Middleware that translates container and account parts of a domain to path parameters that the proxy server understands. The container.account.storageurl/object gets translated to container.account.storageurl/path_root/account/container/object and account.storageurl/path_root/container/object gets translated to account.storageurl/path_root/account/container/object - -.RS 3 -.IP \fBuse\fR -Entry point for paste.deploy for the domain_remap middleware. This is the reference to the installed python egg. -The default is \fBegg:swift#domain_remap\fR. -.IP "\fBset log_name\fR" -Label used when logging. The default is domain_remap. -.IP "\fBset log_facility\fR" -Syslog log facility. The default is LOG_LOCAL0. -.IP "\fBset log_level\fR " -Logging level. The default is INFO. -.IP "\fBset log_headers\fR" -Enables the ability to log request headers. The default is False. -.IP \fBstorage_domain\fR -The domain to be used by the middleware. -.IP \fBpath_root\fR -The path root value for the storage URL. The default is v1. -.IP \fBreseller_prefixes\fR -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'. -.RE - - - .RS 0 .IP "\fB[filter:catch_errors]\fR" .RE diff --git a/doc/source/associated_projects.rst b/doc/source/associated_projects.rst index 3e526e9b65..b00d8ce7b7 100644 --- a/doc/source/associated_projects.rst +++ b/doc/source/associated_projects.rst @@ -55,3 +55,4 @@ Other * `Glance `_ - Provides services for discovering, registering, and retrieving virtual machine images (for OpenStack Compute [Nova], for example). * `StaticWeb `_ - Allows serving static websites from Swift containers using ACLs and other metadata on those containers. * `TempURL/FormPOST `_ - Temporary, Expiring URLs and Form POSTing middleware. +* `Domain Remap `_ - Translates subdomains on the Host header to path elements that are appropriate for swift. diff --git a/doc/source/misc.rst b/doc/source/misc.rst index 039b00831e..9c4a7a1fac 100644 --- a/doc/source/misc.rst +++ b/doc/source/misc.rst @@ -147,13 +147,6 @@ Swift3 :members: :show-inheritance: -Domain Remap -============ - -.. automodule:: swift.common.middleware.domain_remap - :members: - :show-inheritance: - CNAME Lookup ============ diff --git a/etc/proxy-server.conf-sample b/etc/proxy-server.conf-sample index aca205df76..cedbfa62e1 100644 --- a/etc/proxy-server.conf-sample +++ b/etc/proxy-server.conf-sample @@ -162,17 +162,6 @@ use = egg:swift#ratelimit # container_ratelimit_10 = 50 # container_ratelimit_50 = 20 -[filter:domain_remap] -use = egg:swift#domain_remap -# You can override the default log routing for this filter here: -# set log_name = domain_remap -# set log_facility = LOG_LOCAL0 -# set log_level = INFO -# set log_headers = False -# storage_domain = example.com -# path_root = v1 -# reseller_prefixes = AUTH - [filter:catch_errors] use = egg:swift#catch_errors # You can override the default log routing for this filter here: diff --git a/setup.py b/setup.py index 598233e230..6dc873b191 100644 --- a/setup.py +++ b/setup.py @@ -84,7 +84,6 @@ setup( 'ratelimit=swift.common.middleware.ratelimit:filter_factory', 'cname_lookup=swift.common.middleware.cname_lookup:filter_factory', 'catch_errors=swift.common.middleware.catch_errors:filter_factory', - 'domain_remap=swift.common.middleware.domain_remap:filter_factory', 'swift3=swift.common.middleware.swift3:filter_factory', 'tempauth=swift.common.middleware.tempauth:filter_factory', 'recon=swift.common.middleware.recon:filter_factory', diff --git a/swift/common/middleware/domain_remap.py b/swift/common/middleware/domain_remap.py deleted file mode 100644 index a1cc3016be..0000000000 --- a/swift/common/middleware/domain_remap.py +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright (c) 2010-2012 OpenStack, LLC. -# -# 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. - - -""" -Domain Remap Middleware - -Middleware that translates container and account parts of a domain to -path parameters that the proxy server understands. - -container.account.storageurl/object gets translated to -container.account.storageurl/path_root/account/container/object - -account.storageurl/path_root/container/object gets translated to -account.storageurl/path_root/account/container/object - -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'. - -Note that this middleware requires that container names and account names -(except as described above) must be DNS-compatible. This means that the -account name created in the system and the containers created by users -cannot exceed 63 characters or have UTF-8 characters. These are -restrictions over and above what swift requires and are not explicitly -checked. Simply put, the this middleware will do a best-effort attempt to -derive account and container names from elements in the domain name and -put those derived values into the URL path (leaving the Host header -unchanged). - -Also note that using container sync with remapped domain names is not -advised. With container sync, you should use the true storage end points as -sync destinations. -""" - -from webob import Request -from webob.exc import HTTPBadRequest - - -class DomainRemapMiddleware(object): - """ - Domain Remap Middleware - - See above for a full description. - - :param app: The next WSGI filter or app in the paste.deploy - chain. - :param conf: The configuration dict for the middleware. - """ - - def __init__(self, app, conf): - self.app = app - self.storage_domain = conf.get('storage_domain', 'example.com') - if self.storage_domain and self.storage_domain[0] != '.': - self.storage_domain = '.' + self.storage_domain - self.path_root = conf.get('path_root', 'v1').strip('/') - prefixes = conf.get('reseller_prefixes', 'AUTH') - self.reseller_prefixes = [x.strip() for x in prefixes.split(',') - if x.strip()] - self.reseller_prefixes_lower = [x.lower() - for x in self.reseller_prefixes] - - def __call__(self, env, start_response): - if not self.storage_domain: - return self.app(env, start_response) - given_domain = env['HTTP_HOST'] - port = '' - if ':' in given_domain: - given_domain, port = given_domain.rsplit(':', 1) - if given_domain.endswith(self.storage_domain): - parts_to_parse = given_domain[:-len(self.storage_domain)] - parts_to_parse = parts_to_parse.strip('.').split('.') - len_parts_to_parse = len(parts_to_parse) - if len_parts_to_parse == 2: - container, account = parts_to_parse - elif len_parts_to_parse == 1: - container, account = None, parts_to_parse[0] - else: - resp = HTTPBadRequest(request=Request(env), - body='Bad domain in host header', - content_type='text/plain') - return resp(env, start_response) - 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: - # 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: - new_path_parts.append(container) - if path.startswith(self.path_root): - path = path[len(self.path_root):].lstrip('/') - if path: - new_path_parts.append(path) - new_path = '/'.join(new_path_parts) - env['PATH_INFO'] = new_path - return self.app(env, start_response) - - -def filter_factory(global_conf, **local_conf): - conf = global_conf.copy() - conf.update(local_conf) - - def domain_filter(app): - return DomainRemapMiddleware(app, conf) - return domain_filter diff --git a/test/unit/common/middleware/test_domain_remap.py b/test/unit/common/middleware/test_domain_remap.py deleted file mode 100644 index 7139ad7769..0000000000 --- a/test/unit/common/middleware/test_domain_remap.py +++ /dev/null @@ -1,126 +0,0 @@ -# Copyright (c) 2010-2012 OpenStack, LLC. -# -# 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 unittest - -from webob import Request - -from swift.common.middleware import domain_remap - - -class FakeApp(object): - - def __call__(self, env, start_response): - return env['PATH_INFO'] - - -def start_response(*args): - pass - - -class TestDomainRemap(unittest.TestCase): - - def setUp(self): - self.app = domain_remap.DomainRemapMiddleware(FakeApp(), {}) - - def test_domain_remap_passthrough(self): - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/') - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'example.com:8080'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/') - - def test_domain_remap_account(self): - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a') - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'AUTH-uuid.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_uuid') - - def test_domain_remap_account_container(self): - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a/c') - - def test_domain_remap_extra_subdomains(self): - req = Request.blank('/', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'x.y.c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, ['Bad domain in host header']) - - def test_domain_remap_account_with_path_root(self): - req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a') - - def test_domain_remap_account_container_with_path_root(self): - req = Request.blank('/v1', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a/c') - - def test_domain_remap_account_container_with_path(self): - req = Request.blank('/obj', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a/c/obj') - - def test_domain_remap_account_container_with_path_root_and_path(self): - req = Request.blank('/v1/obj', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/AUTH_a/c/obj') - - def test_domain_remap_account_matching_ending_not_domain(self): - req = Request.blank('/dontchange', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.aexample.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/dontchange') - - def test_domain_remap_configured_with_empty_storage_domain(self): - self.app = domain_remap.DomainRemapMiddleware(FakeApp(), - {'storage_domain': ''}) - req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.AUTH_a.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/test') - - def test_domain_remap_configured_with_prefixes(self): - conf = {'reseller_prefixes': 'PREFIX'} - self.app = domain_remap.DomainRemapMiddleware(FakeApp(), conf) - req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.prefix_uuid.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/v1/PREFIX_uuid/c/test') - - def test_domain_remap_configured_with_bad_prefixes(self): - conf = {'reseller_prefixes': 'UNKNOWN'} - self.app = domain_remap.DomainRemapMiddleware(FakeApp(), conf) - req = Request.blank('/test', environ={'REQUEST_METHOD': 'GET'}, - headers={'Host': 'c.prefix_uuid.example.com'}) - resp = self.app(req.environ, start_response) - self.assertEquals(resp, '/test') - - -if __name__ == '__main__': - unittest.main()