Skip to content

Commit

Permalink
[1.3.X] Fixed #10571 -- Factored out the payload encoding code to mak…
Browse files Browse the repository at this point in the history
…e sure it is used for PUT requests. Thanks to kennu for the report, pterk for the patch, and wildfire for the review comments.

Backport of r16651 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16672 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
freakboy3742 committed Aug 23, 2011
1 parent 671483f commit e9a1c03
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
40 changes: 17 additions & 23 deletions django/test/client.py
Expand Up @@ -207,6 +207,18 @@ def request(self, **request):
"Construct a generic request object."
return WSGIRequest(self._base_environ(**request))

def _encode_data(self, data, content_type, ):
if content_type is MULTIPART_CONTENT:
return encode_multipart(BOUNDARY, data)
else:
# 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
return smart_str(data, encoding=charset)

def _get_path(self, parsed):
# If there are parameters, add them
if parsed[3]:
Expand All @@ -232,16 +244,7 @@ def post(self, path, data={}, content_type=MULTIPART_CONTENT,
**extra):
"Construct a POST request."

if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data)
else:
# 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)
post_data = self._encode_data(data, content_type)

parsed = urlparse(path)
r = {
Expand Down Expand Up @@ -286,25 +289,16 @@ def put(self, path, data={}, content_type=MULTIPART_CONTENT,
**extra):
"Construct a PUT request."

if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data)
else:
post_data = data

# Make `data` into a querystring only if it's not already a string. If
# it is a string, we'll assume that the caller has already encoded it.
query_string = None
if not isinstance(data, basestring):
query_string = urlencode(data, doseq=True)
put_data = self._encode_data(data, content_type)

parsed = urlparse(path)
r = {
'CONTENT_LENGTH': len(post_data),
'CONTENT_LENGTH': len(put_data),
'CONTENT_TYPE': content_type,
'PATH_INFO': self._get_path(parsed),
'QUERY_STRING': query_string or parsed[4],
'QUERY_STRING': parsed[4],
'REQUEST_METHOD': 'PUT',
'wsgi.input': FakePayload(post_data),
'wsgi.input': FakePayload(put_data),
}
r.update(extra)
return self.request(**r)
Expand Down
16 changes: 15 additions & 1 deletion tests/regressiontests/test_client_regress/models.py
Expand Up @@ -756,7 +756,9 @@ def test_put(self):

class QueryStringTests(TestCase):
def test_get_like_requests(self):
for method_name in ('get','head','options','put','delete'):
# See: https://code.djangoproject.com/ticket/10571.
# Removed 'put' and 'delete' here as they are 'GET-like requests'
for method_name in ('get','head','options'):
# A GET-like request can pass a query string as data
method = getattr(self.client, method_name)
response = method("/test_client_regress/request_data/", data={'foo':'whiz'})
Expand Down Expand Up @@ -813,6 +815,9 @@ def test_simple_unicode_payload(self):
response = self.client.post("/test_client_regress/parse_unicode_json/", json,
content_type="application/json")
self.assertEqual(response.content, json)
response = self.client.put("/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"
Expand All @@ -821,6 +826,9 @@ def test_unicode_payload_utf8(self):
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'))
response = self.client.put("/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"
Expand All @@ -829,6 +837,9 @@ def test_unicode_payload_utf16(self):
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'))
response = self.client.put("/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"
Expand All @@ -837,6 +848,9 @@ def test_unicode_payload_non_utf(self):
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'))
response = self.client.put("/test_client_regress/parse_unicode_json/", json,
content_type="application/json; charset=koi8-r")
self.assertEqual(response.content, json.encode('koi8-r'))

class DummyFile(object):
def __init__(self, filename):
Expand Down

0 comments on commit e9a1c03

Please sign in to comment.