Skip to content

Commit

Permalink
do not drop extra packets included in first response
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Dec 15, 2018
1 parent d5cdc12 commit 0ffdb0a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 12 deletions.
11 changes: 5 additions & 6 deletions engineio/asyncio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,14 +171,10 @@ async def _connect_polling(self, url, headers, engineio_path):
except ValueError:
six.raise_from(exceptions.ConnectionError(
'Unexpected response from server'), None)
open_packet = [pkt for pkt in p.packets
if pkt.packet_type == packet.OPEN]
if open_packet == []:
open_packet = p.packets[0]
if open_packet.packet_type != packet.OPEN:
raise exceptions.ConnectionError(
'OPEN packet not returned by server')
if len(p.packets) > 1: # pragma: no cover
self.logger.info('extra packets found in server response')
open_packet = open_packet[0]
self.logger.info(
'Polling connection accepted with ' + str(open_packet.data))
self.sid = open_packet.data['sid']
Expand All @@ -192,6 +188,9 @@ async def _connect_polling(self, url, headers, engineio_path):
client.connected_clients.append(self)
await self._trigger_event('connect')

for pkt in p.packets[1:]:
await self._receive_packet(pkt)

if 'websocket' in self.upgrades and 'websocket' in self.transports:
# attempt to upgrade to websocket
if await self._connect_websocket(url, headers, engineio_path):
Expand Down
11 changes: 5 additions & 6 deletions engineio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,10 @@ def _connect_polling(self, url, headers, engineio_path):
except ValueError:
six.raise_from(exceptions.ConnectionError(
'Unexpected response from server'), None)
open_packet = [pkt for pkt in p.packets
if pkt.packet_type == packet.OPEN]
if open_packet == []:
open_packet = p.packets[0]
if open_packet.packet_type != packet.OPEN:
raise exceptions.ConnectionError(
'OPEN packet not returned by server')
if len(p.packets) > 1: # pragma: no cover
self.logger.info('extra packets found in server response')
open_packet = open_packet[0]
self.logger.info(
'Polling connection accepted with ' + str(open_packet.data))
self.sid = open_packet.data['sid']
Expand All @@ -290,6 +286,9 @@ def _connect_polling(self, url, headers, engineio_path):
connected_clients.append(self)
self._trigger_event('connect')

for pkt in p.packets[1:]:
self._receive_packet(pkt)

if 'websocket' in self.upgrades and 'websocket' in self.transports:
# attempt to upgrade to websocket
if self._connect_websocket(url, headers, engineio_path):
Expand Down
26 changes: 26 additions & 0 deletions tests/test_asyncio_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,32 @@ def test_polling_connection_successful(self):
self.assertEqual(c.upgrades, [])
self.assertEqual(c.transport(), 'polling')

def test_polling_connection_successful(self):
c = asyncio_client.AsyncClient()
c._send_request = AsyncMock()
c._send_request.mock.return_value.status = 200
c._send_request.mock.return_value.read = AsyncMock(
return_value=payload.Payload(packets=[
packet.Packet(packet.OPEN, {
'sid': '123', 'upgrades': [], 'pingInterval': 1000,
'pingTimeout': 2000
}),
packet.Packet(packet.NOOP)
]).encode())
c._ping_loop = AsyncMock()
c._read_loop_polling = AsyncMock()
c._read_loop_websocket = AsyncMock()
c._write_loop = AsyncMock()
c._receive_packet = AsyncMock()
on_connect = AsyncMock()
c.on('connect', on_connect)
_run(c.connect('http://foo'))
time.sleep(0.1)
c._receive_packet.mock.assert_called_once()
self.assertEqual(
c._receive_packet.mock.call_args_list[0][0][0].packet_type,
packet.NOOP)

def test_polling_connection_upgraded(self):
c = asyncio_client.AsyncClient()
c._send_request = AsyncMock()
Expand Down
25 changes: 25 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,31 @@ def test_polling_connection_successful(self, _send_request):
self.assertEqual(c.upgrades, [])
self.assertEqual(c.transport(), 'polling')

@mock.patch('engineio.client.Client._send_request')
def test_polling_connection_with_more_packets(self, _send_request):
_send_request.return_value.status = 200
_send_request.return_value.data = payload.Payload(packets=[
packet.Packet(packet.OPEN, {
'sid': '123', 'upgrades': [], 'pingInterval': 1000,
'pingTimeout': 2000
}),
packet.Packet(packet.NOOP)
]).encode()
c = client.Client()
c._ping_loop = mock.MagicMock()
c._read_loop_polling = mock.MagicMock()
c._read_loop_websocket = mock.MagicMock()
c._receive_packet = mock.MagicMock()
c._write_loop = mock.MagicMock()
on_connect = mock.MagicMock()
c.on('connect', on_connect)
c.connect('http://foo')
time.sleep(0.1)
c._receive_packet.assert_called_once()
self.assertEqual(
c._receive_packet.call_args_list[0][0][0].packet_type,
packet.NOOP)

@mock.patch('engineio.client.Client._send_request')
def test_polling_connection_upgraded(self, _send_request):
_send_request.return_value.status = 200
Expand Down

0 comments on commit 0ffdb0a

Please sign in to comment.