diff options
author | ianb <devnull@localhost> | 2005-08-15 19:03:21 +0000 |
---|---|---|
committer | ianb <devnull@localhost> | 2005-08-15 19:03:21 +0000 |
commit | 32574051da2c706f9d29780b72f42b8fb5a2302e (patch) | |
tree | c2b6df959ebc430dc26a9f9ac67873c9c7f35903 /paste/cascade.py | |
parent | 89969c0846de7cacac621938797bea4cac5663ac (diff) | |
download | paste-32574051da2c706f9d29780b72f42b8fb5a2302e.tar.gz |
Dispatcher to try multiple applications until 404 not given
Diffstat (limited to 'paste/cascade.py')
-rw-r--r-- | paste/cascade.py | 50 |
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) |