summaryrefslogtreecommitdiff
path: root/paste/cascade.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2005-08-15 19:03:21 +0000
committerianb <devnull@localhost>2005-08-15 19:03:21 +0000
commit32574051da2c706f9d29780b72f42b8fb5a2302e (patch)
treec2b6df959ebc430dc26a9f9ac67873c9c7f35903 /paste/cascade.py
parent89969c0846de7cacac621938797bea4cac5663ac (diff)
downloadpaste-32574051da2c706f9d29780b72f42b8fb5a2302e.tar.gz
Dispatcher to try multiple applications until 404 not given
Diffstat (limited to 'paste/cascade.py')
-rw-r--r--paste/cascade.py50
1 files changed, 50 insertions, 0 deletions
diff --git a/paste/cascade.py b/paste/cascade.py
new file mode 100644
index 0000000..300d787
--- /dev/null
+++ b/paste/cascade.py
@@ -0,0 +1,50 @@
+"""
+Cascades through several applications, so long as applications
+return ``404 Not Found``.
+"""
+import httpexceptions
+
+__all__ = ['Cascade']
+
+class Cascade(object):
+
+ """
+ Passed a list of applications, ``Cascade`` will try each of them
+ in turn. If one returns a status code listed in ``catch`` (by
+ default just ``404 Not Found``) then the next application is
+ tried.
+
+ If all applications fail, then the last application's failure
+ response is used.
+ """
+
+ def __init__(self, applications, catch=(404,)):
+ self.apps = applications
+ self.catch_codes = {}
+ self.catch_exceptions = []
+ for error in catch:
+ if isinstance(error, str):
+ error = int(error.split(None, 1))
+ if isinstance(error, httpexceptions.HTTPException):
+ exc = error
+ code = error.code
+ else:
+ exc = httpexceptions.get_exception(error)
+ code = error
+ self.catch_codes[code] = exc
+ self.catch_exceptions.append(exc)
+ self.catch_exceptions = tuple(self.catch_exceptions)
+
+ def __call__(self, environ, start_response):
+ def repl_start_response(status, headers, exc_info=None):
+ code = int(status.split(None, 1)[0])
+ if code in self.catch_codes:
+ raise self.catch_codes[code]
+ return start_response(status, headers, exc_info)
+
+ for app in self.apps[:-1]:
+ try:
+ return app(environ, repl_start_response)
+ except self.catch_exceptions:
+ pass
+ return self.apps[-1](environ, start_response)