[wsgi] Fix unicode decoding in POST
authorChristophe de Vienne <christophe@unlish.com>
Wed, 10 Sep 2014 21:28:33 +0200
changeset 9946 ec88c1a1904a
parent 9945 cf5b0d0f5731
child 9975 98b4f7fa2e3a
[wsgi] Fix unicode decoding in POST The application/x-www-form-urlencoded sent by firefox or chrome is utf-8 encoded BEFORE being urlencoded. Hence, decoding must urldecode THEN decode the utf-8 string, and not the other way around.
multipart.py
wsgi/test/unittest_wsgi.py
--- a/multipart.py	Thu Aug 21 22:42:48 2014 +0200
+++ b/multipart.py	Wed Sep 10 21:28:33 2014 +0200
@@ -398,13 +398,13 @@
             mem_limit = kw.get('mem_limit', 2**20)
             if content_length > mem_limit:
                 raise MultipartError("Request to big. Increase MAXMEM.")
-            data = stream.read(mem_limit).decode(charset)
+            data = stream.read(mem_limit)
             if stream.read(1): # These is more that does not fit mem_limit
                 raise MultipartError("Request to big. Increase MAXMEM.")
             data = parse_qs(data, keep_blank_values=True)
             for key, values in data.iteritems():
                 for value in values:
-                    forms[key] = value
+                    forms[key] = value.decode(charset)
         else:
             raise MultipartError("Unsupported content type.")
     except MultipartError:
--- a/wsgi/test/unittest_wsgi.py	Thu Aug 21 22:42:48 2014 +0200
+++ b/wsgi/test/unittest_wsgi.py	Wed Sep 10 21:28:33 2014 +0200
@@ -1,3 +1,5 @@
+# encoding=utf-8
+
 import webtest.app
 from StringIO import StringIO
 
@@ -76,6 +78,13 @@
 
         self.assertEqual([u'1', u'2'], req.form['arg'])
 
+    def test_post_unicode_urlencoded(self):
+        params = 'arg=%C3%A9'
+        r = webtest.app.TestRequest.blank(
+            '/', POST=params, content_type='application/x-www-form-urlencoded')
+        req = CubicWebWsgiRequest(r.environ, self.vreg)
+        self.assertEqual(u"é", req.form['arg'])
+
     @classmethod
     def init_config(cls, config):
         super(WSGIAppTC, cls).init_config(config)