summaryrefslogtreecommitdiff
path: root/paste/cascade.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2007-10-10 01:17:23 +0000
committerianb <devnull@localhost>2007-10-10 01:17:23 +0000
commita11c498781b471b9c644681b9cd554b119f22398 (patch)
tree4d4135cb96c062a16deedfff1297b211dd694850 /paste/cascade.py
parentbe02769dbf04aa73bab71ff832878c72ee929ea1 (diff)
downloadpaste-a11c498781b471b9c644681b9cd554b119f22398.tar.gz
Fix #194, paste.cascade doesn't copy wsgi.input, and blocking can occur: now wsgi.input is copied and .seek(0) on each call
Diffstat (limited to 'paste/cascade.py')
-rw-r--r--paste/cascade.py21
1 files changed, 21 insertions, 0 deletions
diff --git a/paste/cascade.py b/paste/cascade.py
index 9176320..962da31 100644
--- a/paste/cascade.py
+++ b/paste/cascade.py
@@ -7,6 +7,8 @@ return ``404 Not Found``.
"""
from paste import httpexceptions
from paste.util import converters
+import tempfile
+from cStringIO import StringIO
__all__ = ['Cascade']
@@ -74,8 +76,27 @@ class Cascade(object):
return _consuming_writer
return start_response(status, headers, exc_info)
+ length = int(environ.get('CONTENT_LENGTH', '0'))
+ if length > 0:
+ # We have to copy wsgi.input
+ copy_wsgi_input = True
+ if length > 4096 or length == -1:
+ f = tempfile.TemporaryFile()
+ copy_len = length
+ while copy_len:
+ chunk = environ['wsgi.input'].read(min(copy_len, 4096))
+ f.write(chunk)
+ copy_len -= len(chunk)
+ f.seek(0)
+ else:
+ f = StringIO(environ['wsgi.input'].read(length))
+ environ['wsgi.input'] = f
+ else:
+ copy_wsgi_input = False
for app in self.apps[:-1]:
environ_copy = environ.copy()
+ if copy_wsgi_input:
+ environ_copy['wsgi.input'].seek(0)
failed = []
try:
v = app(environ_copy, repl_start_response)