summaryrefslogtreecommitdiff
path: root/paste/errordocument.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2006-07-14 16:43:27 +0000
committerianb <devnull@localhost>2006-07-14 16:43:27 +0000
commit4faed50946111b3f687cba89d5a4ad5d6a11a95e (patch)
tree63f768fd5779745cfc10d12ca2013069ec3d2093 /paste/errordocument.py
parent9acb7d24a7aad19a01c3f03cfb9ea9716b322bdb (diff)
downloadpaste-4faed50946111b3f687cba89d5a4ad5d6a11a95e.tar.gz
Added a middleware to clear out error bodies, making them more accessible to Apache; added an app_iter wrapper for chaining app_iters from multiple sources (needed for peeking at status)
Diffstat (limited to 'paste/errordocument.py')
-rw-r--r--paste/errordocument.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/paste/errordocument.py b/paste/errordocument.py
index 991ba8a..0a44a3e 100644
--- a/paste/errordocument.py
+++ b/paste/errordocument.py
@@ -59,6 +59,7 @@ base path of the application is.
from urllib import urlencode
from urlparse import urlparse
+from paste.wsgilib import chained_app_iters
def forward(app, codes):
"""
@@ -327,3 +328,51 @@ def make_errordocument(app, global_conf, **kw):
map[status] = redir_loc
forwarder = forward(app, map)
return forwarder
+
+
+def make_empty_error(app, global_conf, **kw):
+ """
+ Use like:
+
+ [filter-app:main]
+ use = egg:Paste#emptyerror
+ next = real-app
+
+ This will clear the body of any bad responses (e.g., 404, 500,
+ etc). If running behind Apache, Apache will replace the empty
+ response with whatever its configured ``ErrorDocument`` (but
+ Apache doesn't overwrite responses that do have content, which is
+ why this middlware is necessary)
+ """
+ if kw:
+ raise ValueError(
+ 'emptyerror does not take any configuration')
+ return empty_error(app)
+
+def empty_error(app):
+ def filtered_app(environ, start_response):
+ got_status = []
+ def replace_start_response(status, headers, exc_info=None):
+ got_status.append(status)
+ return start_response(status, headers, exc_info)
+ app_iter = app(environ, replace_start_response)
+ item1 = None
+ if not got_status:
+ item1 = ''
+ for item in app_iter:
+ item1 = item
+ break
+ if not got_status:
+ raise ValueError(
+ "start_response not called from application")
+ status = int(got_status[0].split()[0])
+ if status >= 400:
+ if hasattr(app_iter, 'close'):
+ app_iter.close()
+ return ['']
+ else:
+ if item1 is not None:
+ return chained_app_iters([item1], app_iter)
+ else:
+ return app_iter
+ return filtered_app