From b0467bac975abdc2fa3b49e650f92d9f81fcd77e Mon Sep 17 00:00:00 2001
From: Gisle Aas <gisle@aas.no>
Date: Mon, 22 Feb 2010 17:31:54 -0500
Subject: [PATCH 1/2] Ticket #12747 Set custom status_text message

---
 django/core/handlers/wsgi.py                |    2 +-
 django/http/__init__.py                     |   14 +++++++++++++-
 docs/ref/request-response.txt               |   11 ++++++++++-
 tests/regressiontests/httpwrappers/tests.py |   20 ++++++++++++++++++++
 4 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/django/core/handlers/wsgi.py b/django/core/handlers/wsgi.py
index 927b098..0320048 100644
--- a/django/core/handlers/wsgi.py
+++ b/django/core/handlers/wsgi.py
@@ -248,7 +248,7 @@ class WSGIHandler(base.BaseHandler):
             signals.request_finished.send(sender=self.__class__)
 
         try:
-            status_text = STATUS_CODE_TEXT[response.status_code]
+            status_text = response.status_text or STATUS_CODE_TEXT[response.status_code]
         except KeyError:
             status_text = 'UNKNOWN STATUS CODE'
         status = '%s %s' % (response.status_code, status_text)
diff --git a/django/http/__init__.py b/django/http/__init__.py
index 6353637..b2cd794 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -293,6 +293,9 @@ def parse_cookie(cookie):
         cookiedict[key] = c.get(key).value
     return cookiedict
 
+class BadStatusError(ValueError):
+    pass
+
 class BadHeaderError(ValueError):
     pass
 
@@ -300,6 +303,7 @@ class HttpResponse(object):
     """A basic HTTP response, with content and dictionary-accessed headers."""
 
     status_code = 200
+    status_text = None
 
     def __init__(self, content='', mimetype=None, status=None,
             content_type=None):
@@ -318,7 +322,15 @@ class HttpResponse(object):
             self._is_string = True
         self.cookies = CompatCookie()
         if status:
-            self.status_code = status
+            if isinstance(status, basestring):
+                m = re.match(r'(\d{3}) +([^\n]*)$', status)
+                if m:
+                    self.status_code = int(m.group(1))
+                    self.status_text = m.group(2)
+                else:
+                    raise BadStatusError("Bad HTTP status line string (%r)" % (status))
+            else:
+                self.status_code = status
 
         # _headers is a mapping of the lower-case name to the original case of
         # the header (required for working with legacy systems) and the header
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 1788e06..7e74dfd 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -466,6 +466,12 @@ Attributes
 
     The `HTTP Status code`_ for the response.
 
+.. attribute:: HttpResponse.status_text
+
+    The `HTTP Status code`_ text for the response. This is the human readable
+    string passed with the status code in the status line.  If not provided the
+    standard text corresponding to ``status_code`` is used.
+
 Methods
 -------
 
@@ -478,7 +484,10 @@ Methods
     return strings, and those strings will be joined together to form the
     content of the response.
 
-    ``status`` is the `HTTP Status code`_ for the response.
+    ``status`` is the `HTTP Status code`_ for the response.  Normally this will
+    be an integer, but if passed as a string it should be on the form "200 OK"
+    and this will then intialize both the ``status_code`` and ``status_text``
+    attribute of the response.
 
     .. versionadded:: 1.0
 
diff --git a/tests/regressiontests/httpwrappers/tests.py b/tests/regressiontests/httpwrappers/tests.py
index 132472c..c842602 100644
--- a/tests/regressiontests/httpwrappers/tests.py
+++ b/tests/regressiontests/httpwrappers/tests.py
@@ -503,6 +503,26 @@ class Cookies(TestCase):
         c2.load(c.output())
         self.assertEqual(c['test'].value, c2['test'].value)
 
+class Response(TestCase):
+
+    def test_status(self):
+        """
+        Test setting of status code in the constructor call
+        """
+        r = HttpResponse()
+        self.assertEqual(r.status_code, 200)
+        self.assertEqual(r.status_text, None)
+        r = HttpResponse(status=404)
+        self.assertEqual(r.status_code, 404)
+        self.assertEqual(r.status_text, None)
+        r = HttpResponse(status="202 Thanks!")
+        self.assertEqual(r.status_code, 202)
+        self.assertEqual(r.status_text, "Thanks!")
+
+        from django.http import BadStatusError
+        self.assertRaises(ValueError, lambda: HttpResponse(status="OK"))
+        self.assertRaises(BadStatusError, lambda: HttpResponse(status="OK"))
+
 if __name__ == "__main__":
     import doctest
     doctest.testmod()
-- 
1.7.0.83.g241b9

