diff options
author | ianb <devnull@localhost> | 2006-03-02 17:23:05 +0000 |
---|---|---|
committer | ianb <devnull@localhost> | 2006-03-02 17:23:05 +0000 |
commit | 03d701577e629f2533d5d29654292e3e755d321b (patch) | |
tree | 8f1500cbefb4ef0a62e701a84d4aef43bf13040c /paste/recursive.py | |
parent | e61081c16e95cd2e4374db4cf34b836f3aba90fa (diff) | |
download | paste-03d701577e629f2533d5d29654292e3e755d321b.tar.gz |
Added a newer/more sane way of doing forwarding, instead of the wonky callback stuff (which is now deprecated with a warning)
Diffstat (limited to 'paste/recursive.py')
-rw-r--r-- | paste/recursive.py | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/paste/recursive.py b/paste/recursive.py index 2cc6f8a..e0623f8 100644 --- a/paste/recursive.py +++ b/paste/recursive.py @@ -2,6 +2,24 @@ # Licensed under the MIT license: http://www.opensource.org/licenses/mit-license.php """ Middleware to make internal requests and forward requests internally. + +When applied, several keys are added to the environment that will allow +you to trigger recursive redirects and forwards. + +``paste.recursive.include``: + When you call ``environ['paste.recursive.include'](new_path_info)`` + a response will be returned. The response has a ``body`` attribute, + a ``status`` attribute, and a ``headers`` attribute. + +``paste.recursive.script_name``: + The ``SCRIPT_NAME`` at the point that recursive lives. Only paths + underneath this path can be redirected to. + +``paste.recursive.old_path_info``: + A list of previous ``PATH_INFO`` values from previous redirects. + +Raise ``ForewardRequestException(new_path_info)`` to do a forward +(aborting the current request). """ from cStringIO import StringIO @@ -28,7 +46,33 @@ class RecursiveMiddleware(object): self.application, environ, start_response) environ['paste.recursive.include'] = Includer( self.application, environ, start_response) - return self.application(environ, start_response) + my_script_name = environ.get('SCRIPT_NAME', '') + current_path_info = environ.get('PATH_INFO', '') + environ['paste.recursive.script_name'] = my_script_name + try: + return self.application(environ, start_response) + except ForwardRequestException, e: + if e.path_info in environ.get( + 'paste.recursive.old_path_info', []): + raise AssertionError( + "Forwarding loop detected; %r visited twice (internal " + "redirect path: %s)" + % (e.path_info, environ['paste.recursive.old_path_info'])) + environ.setdefault('paste.recursive.old_path_info', []).append(current_path_info) + environ['SCRIPT_NAME'] = my_script_name + environ['PATH_INFO'] = e.path_info + return self(environ, start_response) + +class ForwardRequestException(Exception): + + """ + Used to signal that a request should be forwarded to a different location. + The ``path_info`` attribute (passed in as an argument to the constructor) + is the position under the recursive middleware to redirect to. + """ + + def __init__(self, path_info): + self.path_info = path_info class Recursive(object): @@ -82,6 +126,13 @@ class Forwarder(Recursive): rewritten. """ + def __init__(self, *args, **kw): + warnings.warn( + "recursive.Forwarder has been deprecated; please use " + "ForwardRequestException", + DeprecationWarning, 2) + Recursive.__init__(self, *args, **kw) + def activate(self, environ): return self.application(environ, self.start_response) |