Anonymous avatar Anonymous committed 7463bfa

[soc2009/http-wsgi-improvements] Throw an exception when HttpResponse.codec is set with a bad value. Improved coverage of encoding changes in request and response headers. Refs #10190.

Passes the test suite.

Comments (0)

Files changed (4)

django/http/__init__.py

         return self._codec
 
     def _set_codec(self, value):
-        if hasattr(value, "name"):
-            self._codec = value
+        if not hasattr(value, "name"):
+            # This is slightly more permissive, allowing any object with the
+            # "name" attribute.
+            raise Exception("Codec should be provided with a CodecInfo object.")
+        self._codec = value
 
     codec = property(_get_codec, _set_codec)
 

tests/regressiontests/charsets/tests.py

 
 class ClientTest(TestCase):
     urls = 'regressiontests.charsets.urls'
-    
+    test_string = u'\u82cf\u8054\u961f'
+    codec = get_codec("GBK")
+
+    def encode(self, string):
+        return self.codec.encode(string)[0]
+
+    def decode(self, string):
+        return self.codec.decode(string)[0]
+
     def test_good_accept_charset(self):
         "Use Accept-Charset, with a quality value that throws away default_charset"
         # The data is ignored, but let's check it doesn't crash the system
         # anyway.
-        
+
         response = self.client.post('/accept_charset/', ACCEPT_CHARSET="ascii,utf-8;q=0")
         
         self.assertEqual(response.status_code, 200)
         self.assertEqual(response.status_code, 200)
         self.assertEqual(get_charset(response), settings.DEFAULT_CHARSET)
 
+    def test_encode_content_type(self):
+        "Make sure a request gets encoded according to the content type in the view."
+        response = self.client.post('/encode_response_content_type/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(get_codec(get_charset(response)).name, self.codec.name)
+        self.assertEqual(response.content, self.encode(self.test_string))
+
+    def test_encode_accept_charset(self):
+        "Make sure a request gets encoded according to the Accept-Charset request header."
+        response = self.client.post('/encode_response_accept_charset/',
+                                     ACCEPT_CHARSET="gbk;q=1,utf-8;q=0.9")
+
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(get_codec(get_charset(response)).name, self.codec.name)
+        self.assertEqual(response.content, self.encode(self.test_string))
+
+    def test_bad_codec(self):
+        "Assure we get an Exception for setting a bad codec in the view."
+        self.assertRaises(Exception, self.client.post, '/bad_codec/')
+
+    def test_good_codecs(self):
+        response = self.client.post('/good_codec/')
+        self.assertEqual(response.status_code, 200)
+        self.assertEqual(response.content, self.encode(self.test_string))

tests/regressiontests/charsets/urls.py

     (r'^bad_content_type/', views.bad_content_type),
     (r'^content_type_no_charset/', views.content_type_no_charset),
     (r'^basic_response/', views.basic_response),
+    (r'^good_codec/', views.good_codec),
+    (r'^bad_codec/', views.bad_codec),
+    (r'^encode_response_content_type/', views.encode_response_content_type),
+    (r'^encode_response_accept_charset/', views.encode_response_accept_charset),
 )

tests/regressiontests/charsets/views.py

+import codecs
 from django.http import HttpResponse
 from django.shortcuts import render_to_response
 
+test_string = u'\u82cf\u8054\u961f'
+codec = "GBK"
+
 def accept_charset(request):
     return HttpResponse("ASCII.", request=request)
 
 def content_type_no_charset(request):
     return HttpResponse("UTF-8", content_type="text/html")
 
-def encode_response(request):
-    return HttpResponse(u"\ue863", content_type="text/html; charset=GBK")
+def encode_response_content_type(request):
+    return HttpResponse(test_string, content_type="text/html; charset=GBK")
+
+def encode_response_accept_charset(request):
+    return HttpResponse(test_string, request=request)
 
 def basic_response(request):
     return HttpResponse("ASCII.")
+
+# This mimics codecs.CodecInfo enough for the purposes of HttpResponse.
+class FakeCodec:
+    def __init__(self, name=None):
+        if name:
+            self.name = name
+
+def bad_codec(request):
+    data = HttpResponse("ASCII.")
+    data.codec = FakeCodec()
+    return data
+
+def good_codec(request):
+    data = HttpResponse(test_string)
+    data.codec = FakeCodec(codec)
+    return data
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.