add always_connect option to previous fix optional · gitmit1/python-socketio@fe6b311 · GitHub
Skip to content

Commit fe6b311

Browse files
add always_connect option to previous fix optional
1 parent 0db35c8 commit fe6b311

4 files changed

Lines changed: 95 additions & 15 deletions

File tree

socketio/asyncio_server.py

Lines changed: 13 additions & 5 deletions

socketio/server.py

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ class Server(object):
3838
executed in separate threads. To run handlers for a
3939
client synchronously, set to ``False``. The default
4040
is ``True``.
41+
:param always_connect: When set to ``False``, new connections are
42+
provisory until the connect handler returns
43+
something other than ``False``, at which point they
44+
are accepted. When set to ``True``, connections are
45+
immediately accepted, and then if the connect
46+
handler returns ``False`` a disconnect is issued.
47+
Set to ``True`` if you need to emit events from the
48+
connect handler and your client is confused when it
49+
receives events before the connection acceptance.
50+
In any other case use the default of ``False``.
4151
:param kwargs: Connection parameters for the underlying Engine.IO server.
4252
4353
The Engine.IO configuration supports the following settings:
@@ -79,7 +89,8 @@ class Server(object):
7989
``False``. The default is ``False``.
8090
"""
8191
def __init__(self, client_manager=None, logger=False, binary=False,
82-
json=None, async_handlers=True, **kwargs):
92+
json=None, async_handlers=True, always_connect=False,
93+
**kwargs):
8394
engineio_options = kwargs
8495
engineio_logger = engineio_options.pop('engineio_logger', None)
8596
if engineio_logger is not None:
@@ -119,6 +130,7 @@ def __init__(self, client_manager=None, logger=False, binary=False,
119130
self.manager_initialized = False
120131

121132
self.async_handlers = async_handlers
133+
self.always_connect = always_connect
122134

123135
self.async_mode = self.eio.async_mode
124136

@@ -530,17 +542,26 @@ def _handle_connect(self, sid, namespace):
530542
"""Handle a client connection request."""
531543
namespace = namespace or '/'
532544
self.manager.connect(sid, namespace)
533-
self._send_packet(sid, packet.Packet(packet.CONNECT,
534-
namespace=namespace))
545+
if self.always_connect:
546+
self._send_packet(sid, packet.Packet(packet.CONNECT,
547+
namespace=namespace))
535548
if self._trigger_event('connect', namespace, sid,
536549
self.environ[sid]) is False:
537-
self.manager.pre_disconnect(sid, namespace)
538-
self._send_packet(sid, packet.Packet(packet.DISCONNECT,
539-
namespace=namespace))
550+
if self.always_connect:
551+
self.manager.pre_disconnect(sid, namespace)
552+
self._send_packet(sid, packet.Packet(packet.DISCONNECT,
553+
namespace=namespace))
540554
self.manager.disconnect(sid, namespace)
555+
if not self.always_connect:
556+
self._send_packet(sid, packet.Packet(packet.ERROR,
557+
namespace=namespace))
558+
541559
if sid in self.environ: # pragma: no cover
542560
del self.environ[sid]
543561
return False
562+
elif not self.always_connect:
563+
self._send_packet(sid, packet.Packet(packet.CONNECT,
564+
namespace=namespace))
544565

545566
def _handle_disconnect(self, sid, namespace):
546567
"""Handle a client disconnect."""

tests/asyncio/test_asyncio_server.py

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,7 @@ def test_handle_connect_rejected(self, eio):
295295
self.assertEqual(s.manager.connect.call_count, 1)
296296
self.assertEqual(s.manager.disconnect.call_count, 1)
297297
self.assertEqual(s.environ, {})
298-
s.eio.send.mock.assert_any_call('123', '0', binary=False)
299-
s.eio.send.mock.assert_any_call('123', '1', binary=False)
298+
s.eio.send.mock.assert_called_once_with('123', '4', binary=False)
300299

301300
def test_handle_connect_namespace_rejected(self, eio):
302301
eio.return_value.send = AsyncMock()
@@ -309,6 +308,35 @@ def test_handle_connect_namespace_rejected(self, eio):
309308
self.assertEqual(s.manager.connect.call_count, 2)
310309
self.assertEqual(s.manager.disconnect.call_count, 1)
311310
self.assertEqual(s.environ, {})
311+
s.eio.send.mock.assert_any_call('123', '4/foo', binary=False)
312+
313+
def test_handle_connect_rejected_always_connect(self, eio):
314+
eio.return_value.send = AsyncMock()
315+
mgr = self._get_mock_manager()
316+
s = asyncio_server.AsyncServer(client_manager=mgr,
317+
always_connect=True)
318+
handler = mock.MagicMock(return_value=False)
319+
s.on('connect', handler)
320+
_run(s._handle_eio_connect('123', 'environ'))
321+
handler.assert_called_once_with('123', 'environ')
322+
self.assertEqual(s.manager.connect.call_count, 1)
323+
self.assertEqual(s.manager.disconnect.call_count, 1)
324+
self.assertEqual(s.environ, {})
325+
s.eio.send.mock.assert_any_call('123', '0', binary=False)
326+
s.eio.send.mock.assert_any_call('123', '1', binary=False)
327+
328+
def test_handle_connect_namespace_rejected_always_connect(self, eio):
329+
eio.return_value.send = AsyncMock()
330+
mgr = self._get_mock_manager()
331+
s = asyncio_server.AsyncServer(client_manager=mgr,
332+
always_connect=True)
333+
handler = mock.MagicMock(return_value=False)
334+
s.on('connect', handler, namespace='/foo')
335+
_run(s._handle_eio_connect('123', 'environ'))
336+
_run(s._handle_eio_message('123', '0/foo'))
337+
self.assertEqual(s.manager.connect.call_count, 2)
338+
self.assertEqual(s.manager.disconnect.call_count, 1)
339+
self.assertEqual(s.environ, {})
312340
s.eio.send.mock.assert_any_call('123', '0/foo', binary=False)
313341
s.eio.send.mock.assert_any_call('123', '1/foo', binary=False)
314342

tests/common/test_server.py

Lines changed: 25 additions & 2 deletions

0 commit comments

Comments
 (0)