diff options
-rw-r--r-- | nova/console/websocketproxy.py | 12 | ||||
-rw-r--r-- | nova/tests/console/test_websocketproxy.py | 41 |
2 files changed, 48 insertions, 5 deletions
diff --git a/nova/console/websocketproxy.py b/nova/console/websocketproxy.py index b2c3d0b59d..4d32ff4328 100644 --- a/nova/console/websocketproxy.py +++ b/nova/console/websocketproxy.py @@ -20,6 +20,7 @@ Leverages websockify.py by Joel Martin import Cookie import socket +import sys import urlparse import websockify @@ -43,7 +44,16 @@ class NovaProxyRequestHandlerBase(object): # The nova expected behavior is to have token # passed to the method GET of the request - query = urlparse.urlparse(self.path).query + parse = urlparse.urlparse(self.path) + if parse.scheme not in ('http', 'https'): + # From a bug in urlparse in Python < 2.7.4 we cannot support + # special schemes (cf: http://bugs.python.org/issue9374) + if sys.version_info < (2, 7, 4): + raise exception.NovaException( + _("We do not support scheme '%s' under Python < 2.7.4, " + "please use http or https") % parse.scheme) + + query = parse.query token = urlparse.parse_qs(query).get("token", [""]).pop() if not token: # NoVNC uses it's own convention that forward token diff --git a/nova/tests/console/test_websocketproxy.py b/nova/tests/console/test_websocketproxy.py index cb0f3ec162..c0526a2cf1 100644 --- a/nova/tests/console/test_websocketproxy.py +++ b/nova/tests/console/test_websocketproxy.py @@ -40,7 +40,7 @@ class NovaProxyRequestHandlerBaseTestCase(test.TestCase): 'port': '10000' } self.wh.socket.return_value = '<socket>' - self.wh.path = "ws://127.0.0.1/?token=123-456-789" + self.wh.path = "http://127.0.0.1/?token=123-456-789" self.wh.new_websocket_client() @@ -52,7 +52,7 @@ class NovaProxyRequestHandlerBaseTestCase(test.TestCase): def test_new_websocket_client_token_invalid(self, check_token): check_token.return_value = False - self.wh.path = "ws://127.0.0.1/?token=XXX" + self.wh.path = "http://127.0.0.1/?token=XXX" self.assertRaises(exception.InvalidToken, self.wh.new_websocket_client) @@ -97,7 +97,7 @@ class NovaProxyRequestHandlerBaseTestCase(test.TestCase): tsock.recv.return_value = "HTTP/1.1 200 OK\r\n\r\n" self.wh.socket.return_value = tsock - self.wh.path = "ws://127.0.0.1/?token=123-456-789" + self.wh.path = "http://127.0.0.1/?token=123-456-789" self.wh.new_websocket_client() @@ -117,8 +117,41 @@ class NovaProxyRequestHandlerBaseTestCase(test.TestCase): tsock.recv.return_value = "HTTP/1.1 500 Internal Server Error\r\n\r\n" self.wh.socket.return_value = tsock - self.wh.path = "ws://127.0.0.1/?token=123-456-789" + self.wh.path = "http://127.0.0.1/?token=123-456-789" self.assertRaises(exception.InvalidConnectionInfo, self.wh.new_websocket_client) check_token.assert_called_with(mock.ANY, token="123-456-789") + + @mock.patch('sys.version_info') + @mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token') + def test_new_websocket_client_py273_good_scheme( + self, check_token, version_info): + version_info.return_value = (2, 7, 3) + check_token.return_value = { + 'host': 'node1', + 'port': '10000' + } + self.wh.socket.return_value = '<socket>' + self.wh.path = "http://127.0.0.1/?token=123-456-789" + + self.wh.new_websocket_client() + + check_token.assert_called_with(mock.ANY, token="123-456-789") + self.wh.socket.assert_called_with('node1', 10000, connect=True) + self.wh.do_proxy.assert_called_with('<socket>') + + @mock.patch('sys.version_info') + @mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token') + def test_new_websocket_client_py273_special_scheme( + self, check_token, version_info): + version_info.return_value = (2, 7, 3) + check_token.return_value = { + 'host': 'node1', + 'port': '10000' + } + self.wh.socket.return_value = '<socket>' + self.wh.path = "ws://127.0.0.1/?token=123-456-789" + + self.assertRaises(exception.NovaException, + self.wh.new_websocket_client) |