]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Make WSGIContainer work on python 3
authorBen Darnell <ben@bendarnell.com>
Sun, 29 May 2011 22:45:41 +0000 (15:45 -0700)
committerBen Darnell <ben@bendarnell.com>
Sun, 29 May 2011 22:45:41 +0000 (15:45 -0700)
tornado/httpserver.py
tornado/test/runtests.py
tornado/test/wsgi_test.py [new file with mode: 0644]
tornado/wsgi.py

index d361ee6dffdb3d45e4a589a1bcd64d8c3f31990c..7e6e2fa70ab31f3bc85d4bb5b65c1ed859a9e6cb 100644 (file)
@@ -362,7 +362,7 @@ class HTTPConnection(object):
 
     def _on_headers(self, data):
         try:
-            data = data.decode('latin1')
+            data = native_str(data.decode('latin1'))
             eol = data.find("\r\n")
             start_line = data[:eol]
             try:
index 683e9aa6848269c96710bf973354645230bde861..338eea7854c1e3d16d70c7e36e9fbd435383afb5 100755 (executable)
@@ -16,6 +16,7 @@ TEST_MODULES = [
     'tornado.test.template_test',
     'tornado.test.testing_test',
     'tornado.test.web_test',
+    'tornado.test.wsgi_test',
 ]
 
 def all():
diff --git a/tornado/test/wsgi_test.py b/tornado/test/wsgi_test.py
new file mode 100644 (file)
index 0000000..3d2ca68
--- /dev/null
@@ -0,0 +1,19 @@
+from wsgiref.validate import validator
+
+from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase
+from tornado.util import b
+from tornado.wsgi import WSGIApplication, WSGIContainer
+
+class WSGIContainerTest(AsyncHTTPTestCase, LogTrapTestCase):
+    def wsgi_app(self, environ, start_response):
+        status = "200 OK"
+        response_headers = [("Content-Type", "text/plain")]
+        start_response(status, response_headers)
+        return [b("Hello world!")]
+
+    def get_app(self):
+        return WSGIContainer(validator(self.wsgi_app))
+
+    def test_simple(self):
+        response = self.fetch("/")
+        self.assertEqual(response.body, b("Hello world!"))
index 7c261ffe4e9c61d5551dbf9f15e76bae4b7bb4a5..4b079f0d3bf8b2f40f6a9a32e941dd5f35063109 100644 (file)
@@ -50,7 +50,6 @@ frameworks on the Tornado HTTP server and I/O loop. See WSGIContainer for
 details and documentation.
 """
 
-import cStringIO
 import cgi
 import httplib
 import logging
@@ -62,6 +61,12 @@ import urllib
 from tornado import escape
 from tornado import httputil
 from tornado import web
+from tornado.util import b
+
+try:
+    from io import BytesIO  # python 3
+except ImportError:
+    from cStringIO import StringIO as BytesIO  # python 2
 
 class WSGIApplication(web.Application):
     """A WSGI-equivalent of web.Application.
@@ -226,7 +231,7 @@ class WSGIContainer(object):
         app_response = self.wsgi_application(
             WSGIContainer.environ(request), start_response)
         response.extend(app_response)
-        body = "".join(response)
+        body = b("").join(response)
         if hasattr(app_response, "close"):
             app_response.close()
         if not data: raise Exception("WSGI app did not call start_response")
@@ -242,12 +247,12 @@ class WSGIContainer(object):
         if "server" not in header_set:
             headers.append(("Server", "TornadoServer/%s" % tornado.version))
 
-        parts = ["HTTP/1.1 " + data["status"] + "\r\n"]
+        parts = [escape.utf8("HTTP/1.1 " + data["status"] + "\r\n")]
         for key, value in headers:
-            parts.append(escape.utf8(key) + ": " + escape.utf8(value) + "\r\n")
-        parts.append("\r\n")
+            parts.append(escape.utf8(key) + b(": ") + escape.utf8(value) + b("\r\n"))
+        parts.append(b("\r\n"))
         parts.append(body)
-        request.write("".join(parts))
+        request.write(b("").join(parts))
         request.finish()
         self._log(status_code, request)
 
@@ -267,11 +272,11 @@ class WSGIContainer(object):
             "QUERY_STRING": request.query,
             "REMOTE_ADDR": request.remote_ip,
             "SERVER_NAME": host,
-            "SERVER_PORT": port,
+            "SERVER_PORT": str(port),
             "SERVER_PROTOCOL": request.version,
             "wsgi.version": (1, 0),
             "wsgi.url_scheme": request.protocol,
-            "wsgi.input": cStringIO.StringIO(escape.utf8(request.body)),
+            "wsgi.input": BytesIO(escape.utf8(request.body)),
             "wsgi.errors": sys.stderr,
             "wsgi.multithread": False,
             "wsgi.multiprocess": True,