From c53f2451a83fc081c1886d07c390cf0447b1143f Mon Sep 17 00:00:00 2001
From: Flavio Curella <flavio.curella@gmail.com>
Date: Fri, 5 Sep 2014 13:27:26 -0700
Subject: [PATCH] Fixed #23398 -- Added helpful error message when runserver is
 accessed via HTTPS

---
 django/core/servers/basehttp.py | 12 +++++++++++-
 tests/servers/test_basehttp.py  | 27 +++++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 tests/servers/test_basehttp.py

diff --git a/django/core/servers/basehttp.py b/django/core/servers/basehttp.py
index f93b3a3143..cea1dd5057 100644
--- a/django/core/servers/basehttp.py
+++ b/django/core/servers/basehttp.py
@@ -85,7 +85,13 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
         return self.client_address[0]
 
     def log_message(self, format, *args):
-        msg = "[%s] %s\n" % (self.log_date_time_string(), format % args)
+
+        msg = "[%s]" % self.log_date_time_string()
+        try:
+            msg += "%s\n" % (format % args)
+        except UnicodeDecodeError:
+            # e.g. accessing the server via SSL on Python 2
+            msg += "\n"
 
         # Utilize terminal colors, if available
         if args[1][0] == '2':
@@ -100,6 +106,10 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler, object):
         elif args[1] == '404':
             msg = self.style.HTTP_NOT_FOUND(msg)
         elif args[1][0] == '4':
+            # 0x16 = Handshake, 0x03 = SSL 3.0 or TLS 1.x
+            if args[0].startswith(str('\x16\x03')):
+                msg = ("You're accessing the developement server over HTTPS, "
+                    "but it only supports HTTP.\n")
             msg = self.style.HTTP_BAD_REQUEST(msg)
         else:
             # Any 5XX, or any other response
diff --git a/tests/servers/test_basehttp.py b/tests/servers/test_basehttp.py
new file mode 100644
index 0000000000..8ee99d4eaa
--- /dev/null
+++ b/tests/servers/test_basehttp.py
@@ -0,0 +1,27 @@
+import sys
+
+from django.core.handlers.wsgi import WSGIRequest
+from django.core.servers.basehttp import WSGIRequestHandler
+from django.test import TestCase
+from django.test.client import RequestFactory
+from django.utils.six import BytesIO, StringIO
+
+
+class WSGIRequestHandlerTestCase(TestCase):
+    def test_https(self):
+        request = WSGIRequest(RequestFactory().get('/').environ)
+        request.makefile = lambda *args, **kwargs: BytesIO()
+
+        handler = WSGIRequestHandler(request, '192.168.0.2', None)
+
+        _stderr = sys.stderr
+        sys.stderr = StringIO()
+        try:
+            handler.log_message("GET %s %s", str('\x16\x03'), "4")
+            self.assertIn(
+                "You're accessing the developement server over HTTPS, "
+                "but it only supports HTTP.",
+                sys.stderr.getvalue()
+            )
+        finally:
+            sys.stderr = _stderr
-- 
2.18.1