wsgi/request.py
changeset 9821 2077c8da1893
parent 9755 566d90bdc565
parent 9735 b71158815bc8
child 9990 c84ad981fc4a
--- 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