Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.0.X] Fixed #10571 -- Ensured that unicode POST data is correctly e…

…ncoded by the test client. Thanks to Rick Wagner for his help identifying and fixing this problem.

Merge of r10513 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.0.X@10514 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b6bd5ddc3357d99f22f5181f5daecb46512650ba 1 parent c2a828c
@freakboy3742 freakboy3742 authored
View
1  AUTHORS
@@ -422,6 +422,7 @@ answer newbie questions, and generally made Django that much better:
Vlado <vlado@labath.org>
Milton Waddams
Chris Wagner <cw264701@ohio.edu>
+ Rick Wagner <rwagner@physics.ucsd.edu>
wam-djangobug@wamber.net
Wang Chun <wangchun@exoweb.net>
Filip Wasilewski <filip.wasilewski@gmail.com>
View
11 django/test/client.py
@@ -1,6 +1,7 @@
import urllib
import sys
import os
+import re
try:
from cStringIO import StringIO
except ImportError:
@@ -21,7 +22,7 @@
BOUNDARY = 'BoUnDaRyStRiNg'
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
-
+CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?')
class FakePayload(object):
"""
@@ -279,7 +280,13 @@ def post(self, path, data={}, content_type=MULTIPART_CONTENT, **extra):
if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data)
else:
- post_data = data
+ # Encode the content so that the byte representation is correct.
+ match = CONTENT_TYPE_RE.match(content_type)
+ if match:
+ charset = match.group(1)
+ else:
+ charset = settings.DEFAULT_CHARSET
+ post_data = smart_str(data, encoding=charset)
r = {
'CONTENT_LENGTH': len(post_data),
View
33 tests/regressiontests/test_client_regress/models.py
@@ -412,3 +412,36 @@ def test_logout(self):
self.failUnless(login, 'Could not log in')
self.client.logout()
self.client.logout()
+
+class UnicodePayloadTests(TestCase):
+ def test_simple_unicode_payload(self):
+ "A simple ASCII-only unicode JSON document can be POSTed"
+ # Regression test for #10571
+ json = u'{"english": "mountain pass"}'
+ response = self.client.post("/test_client_regress/parse_unicode_json/", json,
+ content_type="application/json")
+ self.assertEqual(response.content, json)
+
+ def test_unicode_payload_utf8(self):
+ "A non-ASCII unicode data encoded as UTF-8 can be POSTed"
+ # Regression test for #10571
+ json = u'{"dog": "собака"}'
+ response = self.client.post("/test_client_regress/parse_unicode_json/", json,
+ content_type="application/json; charset=utf-8")
+ self.assertEqual(response.content, json.encode('utf-8'))
+
+ def test_unicode_payload_utf16(self):
+ "A non-ASCII unicode data encoded as UTF-16 can be POSTed"
+ # Regression test for #10571
+ json = u'{"dog": "собака"}'
+ response = self.client.post("/test_client_regress/parse_unicode_json/", json,
+ content_type="application/json; charset=utf-16")
+ self.assertEqual(response.content, json.encode('utf-16'))
+
+ def test_unicode_payload_non_utf(self):
+ "A non-ASCII unicode data as a non-UTF based encoding can be POSTed"
+ #Regression test for #10571
+ json = u'{"dog": "собака"}'
+ response = self.client.post("/test_client_regress/parse_unicode_json/", json,
+ content_type="application/json; charset=koi8-r")
+ self.assertEqual(response.content, json.encode('koi8-r'))
View
1  tests/regressiontests/test_client_regress/urls.py
@@ -10,4 +10,5 @@
(r'^set_session/$', views.set_session_view),
(r'^check_session/$', views.check_session_view),
(r'^check_unicode/$', views.return_unicode),
+ (r'^parse_unicode_json/$', views.return_json_file),
)
View
23 tests/regressiontests/test_client_regress/views.py
@@ -1,7 +1,12 @@
+from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, HttpResponseRedirect
from django.core.exceptions import SuspiciousOperation
from django.shortcuts import render_to_response
+from django.utils import simplejson
+from django.utils.encoding import smart_str
+from django.core.serializers.json import DjangoJSONEncoder
+from django.test.client import CONTENT_TYPE_RE
def no_template_view(request):
"A simple view that expects a GET request, and returns a rendered template"
@@ -47,3 +52,21 @@ def check_session_view(request):
def return_unicode(request):
return render_to_response('unicode.html')
+
+def return_json_file(request):
+ "A view that parses and returns a JSON string as a file."
+ match = CONTENT_TYPE_RE.match(request.META['CONTENT_TYPE'])
+ if match:
+ charset = match.group(1)
+ else:
+ charset = settings.DEFAULT_CHARSET
+
+ # This just checks that the uploaded data is JSON
+ obj_dict = simplejson.loads(request.raw_post_data.decode(charset))
+ obj_json = simplejson.dumps(obj_dict, encoding=charset,
+ cls=DjangoJSONEncoder,
+ ensure_ascii=False)
+ response = HttpResponse(smart_str(obj_json, encoding=charset), status=200,
+ mimetype='application/json; charset=' + charset)
+ response['Content-Disposition'] = 'attachment; filename=testfile.json'
+ return response
Please sign in to comment.
Something went wrong with that request. Please try again.