From edf263702653e085625d88139797e54b53022582 Mon Sep 17 00:00:00 2001 From: John Dickinson Date: Sat, 31 Mar 2012 10:18:44 -0500 Subject: [PATCH] updated docs for domain remap and cname lookup middleware Change-Id: I1c571951f25a6e724cdd4699eb94baad5e47eb95 --- doc/source/misc.rst | 14 ++++ swift/common/middleware/cname_lookup.py | 39 +++++++++-- swift/common/middleware/domain_remap.py | 69 +++++++++++-------- .../common/middleware/test_cname_lookup.py | 6 +- 4 files changed, 92 insertions(+), 36 deletions(-) diff --git a/doc/source/misc.rst b/doc/source/misc.rst index 81d8878aac..8a3d3f2405 100644 --- a/doc/source/misc.rst +++ b/doc/source/misc.rst @@ -157,3 +157,17 @@ FormPost .. automodule:: swift.common.middleware.formpost :members: :show-inheritance: + +Domain Remap +============ + +.. automodule:: swift.common.middleware.domain_remap + :members: + :show-inheritance: + +CNAME Lookup +============ + +.. automodule:: swift.common.middleware.cname_lookup + :members: + :show-inheritance: diff --git a/swift/common/middleware/cname_lookup.py b/swift/common/middleware/cname_lookup.py index b58369b281..eafdd3a4ce 100644 --- a/swift/common/middleware/cname_lookup.py +++ b/swift/common/middleware/cname_lookup.py @@ -13,11 +13,31 @@ # See the License for the specific language governing permissions and # limitations under the License. + +""" +CNAME Lookup Middleware + +Middleware that translates an unknown domain in the host header to +something that ends with the configured storage_domain by looking up +the given domain's CNAME record in DNS. + +This middleware will continue to follow a CNAME chain in DNS until it finds +a record ending in the configured storage domain or it reaches the configured +maximum lookup depth. If a match is found, the environment's Host header is +rewritten and the request is passed further down the WSGI chain. +""" + from webob import Request from webob.exc import HTTPBadRequest -import dns.resolver -from dns.exception import DNSException -from dns.resolver import NXDOMAIN, NoAnswer +try: + import dns.resolver + from dns.exception import DNSException + from dns.resolver import NXDOMAIN, NoAnswer +except ImportError: + # catch this to allow docs to be built without the dependency + MODULE_DEPENDENCY_MET = False +else: # executed if the try block finishes with no errors + MODULE_DEPENDENCY_MET = True from swift.common.utils import cache_from_env, get_logger @@ -41,12 +61,19 @@ def lookup_cname(domain): # pragma: no cover class CNAMELookupMiddleware(object): """ - Middleware that translates a unknown domain in the host header to - something that ends with the configured storage_domain by looking up - the given domain's CNAME record in DNS. + CNAME Lookup 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): + if not MODULE_DEPENDENCY_MET: + # reraise the exception if the dependency wasn't met + raise ImportError('dnspython is required for this module') self.app = app self.storage_domain = conf.get('storage_domain', 'example.com') if self.storage_domain and self.storage_domain[0] != '.': diff --git a/swift/common/middleware/domain_remap.py b/swift/common/middleware/domain_remap.py index c23e2f2b29..a1cc3016be 100644 --- a/swift/common/middleware/domain_remap.py +++ b/swift/common/middleware/domain_remap.py @@ -13,42 +13,55 @@ # 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): """ - Middleware that translates container and account parts of a domain to - path parameters that the proxy server understands. + Domain Remap Middleware - container.account.storageurl/object gets translated to - container.account.storageurl/path_root/account/container/object + See above for a full description. - 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. + :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): diff --git a/test/unit/common/middleware/test_cname_lookup.py b/test/unit/common/middleware/test_cname_lookup.py index 1cb3df04a8..12ab7ad1f1 100644 --- a/test/unit/common/middleware/test_cname_lookup.py +++ b/test/unit/common/middleware/test_cname_lookup.py @@ -20,10 +20,12 @@ from webob import Request try: # this test requires the dnspython package to be installed - from swift.common.middleware import cname_lookup - skip = False + import dns.resolver except ImportError: skip = True +else: # executed if the try has no errors + skip = False +from swift.common.middleware import cname_lookup class FakeApp(object):