Browse Source

Do not invoke reserved events on a catch-all handler (Fixes #814)

pull/844/head
Miguel Grinberg 3 years ago
parent
commit
34f34e53d6
No known key found for this signature in database GPG Key ID: 36848B262DF5F06C
  1. 11
      docs/client.rst
  2. 3
      docs/server.rst
  3. 3
      src/socketio/asyncio_client.py
  4. 3
      src/socketio/asyncio_server.py
  5. 5
      src/socketio/client.py
  6. 5
      src/socketio/server.py
  7. 1
      tests/asyncio/test_asyncio_client.py
  8. 1
      tests/common/test_client.py

11
docs/client.rst

@ -65,6 +65,9 @@ or can also be coroutines::
async def message(data):
print('I received a message!')
If the server includes arguments with an event, those are passed to the
handler function as arguments.
Catch-All Event Handlers
------------------------
@ -72,13 +75,13 @@ A "catch-all" event handler is invoked for any events that do not have an
event handler. You can define a catch-all handler using ``'*'`` as event name::
@sio.on('*')
def catch_all(event, sid, data):
def catch_all(event, data):
pass
Asyncio clients can also use a coroutine::
@sio.on('*')
async def catch_all(event, sid, data):
async def catch_all(event, data):
pass
A catch-all event handler receives the event name as a first argument. The
@ -115,8 +118,8 @@ going to attempt to reconnect immediately after invoking the disconnect
handler. As soon as the connection is re-established the connect handler will
be invoked once again.
If the server includes arguments with an event, those are passed to the
handler function as arguments.
The ``connect``, ``connect_error`` and ``disconnect`` events have to be
defined explicitly and are not invoked on a catch-all event handler.
Connecting to a Server
----------------------

3
docs/server.rst

@ -197,6 +197,9 @@ Asyncio servers can also use a coroutine::
A catch-all event handler receives the event name as a first argument. The
remaining arguments are the same as for a regular event handler.
The ``connect`` and ``disconnect`` events have to be defined explicitly and are
not invoked on a catch-all event handler.
Connect and Disconnect Event Handlers
-------------------------------------

3
src/socketio/asyncio_client.py

@ -431,7 +431,8 @@ class AsyncClient(client.Client):
handler = None
if event in self.handlers[namespace]:
handler = self.handlers[namespace][event]
elif '*' in self.handlers[namespace]:
elif event not in self.reserved_events and \
'*' in self.handlers[namespace]:
handler = self.handlers[namespace]['*']
args = (event, *args)
if handler:

3
src/socketio/asyncio_server.py

@ -532,7 +532,8 @@ class AsyncServer(server.Server):
handler = None
if event in self.handlers[namespace]:
handler = self.handlers[namespace][event]
elif '*' in self.handlers[namespace]:
elif event not in self.reserved_events and \
'*' in self.handlers[namespace]:
handler = self.handlers[namespace]['*']
args = (event, *args)
if handler:

5
src/socketio/client.py

@ -92,6 +92,8 @@ class Client(object):
fatal errors are logged even when
``engineio_logger`` is ``False``.
"""
reserved_events = ['connect', 'connect_error', 'disconnect']
def __init__(self, reconnection=True, reconnection_attempts=0,
reconnection_delay=1, reconnection_delay_max=5,
randomization_factor=0.5, logger=False, serializer='default',
@ -625,7 +627,8 @@ class Client(object):
if namespace in self.handlers:
if event in self.handlers[namespace]:
return self.handlers[namespace][event](*args)
elif '*' in self.handlers[namespace]:
elif event not in self.reserved_events and \
'*' in self.handlers[namespace]:
return self.handlers[namespace]['*'](event, *args)
# or else, forward the event to a namespace handler if one exists

5
src/socketio/server.py

@ -106,6 +106,8 @@ class Server(object):
fatal errors are logged even when
``engineio_logger`` is ``False``.
"""
reserved_events = ['connect', 'disconnect']
def __init__(self, client_manager=None, logger=False, serializer='default',
json=None, async_handlers=True, always_connect=False,
**kwargs):
@ -741,7 +743,8 @@ class Server(object):
if namespace in self.handlers:
if event in self.handlers[namespace]:
return self.handlers[namespace][event](*args)
elif '*' in self.handlers[namespace]:
elif event not in self.reserved_events and \
'*' in self.handlers[namespace]:
return self.handlers[namespace]['*'](event, *args)
# or else, forward the event to a namespace handler if one exists

1
tests/asyncio/test_asyncio_client.py

@ -838,6 +838,7 @@ class TestAsyncClient(unittest.TestCase):
c.on('*', catchall_handler)
_run(c._trigger_event('foo', '/', 1, '2'))
_run(c._trigger_event('bar', '/', 1, '2', 3))
_run(c._trigger_event('connect', '/')) # should not trigger
handler.assert_called_once_with(1, '2')
catchall_handler.assert_called_once_with('bar', 1, '2', 3)

1
tests/common/test_client.py

@ -943,6 +943,7 @@ class TestClient(unittest.TestCase):
c.on('*', catchall_handler)
c._trigger_event('foo', '/', 1, '2')
c._trigger_event('bar', '/', 1, '2', 3)
c._trigger_event('connect', '/') # should not trigger
handler.assert_called_once_with(1, '2')
catchall_handler.assert_called_once_with('bar', 1, '2', 3)

Loading…
Cancel
Save