console: make unsupported ws scheme in python < 2.7.4
Due to a bug in python < 2.7.4, urlparse won't parse a query string
in a URL where the scheme is not recognized:
http://bugs.python.org/issue9374
Commit 1dda5ef75a added some tests for
websocketproxy that uses urlparse to get a token but these don't work
on python < 2.7.4 since the scheme in the tests is "ws://".
In the actual code, raise an exception if python < 2.7.4 and an
unsupported URL scheme is used.
DocImpact: The "getting-started-with-vnc-proxy" page in the
"admin-guide-cloud" docs should be updated with a note that the web
proxy console URLs do not support the websocket protocol scheme (ws://)
on python versions less than 2.7.4.
Change-Id: Ib6e0fc4e50c1ea144a9c538099e23597d66b429b
Closes-Bug: #1376078
			
			
This commit is contained in:
		
				
					committed by
					
						
						sahid
					
				
			
			
				
	
			
			
			
						parent
						
							19053add4d
						
					
				
				
					commit
					542d885874
				
			@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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,7 +117,40 @@ 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, self.wh.new_websocket_client)  # noqa
 | 
			
		||||
        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)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user