Fix the race condition with novnc
The first RFP negotiation message potentially arrived earlier, in which case the message will be swallowed by the recv() which receive response for the http request. This commit is to ensure only the response is removed from the socket buffer, so it won't impact the following RFP negotiation. Change-Id: I100e140acbc2d981f7b98e12b3e9ae02844f41fd Closes-Bug: #1695844
This commit is contained in:
committed by
Jianghua Wang
parent
3d84232d7b
commit
a7c054c551
@@ -147,12 +147,15 @@ class NovaProxyRequestHandlerBase(object):
|
||||
if connect_info.get('internal_access_path'):
|
||||
tsock.send("CONNECT %s HTTP/1.1\r\n\r\n" %
|
||||
connect_info['internal_access_path'])
|
||||
end_token = "\r\n\r\n"
|
||||
while True:
|
||||
data = tsock.recv(4096, socket.MSG_PEEK)
|
||||
if data.find("\r\n\r\n") != -1:
|
||||
token_loc = data.find(end_token)
|
||||
if token_loc != -1:
|
||||
if data.split("\r\n")[0].find("200") == -1:
|
||||
raise exception.InvalidConnectionInfo()
|
||||
tsock.recv(len(data))
|
||||
# remove the response from recv buffer
|
||||
tsock.recv(token_loc + len(end_token))
|
||||
break
|
||||
|
||||
# Start proxying
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
import mock
|
||||
|
||||
import socket
|
||||
|
||||
from nova.console import websocketproxy
|
||||
from nova import exception
|
||||
from nova import test
|
||||
@@ -180,6 +182,35 @@ class NovaProxyRequestHandlerBaseTestCase(test.NoDBTestCase):
|
||||
self.wh.new_websocket_client)
|
||||
check_token.assert_called_with(mock.ANY, token="123-456-789")
|
||||
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
|
||||
def test_new_websocket_client_internal_access_path_rfb(self, check_token):
|
||||
check_token.return_value = {
|
||||
'host': 'node1',
|
||||
'port': '10000',
|
||||
'internal_access_path': 'vmid',
|
||||
'console_type': 'novnc',
|
||||
'access_url': 'https://example.net:6080'
|
||||
}
|
||||
|
||||
tsock = mock.MagicMock()
|
||||
HTTP_RESP = "HTTP/1.1 200 OK\r\n\r\n"
|
||||
RFB_MSG = "RFB 003.003\n"
|
||||
# RFB negotiation message may arrive earlier.
|
||||
tsock.recv.side_effect = [HTTP_RESP + RFB_MSG,
|
||||
HTTP_RESP]
|
||||
|
||||
self.wh.socket.return_value = tsock
|
||||
self.wh.path = "http://127.0.0.1/?token=123-456-789"
|
||||
self.wh.headers = self.fake_header
|
||||
|
||||
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)
|
||||
tsock.recv.assert_has_calls([mock.call(4096, socket.MSG_PEEK),
|
||||
mock.call(len(HTTP_RESP))])
|
||||
self.wh.do_proxy.assert_called_with(tsock)
|
||||
|
||||
@mock.patch.object(websocketproxy, 'sys')
|
||||
@mock.patch('nova.consoleauth.rpcapi.ConsoleAuthAPI.check_token')
|
||||
def test_new_websocket_client_py273_good_scheme(
|
||||
|
||||
Reference in New Issue
Block a user