summaryrefslogtreecommitdiff
path: root/paste/recursive.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2006-03-02 17:23:05 +0000
committerianb <devnull@localhost>2006-03-02 17:23:05 +0000
commit03d701577e629f2533d5d29654292e3e755d321b (patch)
tree8f1500cbefb4ef0a62e701a84d4aef43bf13040c /paste/recursive.py
parente61081c16e95cd2e4374db4cf34b836f3aba90fa (diff)
downloadpaste-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.py53
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)