Skip to content

Commit

Permalink
Return error packet if client connects to an already connected namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Jul 22, 2021
1 parent e5e7c8e commit cb1b8ec
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/socketio/base_manager.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import itertools
import logging

from bidict import bidict
from bidict import bidict, ValueDuplicationError

default_logger = logging.getLogger('socketio')

Expand Down Expand Up @@ -51,7 +51,11 @@ def get_participants(self, namespace, room):
def connect(self, eio_sid, namespace):
"""Register a client connection to a namespace."""
sid = self.server.eio.generate_id()
self.enter_room(sid, namespace, None, eio_sid=eio_sid)
try:
self.enter_room(sid, namespace, None, eio_sid=eio_sid)
except ValueDuplicationError:
# already connected
return None
self.enter_room(sid, namespace, sid, eio_sid=eio_sid)
return sid

Expand Down
6 changes: 6 additions & 0 deletions src/socketio/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,12 @@ def _handle_connect(self, eio_sid, namespace, data):
"""Handle a client connection request."""
namespace = namespace or '/'
sid = self.manager.connect(eio_sid, namespace)
if sid is None:
self._send_packet(eio_sid, self.packet_class(
packet.CONNECT_ERROR, data='Unable to connect',
namespace=namespace))
return

if self.always_connect:
self._send_packet(eio_sid, self.packet_class(
packet.CONNECT, {'sid': sid}, namespace=namespace))
Expand Down
13 changes: 13 additions & 0 deletions tests/common/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,19 @@ def test_handle_connect_namespace(self, eio):
handler.assert_called_once_with('1', 'environ')
s.eio.send.assert_called_once_with('123', '0/foo,{"sid":"1"}')

def test_handle_connect_namespace_twice(self, eio):
s = server.Server()
handler = mock.MagicMock()
s.on('connect', handler, namespace='/foo')
s._handle_eio_connect('123', 'environ')
s._handle_eio_message('123', '0/foo,')
s._handle_eio_message('123', '0/foo,')
assert s.manager.is_connected('1', '/foo')
handler.assert_called_once_with('1', 'environ')
s.eio.send.assert_any_call('123', '0/foo,{"sid":"1"}')
print(s.eio.send.call_args_list)
s.eio.send.assert_any_call('123', '4/foo,"Unable to connect"')

def test_handle_connect_always_connect(self, eio):
s = server.Server(always_connect=True)
s.manager.initialize = mock.MagicMock()
Expand Down

0 comments on commit cb1b8ec

Please sign in to comment.