mirror of
https://github.com/django/django.git
synced 2025-01-05 07:55:47 +00:00
Fixed #10571 -- Ensured that unicode POST data is correctly encoded by the test client. Thanks to Rick Wagner for his help identifying and fixing this problem.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10513 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
8fecf36b68
commit
8dc73e8425
1
AUTHORS
1
AUTHORS
@ -436,6 +436,7 @@ answer newbie questions, and generally made Django that much better:
|
|||||||
Vlado <vlado@labath.org>
|
Vlado <vlado@labath.org>
|
||||||
Milton Waddams
|
Milton Waddams
|
||||||
Chris Wagner <cw264701@ohio.edu>
|
Chris Wagner <cw264701@ohio.edu>
|
||||||
|
Rick Wagner <rwagner@physics.ucsd.edu>
|
||||||
wam-djangobug@wamber.net
|
wam-djangobug@wamber.net
|
||||||
Wang Chun <wangchun@exoweb.net>
|
Wang Chun <wangchun@exoweb.net>
|
||||||
Filip Wasilewski <filip.wasilewski@gmail.com>
|
Filip Wasilewski <filip.wasilewski@gmail.com>
|
||||||
|
@ -2,6 +2,7 @@ import urllib
|
|||||||
from urlparse import urlparse, urlunparse, urlsplit
|
from urlparse import urlparse, urlunparse, urlsplit
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
try:
|
try:
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -25,7 +26,7 @@ from django.test.utils import ContextList
|
|||||||
|
|
||||||
BOUNDARY = 'BoUnDaRyStRiNg'
|
BOUNDARY = 'BoUnDaRyStRiNg'
|
||||||
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
|
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
|
||||||
|
CONTENT_TYPE_RE = re.compile('.*; charset=([\w\d-]+);?')
|
||||||
|
|
||||||
class FakePayload(object):
|
class FakePayload(object):
|
||||||
"""
|
"""
|
||||||
@ -290,7 +291,13 @@ class Client(object):
|
|||||||
if content_type is MULTIPART_CONTENT:
|
if content_type is MULTIPART_CONTENT:
|
||||||
post_data = encode_multipart(BOUNDARY, data)
|
post_data = encode_multipart(BOUNDARY, data)
|
||||||
else:
|
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)
|
||||||
|
|
||||||
parsed = urlparse(path)
|
parsed = urlparse(path)
|
||||||
r = {
|
r = {
|
||||||
|
@ -624,3 +624,36 @@ class QueryStringTests(TestCase):
|
|||||||
self.assertEqual(response.context['post-bar'], 'bang')
|
self.assertEqual(response.context['post-bar'], 'bang')
|
||||||
self.assertEqual(response.context['request-foo'], 'whiz')
|
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||||
self.assertEqual(response.context['request-bar'], 'bang')
|
self.assertEqual(response.context['request-bar'], 'bang')
|
||||||
|
|
||||||
|
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'))
|
||||||
|
@ -23,4 +23,5 @@ urlpatterns = patterns('',
|
|||||||
(r'^check_session/$', views.check_session_view),
|
(r'^check_session/$', views.check_session_view),
|
||||||
(r'^request_methods/$', views.request_methods_view),
|
(r'^request_methods/$', views.request_methods_view),
|
||||||
(r'^check_unicode/$', views.return_unicode),
|
(r'^check_unicode/$', views.return_unicode),
|
||||||
|
(r'^parse_unicode_json/$', views.return_json_file),
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
|
from django.conf import settings
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.http import HttpResponse, HttpResponseRedirect
|
from django.http import HttpResponse, HttpResponseRedirect
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.shortcuts import render_to_response
|
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):
|
def no_template_view(request):
|
||||||
"A simple view that expects a GET request, and returns a rendered template"
|
"A simple view that expects a GET request, and returns a rendered template"
|
||||||
@ -63,3 +68,21 @@ def request_methods_view(request):
|
|||||||
|
|
||||||
def return_unicode(request):
|
def return_unicode(request):
|
||||||
return render_to_response('unicode.html')
|
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
|
||||||
|
Loading…
Reference in New Issue
Block a user