Skip to content

Commit efe87d8

Browse files
Add namespaces argument to Server and AsyncServer (Fixes #822)
1 parent d4e69fb commit efe87d8

File tree

4 files changed

+59
-7
lines changed

4 files changed

+59
-7
lines changed

src/socketio/asyncio_server.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ class AsyncServer(server.Server):
4040
connect handler and your client is confused when it
4141
receives events before the connection acceptance.
4242
In any other case use the default of ``False``.
43+
:param namespaces: a list of namespaces that are accepted, in addition to
44+
any namespaces for which handlers have been defined. The
45+
default is `['/']`, which always accepts connections to
46+
the default namespace. Set to `'*'` to accept all
47+
namespaces.
4348
:param kwargs: Connection parameters for the underlying Engine.IO server.
4449
4550
The Engine.IO configuration supports the following settings:
@@ -97,11 +102,12 @@ class AsyncServer(server.Server):
97102
``engineio_logger`` is ``False``.
98103
"""
99104
def __init__(self, client_manager=None, logger=False, json=None,
100-
async_handlers=True, **kwargs):
105+
async_handlers=True, namespaces=None, **kwargs):
101106
if client_manager is None:
102107
client_manager = asyncio_manager.AsyncManager()
103108
super().__init__(client_manager=client_manager, logger=logger,
104-
json=json, async_handlers=async_handlers, **kwargs)
109+
json=json, async_handlers=async_handlers,
110+
namespaces=namespaces, **kwargs)
105111

106112
def is_asyncio_based(self):
107113
return True
@@ -443,7 +449,8 @@ async def _handle_connect(self, eio_sid, namespace, data):
443449
"""Handle a client connection request."""
444450
namespace = namespace or '/'
445451
sid = None
446-
if namespace in self.handlers or namespace in self.namespace_handlers:
452+
if namespace in self.handlers or namespace in self.namespace_handlers \
453+
or self.namespaces == '*' or namespace in self.namespaces:
447454
sid = self.manager.connect(eio_sid, namespace)
448455
if sid is None:
449456
await self._send_packet(eio_sid, self.packet_class(

src/socketio/server.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ class Server(object):
4949
connect handler and your client is confused when it
5050
receives events before the connection acceptance.
5151
In any other case use the default of ``False``.
52+
:param namespaces: a list of namespaces that are accepted, in addition to
53+
any namespaces for which handlers have been defined. The
54+
default is `['/']`, which always accepts connections to
55+
the default namespace. Set to `'*'` to accept all
56+
namespaces.
5257
:param kwargs: Connection parameters for the underlying Engine.IO server.
5358
5459
The Engine.IO configuration supports the following settings:
@@ -110,7 +115,7 @@ class Server(object):
110115

111116
def __init__(self, client_manager=None, logger=False, serializer='default',
112117
json=None, async_handlers=True, always_connect=False,
113-
**kwargs):
118+
namespaces=None, **kwargs):
114119
engineio_options = kwargs
115120
engineio_logger = engineio_options.pop('engineio_logger', None)
116121
if engineio_logger is not None:
@@ -157,6 +162,7 @@ def __init__(self, client_manager=None, logger=False, serializer='default',
157162

158163
self.async_handlers = async_handlers
159164
self.always_connect = always_connect
165+
self.namespaces = namespaces or ['/']
160166

161167
self.async_mode = self.eio.async_mode
162168

@@ -650,7 +656,8 @@ def _handle_connect(self, eio_sid, namespace, data):
650656
"""Handle a client connection request."""
651657
namespace = namespace or '/'
652658
sid = None
653-
if namespace in self.handlers or namespace in self.namespace_handlers:
659+
if namespace in self.handlers or namespace in self.namespace_handlers \
660+
or self.namespaces == '*' or namespace in self.namespaces:
654661
sid = self.manager.connect(eio_sid, namespace)
655662
if sid is None:
656663
self._send_packet(eio_sid, self.packet_class(

tests/asyncio/test_asyncio_server.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,12 +425,32 @@ def test_handle_connect_async(self, eio):
425425
_run(s._handle_eio_message('456', '0'))
426426
assert s.manager.initialize.call_count == 1
427427

428-
def test_handle_connect_with_bad_namespace(self, eio):
428+
def test_handle_connect_with_default_implied_namespaces(self, eio):
429429
eio.return_value.send = AsyncMock()
430430
s = asyncio_server.AsyncServer()
431431
_run(s._handle_eio_connect('123', 'environ'))
432432
_run(s._handle_eio_message('123', '0'))
433+
_run(s._handle_eio_message('123', '0/foo,'))
434+
assert s.manager.is_connected('1', '/')
435+
assert not s.manager.is_connected('2', '/foo')
436+
437+
def test_handle_connect_with_implied_namespaces(self, eio):
438+
eio.return_value.send = AsyncMock()
439+
s = asyncio_server.AsyncServer(namespaces=['/foo'])
440+
_run(s._handle_eio_connect('123', 'environ'))
441+
_run(s._handle_eio_message('123', '0'))
442+
_run(s._handle_eio_message('123', '0/foo,'))
433443
assert not s.manager.is_connected('1', '/')
444+
assert s.manager.is_connected('1', '/foo')
445+
446+
def test_handle_connect_with_all_implied_namespaces(self, eio):
447+
eio.return_value.send = AsyncMock()
448+
s = asyncio_server.AsyncServer(namespaces='*')
449+
_run(s._handle_eio_connect('123', 'environ'))
450+
_run(s._handle_eio_message('123', '0'))
451+
_run(s._handle_eio_message('123', '0/foo,'))
452+
assert s.manager.is_connected('1', '/')
453+
assert s.manager.is_connected('2', '/foo')
434454

435455
def test_handle_connect_namespace(self, eio):
436456
eio.return_value.send = AsyncMock()

tests/common/test_server.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,11 +356,29 @@ def test_handle_connect_with_auth_none(self, eio):
356356
s._handle_eio_connect('456', 'environ')
357357
assert s.manager.initialize.call_count == 1
358358

359-
def test_handle_connect_with_bad_namespace(self, eio):
359+
def test_handle_connect_with_default_implied_namespaces(self, eio):
360360
s = server.Server()
361361
s._handle_eio_connect('123', 'environ')
362362
s._handle_eio_message('123', '0')
363+
s._handle_eio_message('123', '0/foo,')
364+
assert s.manager.is_connected('1', '/')
365+
assert not s.manager.is_connected('2', '/foo')
366+
367+
def test_handle_connect_with_implied_namespaces(self, eio):
368+
s = server.Server(namespaces=['/foo'])
369+
s._handle_eio_connect('123', 'environ')
370+
s._handle_eio_message('123', '0')
371+
s._handle_eio_message('123', '0/foo,')
363372
assert not s.manager.is_connected('1', '/')
373+
assert s.manager.is_connected('1', '/foo')
374+
375+
def test_handle_connect_with_all_implied_namespaces(self, eio):
376+
s = server.Server(namespaces='*')
377+
s._handle_eio_connect('123', 'environ')
378+
s._handle_eio_message('123', '0')
379+
s._handle_eio_message('123', '0/foo,')
380+
assert s.manager.is_connected('1', '/')
381+
assert s.manager.is_connected('2', '/foo')
364382

365383
def test_handle_connect_namespace(self, eio):
366384
s = server.Server()

0 commit comments

Comments
 (0)