diff -r 95902c0b991b -r 2077c8da1893 wsgi/request.py --- a/wsgi/request.py Fri May 23 18:35:13 2014 +0200 +++ b/wsgi/request.py Fri Jun 27 11:48:26 2014 +0200 @@ -27,14 +27,11 @@ from StringIO import StringIO from urllib import quote +from urlparse import parse_qs -from logilab.common.decorators import cached - +from cubicweb.multipart import copy_file, parse_form_data from cubicweb.web.request import CubicWebRequestBase -from cubicweb.wsgi import (pformat, qs2dict, safe_copyfileobj, parse_file_upload, - normalize_header) -from cubicweb.web.http_headers import Headers - +from cubicweb.wsgi import pformat, normalize_header class CubicWebWsgiRequest(CubicWebRequestBase): @@ -45,6 +42,8 @@ self.environ = environ self.path = environ['PATH_INFO'] self.method = environ['REQUEST_METHOD'].upper() + + # content_length "may be empty or absent" try: length = int(environ['CONTENT_LENGTH']) except (KeyError, ValueError): @@ -54,8 +53,9 @@ self.content = StringIO() else: self.content = tempfile.TemporaryFile() - safe_copyfileobj(environ['wsgi.input'], self.content, size=length) + copy_file(environ['wsgi.input'], self.content, maxread=length) self.content.seek(0, 0) + environ['wsgi.input'] = self.content headers_in = dict((normalize_header(k[5:]), v) for k, v in self.environ.items() if k.startswith('HTTP_')) @@ -65,10 +65,11 @@ super(CubicWebWsgiRequest, self).__init__(vreg, https, post, headers= headers_in) if files is not None: - for key, (name, _, stream) in files.iteritems(): - if name is not None: - name = unicode(name, self.encoding) - self.form[key] = (name, stream) + for key, part in files.iteritems(): + name = None + if part.filename is not None: + name = unicode(part.filename, self.encoding) + self.form[key] = (name, part.file) def __repr__(self): # Since this is called as part of error handling, we need to be very @@ -108,23 +109,11 @@ def get_posted_data(self): # The WSGI spec says 'QUERY_STRING' may be absent. - post = qs2dict(self.environ.get('QUERY_STRING', '')) + post = parse_qs(self.environ.get('QUERY_STRING', '')) files = None if self.method == 'POST': - if self.environ.get('CONTENT_TYPE', '').startswith('multipart'): - header_dict = dict((normalize_header(k[5:]), v) - for k, v in self.environ.items() - if k.startswith('HTTP_')) - header_dict['Content-Type'] = self.environ.get('CONTENT_TYPE', '') - post_, files = parse_file_upload(header_dict, self.raw_post_data) - post.update(post_) - else: - post.update(qs2dict(self.raw_post_data)) + forms, files = parse_form_data(self.environ, strict=True, + mem_limit=self.vreg.config['max-post-length']) + post.update(forms) + self.content.seek(0, 0) return post, files - - @property - @cached - def raw_post_data(self): - postdata = self.content.read() - self.content.seek(0, 0) - return postdata