Index: django/http/__init__.py
===================================================================
--- django/http/__init__.py	(revision 6812)
+++ django/http/__init__.py	(working copy)
@@ -278,7 +278,8 @@
             + '\n\n' + self.content
 
     def __setitem__(self, header, value):
-        self._headers[header.lower()] = (header, value)
+        self._headers[header.lower()] = (smart_str(header, self._charset),
+                                         smart_str(value, self._charset))
 
     def __delitem__(self, header):
         try:
Index: tests/regressiontests/httpwrappers/tests.py
===================================================================
--- tests/regressiontests/httpwrappers/tests.py	(revision 6812)
+++ tests/regressiontests/httpwrappers/tests.py	(working copy)
@@ -391,9 +391,40 @@
 >>> q.getlist('foo')
 [u'bar', u'\ufffd']
 
+######################################
+# HttpResponse with Unicode headers  #
+######################################
+
+>>> r = HttpResponse()
+
+If we insert a unicode value it will be converted to a string. This is done
+because the handlers (WSGI/mod_python) expect binary data and will break on
+non-ascii unicode.
+
+>>> r['value'] = u't\xebst value'
+>>> type(r['value'])
+<type 'str'>
+
+It uses the charset of the response for encoding it. By default it is utf-8.
+
+>>> type(r['value'].decode('utf8'))
+<type 'unicode'>
+
+The response also converts unicode keys to strings.
+
+>>> r[u't\xebst'] = 'testing key'
+>>> type(list(sorted(r.items()))[1][0])
+<type 'str'>
+
+This only happens when you call items since the implementation uses a system
+where the original key is used for normal dict lookups.
+
+>>> u't\xebst' in r 
+True
+
 """
 
-from django.http import QueryDict
+from django.http import QueryDict, HttpResponse
 
 if __name__ == "__main__":
     import doctest
