# HG changeset patch # User Julien Cristau # Date 1394110764 -3600 # Node ID 48f0ff3e2a32982ab6881ff81e6561079f13762b # Parent 0509880fec01fe34b6fd2514d1dcdb4b58244da4 [wsgi] make sure request.content is available for consumption The wsgi.input stream is not seekable, so make a copy either to memory or disk so it's still available to the user even after we've parsed it (for POST form processing). Closes #3554996 diff -r 0509880fec01 -r 48f0ff3e2a32 wsgi/request.py --- a/wsgi/request.py Wed Jan 29 10:57:10 2014 +0100 +++ b/wsgi/request.py Thu Mar 06 13:59:24 2014 +0100 @@ -45,7 +45,17 @@ self.environ = environ self.path = environ['PATH_INFO'] self.method = environ['REQUEST_METHOD'].upper() - self.content = environ['wsgi.input'] + try: + length = int(environ['CONTENT_LENGTH']) + except (KeyError, ValueError): + length = 0 + # wsgi.input is not seekable, so copy the request contents to a temporary file + if length < 100000: + self.content = StringIO() + else: + self.content = tempfile.TemporaryFile() + safe_copyfileobj(environ['wsgi.input'], self.content, size=length) + self.content.seek(0, 0) headers_in = dict((normalize_header(k[5:]), v) for k, v in self.environ.items() if k.startswith('HTTP_')) @@ -139,15 +149,6 @@ @property @cached def raw_post_data(self): - buf = StringIO() - try: - # CONTENT_LENGTH might be absent if POST doesn't have content at all (lighttpd) - content_length = int(self.environ.get('CONTENT_LENGTH', 0)) - except ValueError: # if CONTENT_LENGTH was empty string or not an integer - content_length = 0 - if content_length > 0: - safe_copyfileobj(self.environ['wsgi.input'], buf, - size=content_length) - postdata = buf.getvalue() - buf.close() + postdata = self.content.read() + self.content.seek(0, 0) return postdata