From 49585adddbaceac220e5633ae11e4d1f73414596 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 18 Aug 2015 16:03:51 -0700 Subject: [PATCH] Fix Python 3 issues in wsgi Fix unicode versus bytes issues in wsgi code, a HTTP body is a bytes string. Changes: * On Python 3, encode JSON to UTF-8. * Replace file() with open(); file() was removed in Python 3. * Use literal byte strings (b'...') for HTTP body. * Use binary instead of text mode for HTTP body when getting a file from a socket (sock.makefile). Blueprint cinder-python3 Change-Id: If46e0060371f5eb00fd33d5b58ec236d1ff4ace1 --- cinder/api/openstack/wsgi.py | 5 ++- .../tests/unit/wsgi/test_eventlet_server.py | 33 ++++++++++++------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/cinder/api/openstack/wsgi.py b/cinder/api/openstack/wsgi.py index fdb752c35..54af9801e 100644 --- a/cinder/api/openstack/wsgi.py +++ b/cinder/api/openstack/wsgi.py @@ -1336,7 +1336,10 @@ class Fault(webob.exc.HTTPException): 'application/json': JSONDictSerializer(), }[content_type] - self.wrapped_exc.body = serializer.serialize(fault_data) + body = serializer.serialize(fault_data) + if isinstance(body, six.text_type): + body = body.encode('utf-8') + self.wrapped_exc.body = body self.wrapped_exc.content_type = content_type _set_request_id_header(req, self.wrapped_exc.headers) diff --git a/cinder/tests/unit/wsgi/test_eventlet_server.py b/cinder/tests/unit/wsgi/test_eventlet_server.py index c014deb27..600cd7e68 100644 --- a/cinder/tests/unit/wsgi/test_eventlet_server.py +++ b/cinder/tests/unit/wsgi/test_eventlet_server.py @@ -26,6 +26,7 @@ import time import mock from oslo_config import cfg from oslo_i18n import fixture as i18n_fixture +import six from six.moves import urllib import testtools import webob @@ -110,7 +111,7 @@ class TestWSGIServer(test.TestCase): """WSGI server tests.""" def _ipv6_configured(): try: - with file('/proc/net/if_inet6') as f: + with open('/proc/net/if_inet6') as f: return len(f.read()) > 0 except IOError: return False @@ -151,7 +152,7 @@ class TestWSGIServer(test.TestCase): mock_waitall.assert_called_once_with() def test_app(self): - greetings = 'Hello, World!!!' + greetings = b'Hello, World!!!' def hello_world(env, start_response): if env['PATH_INFO'] != '/': @@ -171,7 +172,7 @@ class TestWSGIServer(test.TestCase): def test_client_socket_timeout(self): CONF.set_default("client_socket_timeout", 0.1) - greetings = 'Hello, World!!!' + greetings = b'Hello, World!!!' def hello_world(env, start_response): start_response('200 OK', [('Content-Type', 'text/plain')]) @@ -184,7 +185,7 @@ class TestWSGIServer(test.TestCase): s = socket.socket() s.connect(("127.0.0.1", server.port)) - fd = s.makefile('rw') + fd = s.makefile('rwb') fd.write(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.flush() @@ -195,7 +196,7 @@ class TestWSGIServer(test.TestCase): s2.connect(("127.0.0.1", server.port)) time.sleep(0.2) - fd = s2.makefile('rw') + fd = s2.makefile('rwb') fd.write(b'GET / HTTP/1.1\r\nHost: localhost\r\n\r\n') fd.flush() @@ -290,10 +291,10 @@ class ExceptionTest(test.TestCase): api = self._wsgi_app(fail) resp = webob.Request.blank('/').get_response(api) - self.assertIn('{"computeFault', resp.body) - expected = ('ExceptionWithSafety: some explanation' if expose else - 'The server has either erred or is incapable ' - 'of performing the requested operation.') + self.assertIn(b'{"computeFault', resp.body) + expected = (b'ExceptionWithSafety: some explanation' if expose else + b'The server has either erred or is incapable ' + b'of performing the requested operation.') self.assertIn(expected, resp.body) self.assertEqual(500, resp.status_int, resp.body) @@ -310,7 +311,9 @@ class ExceptionTest(test.TestCase): api = self._wsgi_app(fail) resp = webob.Request.blank('/').get_response(api) - self.assertIn(msg, resp.body) + msg_body = (msg.encode('utf-8') if isinstance(msg, six.text_type) + else msg) + self.assertIn(msg_body, resp.body) self.assertEqual(exception_type.code, resp.status_int, resp.body) if hasattr(exception_type, 'headers'): @@ -370,7 +373,9 @@ class ExceptionTest(test.TestCase): api = self._wsgi_app(fail) resp = webob.Request.blank('/').get_response(api) self.assertEqual(404, resp.status_int) - self.assertIn(msg, resp.body) + msg_body = (msg.encode('utf-8') if isinstance(msg, six.text_type) + else msg) + self.assertIn(msg_body, resp.body) # Test response with localization def mock_translate(msgid, locale): @@ -381,4 +386,8 @@ class ExceptionTest(test.TestCase): api = self._wsgi_app(fail) resp = webob.Request.blank('/').get_response(api) self.assertEqual(404, resp.status_int) - self.assertIn(msg_translation, resp.body) + if isinstance(msg_translation, six.text_type): + msg_body = msg_translation.encode('utf-8') + else: + msg_body = msg_translation + self.assertIn(msg_body, resp.body) -- 2.45.2