Commits

Anonymous committed 445e836

Fixed #5956 -- Added a better error description for non-ASCII HTTP headers. Patch from jvloothuis.

Comments (0)

Files changed (2)

django/http/__init__.py

             for key, value in self._headers.values()]) \
             + '\n\n' + self.content
 
+    def _convert_to_ascii(self, *values):
+        "Convert all values to ascii strings"
+        for value in values:
+            if isinstance(value, unicode):
+                try:
+                    yield value.encode('us-ascii')
+                except UnicodeError, e:
+                    e.reason += ', HTTP response headers must be in US-ASCII format'
+                    raise
+            else:
+                yield str(value)
+
     def __setitem__(self, header, value):
+        header, value = self._convert_to_ascii(header, value)
         self._headers[header.lower()] = (header, value)
 
     def __delitem__(self, header):

tests/regressiontests/httpwrappers/tests.py

 >>> q.getlist('foo')
 [u'bar', u'\ufffd']
 
+
+###################################### 
+# HttpResponse with Unicode headers  # 
+###################################### 
+ 
+>>> r = HttpResponse() 
+ 
+If we insert a unicode value it will be converted to an ascii
+string. This makes sure we comply with the HTTP specifications.
+ 
+>>> r['value'] = u'test value' 
+>>> isinstance(r['value'], str) 
+True
+
+An error is raised When a unicode object with non-ascii is assigned.
+
+>>> r['value'] = u't\xebst value' # doctest:+ELLIPSIS
+Traceback (most recent call last):
+...
+UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format
+ 
+The response also converts unicode keys to strings. 
+ 
+>>> r[u'test'] = 'testing key' 
+>>> list(sorted(r.items()))[1]
+('test', 'testing key')
+
+It will also raise errors for keys with non-ascii data.
+
+>>> r[u't\xebst'] = 'testing key'  # doctest:+ELLIPSIS
+Traceback (most recent call last):
+...
+UnicodeEncodeError: ..., HTTP response headers must be in US-ASCII format
+ 
 """
 
-from django.http import QueryDict
+from django.http import QueryDict, HttpResponse
 
 if __name__ == "__main__":
     import doctest