Index: third_party/Paste/paste/urlmap.py.orig |
diff --git a/third_party/Paste/paste/urlmap.py.orig b/third_party/Paste/paste/urlmap.py.orig |
deleted file mode 100644 |
index f721f2d846051c7aa457b3b1b26f7643c7d67fa0..0000000000000000000000000000000000000000 |
--- a/third_party/Paste/paste/urlmap.py.orig |
+++ /dev/null |
@@ -1,263 +0,0 @@ |
-# (c) 2005 Ian Bicking and contributors; written for Paste (http://pythonpaste.org) |
-# Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php |
-""" |
-Map URL prefixes to WSGI applications. See ``URLMap`` |
-""" |
- |
-import re |
-import os |
-import cgi |
-try: |
- # Python 3 |
- from collections import MutableMapping as DictMixin |
-except ImportError: |
- # Python 2 |
- from UserDict import DictMixin |
- |
-from paste import httpexceptions |
- |
-__all__ = ['URLMap', 'PathProxyURLMap'] |
- |
-def urlmap_factory(loader, global_conf, **local_conf): |
- if 'not_found_app' in local_conf: |
- not_found_app = local_conf.pop('not_found_app') |
- else: |
- not_found_app = global_conf.get('not_found_app') |
- if not_found_app: |
- not_found_app = loader.get_app(not_found_app, global_conf=global_conf) |
- urlmap = URLMap(not_found_app=not_found_app) |
- for path, app_name in local_conf.items(): |
- path = parse_path_expression(path) |
- app = loader.get_app(app_name, global_conf=global_conf) |
- urlmap[path] = app |
- return urlmap |
- |
-def parse_path_expression(path): |
- """ |
- Parses a path expression like 'domain foobar.com port 20 /' or |
- just '/foobar' for a path alone. Returns as an address that |
- URLMap likes. |
- """ |
- parts = path.split() |
- domain = port = path = None |
- while parts: |
- if parts[0] == 'domain': |
- parts.pop(0) |
- if not parts: |
- raise ValueError("'domain' must be followed with a domain name") |
- if domain: |
- raise ValueError("'domain' given twice") |
- domain = parts.pop(0) |
- elif parts[0] == 'port': |
- parts.pop(0) |
- if not parts: |
- raise ValueError("'port' must be followed with a port number") |
- if port: |
- raise ValueError("'port' given twice") |
- port = parts.pop(0) |
- else: |
- if path: |
- raise ValueError("more than one path given (have %r, got %r)" |
- % (path, parts[0])) |
- path = parts.pop(0) |
- s = '' |
- if domain: |
- s = 'http://%s' % domain |
- if port: |
- if not domain: |
- raise ValueError("If you give a port, you must also give a domain") |
- s += ':' + port |
- if path: |
- if s: |
- s += '/' |
- s += path |
- return s |
- |
-class URLMap(DictMixin): |
- |
- """ |
- URLMap instances are dictionary-like object that dispatch to one |
- of several applications based on the URL. |
- |
- The dictionary keys are URLs to match (like |
- ``PATH_INFO.startswith(url)``), and the values are applications to |
- dispatch to. URLs are matched most-specific-first, i.e., longest |
- URL first. The ``SCRIPT_NAME`` and ``PATH_INFO`` environmental |
- variables are adjusted to indicate the new context. |
- |
- URLs can also include domains, like ``http://blah.com/foo``, or as |
- tuples ``('blah.com', '/foo')``. This will match domain names; without |
- the ``http://domain`` or with a domain of ``None`` any domain will be |
- matched (so long as no other explicit domain matches). """ |
- |
- def __init__(self, not_found_app=None): |
- self.applications = [] |
- if not not_found_app: |
- not_found_app = self.not_found_app |
- self.not_found_application = not_found_app |
- |
- def __len__(self): |
- return len(self.applications) |
- |
- def __iter__(self): |
- for app_url, app in self.applications: |
- yield app_url |
- |
- norm_url_re = re.compile('//+') |
- domain_url_re = re.compile('^(http|https)://') |
- |
- def not_found_app(self, environ, start_response): |
- mapper = environ.get('paste.urlmap_object') |
- if mapper: |
- matches = [p for p, a in mapper.applications] |
- extra = 'defined apps: %s' % ( |
- ',\n '.join(map(repr, matches))) |
- else: |
- extra = '' |
- extra += '\nSCRIPT_NAME: %r' % cgi.escape(environ.get('SCRIPT_NAME')) |
- extra += '\nPATH_INFO: %r' % cgi.escape(environ.get('PATH_INFO')) |
- extra += '\nHTTP_HOST: %r' % cgi.escape(environ.get('HTTP_HOST')) |
- app = httpexceptions.HTTPNotFound( |
- environ['PATH_INFO'], |
- comment=cgi.escape(extra)).wsgi_application |
- return app(environ, start_response) |
- |
- def normalize_url(self, url, trim=True): |
- if isinstance(url, (list, tuple)): |
- domain = url[0] |
- url = self.normalize_url(url[1])[1] |
- return domain, url |
- assert (not url or url.startswith('/') |
- or self.domain_url_re.search(url)), ( |
- "URL fragments must start with / or http:// (you gave %r)" % url) |
- match = self.domain_url_re.search(url) |
- if match: |
- url = url[match.end():] |
- if '/' in url: |
- domain, url = url.split('/', 1) |
- url = '/' + url |
- else: |
- domain, url = url, '' |
- else: |
- domain = None |
- url = self.norm_url_re.sub('/', url) |
- if trim: |
- url = url.rstrip('/') |
- return domain, url |
- |
- def sort_apps(self): |
- """ |
- Make sure applications are sorted with longest URLs first |
- """ |
- def key(app_desc): |
- (domain, url), app = app_desc |
- if not domain: |
- # Make sure empty domains sort last: |
- return '\xff', -len(url) |
- else: |
- return domain, -len(url) |
- apps = [(key(desc), desc) for desc in self.applications] |
- apps.sort() |
- self.applications = [desc for (sortable, desc) in apps] |
- |
- def __setitem__(self, url, app): |
- if app is None: |
- try: |
- del self[url] |
- except KeyError: |
- pass |
- return |
- dom_url = self.normalize_url(url) |
- if dom_url in self: |
- del self[dom_url] |
- self.applications.append((dom_url, app)) |
- self.sort_apps() |
- |
- def __getitem__(self, url): |
- dom_url = self.normalize_url(url) |
- for app_url, app in self.applications: |
- if app_url == dom_url: |
- return app |
- raise KeyError( |
- "No application with the url %r (domain: %r; existing: %s)" |
- % (url[1], url[0] or '*', self.applications)) |
- |
- def __delitem__(self, url): |
- url = self.normalize_url(url) |
- for app_url, app in self.applications: |
- if app_url == url: |
- self.applications.remove((app_url, app)) |
- break |
- else: |
- raise KeyError( |
- "No application with the url %r" % (url,)) |
- |
- def keys(self): |
- return [app_url for app_url, app in self.applications] |
- |
- def __call__(self, environ, start_response): |
- host = environ.get('HTTP_HOST', environ.get('SERVER_NAME')).lower() |
- if ':' in host: |
- host, port = host.split(':', 1) |
- else: |
- if environ['wsgi.url_scheme'] == 'http': |
- port = '80' |
- else: |
- port = '443' |
- path_info = environ.get('PATH_INFO') |
- path_info = self.normalize_url(path_info, False)[1] |
- for (domain, app_url), app in self.applications: |
- if domain and domain != host and domain != host+':'+port: |
- continue |
- if (path_info == app_url |
- or path_info.startswith(app_url + '/')): |
- environ['SCRIPT_NAME'] += app_url |
- environ['PATH_INFO'] = path_info[len(app_url):] |
- return app(environ, start_response) |
- environ['paste.urlmap_object'] = self |
- return self.not_found_application(environ, start_response) |
- |
- |
-class PathProxyURLMap(object): |
- |
- """ |
- This is a wrapper for URLMap that catches any strings that |
- are passed in as applications; these strings are treated as |
- filenames (relative to `base_path`) and are passed to the |
- callable `builder`, which will return an application. |
- |
- This is intended for cases when configuration files can be |
- treated as applications. |
- |
- `base_paste_url` is the URL under which all applications added through |
- this wrapper must go. Use ``""`` if you want this to not |
- change incoming URLs. |
- """ |
- |
- def __init__(self, map, base_paste_url, base_path, builder): |
- self.map = map |
- self.base_paste_url = self.map.normalize_url(base_paste_url) |
- self.base_path = base_path |
- self.builder = builder |
- |
- def __setitem__(self, url, app): |
- if isinstance(app, (str, unicode)): |
- app_fn = os.path.join(self.base_path, app) |
- app = self.builder(app_fn) |
- url = self.map.normalize_url(url) |
- # @@: This means http://foo.com/bar will potentially |
- # match foo.com, but /base_paste_url/bar, which is unintuitive |
- url = (url[0] or self.base_paste_url[0], |
- self.base_paste_url[1] + url[1]) |
- self.map[url] = app |
- |
- def __getattr__(self, attr): |
- return getattr(self.map, attr) |
- |
- # This is really the only settable attribute |
- def not_found_application__get(self): |
- return self.map.not_found_application |
- def not_found_application__set(self, value): |
- self.map.not_found_application = value |
- not_found_application = property(not_found_application__get, |
- not_found_application__set) |