Ticket #13391: 13007-http-response-charset.diff

File 13007-http-response-charset.diff, 6.1 KB (added by lucky, 14 years ago)
  • django/http/__init__.py

     
    2121
    2222absolute_http_url_re = re.compile(r"^https?://", re.I)
    2323
     24_charset_from_content_type_re = re.compile(r';\s*charset=([^\s;]+)', re.I)
     25
    2426class Http404(Exception):
    2527    pass
    2628
     
    303305
    304306    def __init__(self, content='', mimetype=None, status=None,
    305307            content_type=None):
    306         from django.conf import settings
    307         self._charset = settings.DEFAULT_CHARSET
    308308        if mimetype:
    309309            content_type = mimetype     # For backwards compatibility
    310310        if not content_type:
     311            from django.conf import settings
    311312            content_type = "%s; charset=%s" % (settings.DEFAULT_CONTENT_TYPE,
    312313                    settings.DEFAULT_CHARSET)
    313314        if not isinstance(content, basestring) and hasattr(content, '__iter__'):
     
    400401
    401402    content = property(_get_content, _set_content)
    402403
     404    def _get_charset(self):
     405        def _unquote(value):
     406            if value and value[0] == value[-1] == '"':
     407                return value[1:-1]
     408            return value
     409
     410        matched = _charset_from_content_type_re.search(self["Content-type"])
     411        if not matched:
     412            from django.conf import settings
     413            return settings.DEFAULT_CHARSET
     414        return _unquote(matched.group(1))
     415
     416    _charset = property(_get_charset)
     417
    403418    def __iter__(self):
    404419        self._iterator = iter(self._container)
    405420        return self
  • tests/regressiontests/http_response_charset/tests.py

     
     1from django.conf import settings
     2from django.http import HttpResponse
     3from django.test import TestCase
     4
     5
     6class HttpResponseCharsetDetectionTest(TestCase):
     7    """Test of the charset detection from the ``Content-type`` header."""
     8
     9    def setUp(self):
     10        self._charset_backup = settings.DEFAULT_CHARSET
     11        settings.DEFAULT_CHARSET = "iso-8859-1"
     12
     13    def tearDown(self):
     14        settings.DEFAULT_CHARSET = self._charset_backup
     15
     16    def testShouldAssumeDefaultCharsetWhenContentTypeIsNotGiven(self):
     17        response = HttpResponse('ok')
     18        self.assertEqual(response._charset, settings.DEFAULT_CHARSET)
     19
     20    def testShouldDetectUnquotedCharset(self):
     21        content_type = "text/plain; charset=utf-8"
     22        response = HttpResponse('ok', content_type=content_type)
     23        self.assertEqual(response._charset, 'utf-8')
     24
     25    def testShouldDetectQuotedCharset(self):
     26        content_type = 'text/plain; charset="utf-8"'
     27        response = HttpResponse('ok', content_type=content_type)
     28        self.assertEqual(response._charset, "utf-8")
     29
     30    def testShouldAssumeDefaultCharsetWhenTheCharsetIsEmpty(self):
     31        content_type = 'text/plain; charset='
     32        response = HttpResponse('ok', content_type=content_type)
     33        self.assertEqual(response._charset, settings.DEFAULT_CHARSET)
     34
     35    def testShouldAssumeDefaultCharsetWhenTheCharsetIsNotGiven(self):
     36        content_type = 'text/plain'
     37        response = HttpResponse('ok', content_type=content_type)
     38        self.assertEqual(response._charset, settings.DEFAULT_CHARSET)
     39
  • tests/regressiontests/tests_testcase_assertcontains/tests.py

     
     1from django.conf import settings
     2from django.http import HttpResponse
     3from django.test import TestCase
     4
     5
     6class HttpResponseContentWithNotDefaultCharsetTest(TestCase):
     7
     8    def setUp(self):
     9        self.default_charset = "iso-8859-1"
     10        self.content_with_default_charset = "Just latin-1 :)"
     11        self.unusual_charset = "utf-8"
     12        self.content_with_unusual_charset =  u"Unicode smile \u32e1"
     13
     14        self._charset_back = settings.DEFAULT_CHARSET
     15        settings.DEFAULT_CHARSET = self.default_charset
     16
     17    def tearDown(self):
     18        settings.DEFAULT_CHARSET = self._charset_back
     19
     20    def testMayOmitContentTypeHeaderWhenContentHasDefaultCharset(self):
     21        self.assertEqual(settings.DEFAULT_CHARSET, self.default_charset)
     22        response = HttpResponse(self.content_with_default_charset)
     23        self.assertContains(response, self.content_with_default_charset)
     24
     25    def testShouldPassWhenCharsetGivenInTheContentTypeHeader(self):
     26        if settings.DEFAULT_CHARSET <> self.unusual_charset:
     27            content_type = "text/plain; charset=%s" % self.unusual_charset
     28        else:
     29            content_type = None
     30
     31        self.assertEqual(content_type, "text/plain; charset=utf-8")
     32        response = HttpResponse(self.content_with_unusual_charset,
     33                                content_type=content_type)
     34        self.assertContains(response, self.content_with_unusual_charset)
     35
     36    def testMayBeCrazyIfCharsetIsNotGiven(self):
     37        response = HttpResponse(self.content_with_unusual_charset)
     38        self.assertRaises(UnicodeEncodeError,
     39                self.assertContains, response, self.content_with_unusual_charset)
     40
     41        response = HttpResponse(self.content_with_unusual_charset,
     42                                content_type="text/plain")
     43        self.assertRaises(UnicodeEncodeError,
     44                self.assertContains, response, self.content_with_unusual_charset)
     45
Back to Top