Skip to content

Commit 8d1aeb2

Browse files
Correct use of a trailing comma in Socket.IO packets with no id or data (Fixes #671)
1 parent a07eedf commit 8d1aeb2

File tree

4 files changed

+32
-39
lines changed

4 files changed

+32
-39
lines changed

socketio/packet.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ class Packet(object):
1515
# packet type: 1 byte, values 0-6
1616
# num_attachments: ASCII encoded, only if num_attachments != 0
1717
# '-': only if num_attachments != 0
18-
# namespace: only if namespace != '/'
19-
# ',': only if namespace and one of id and data are defined in this packet
18+
# namespace, followed by a ',': only if namespace != '/'
2019
# id: ASCII encoded, only if id is not None
2120
# data: JSON dump of data payload
2221

@@ -54,18 +53,11 @@ def encode(self):
5453
else:
5554
data = self.data
5655
attachments = None
57-
needs_comma = False
5856
if self.namespace is not None and self.namespace != '/':
59-
encoded_packet += self.namespace
60-
needs_comma = True
57+
encoded_packet += self.namespace + ','
6158
if self.id is not None:
62-
if needs_comma:
63-
encoded_packet += ','
64-
needs_comma = False
6559
encoded_packet += str(self.id)
6660
if data is not None:
67-
if needs_comma:
68-
encoded_packet += ','
6961
encoded_packet += self.json.dumps(data, separators=(',', ':'))
7062
if attachments is not None:
7163
encoded_packet = [encoded_packet] + attachments

tests/asyncio/test_asyncio_server.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ def test_handle_connect_namespace(self, eio):
431431
handler = mock.MagicMock()
432432
s.on('connect', handler, namespace='/foo')
433433
_run(s._handle_eio_connect('123', 'environ'))
434-
_run(s._handle_eio_message('123', '0/foo'))
434+
_run(s._handle_eio_message('123', '0/foo,'))
435435
assert s.manager.is_connected('1', '/foo')
436436
handler.assert_called_once_with('1', 'environ')
437437
s.eio.send.mock.assert_called_once_with('123', '0/foo,{"sid":"1"}')
@@ -471,7 +471,7 @@ def test_handle_connect_namespace_rejected(self, eio):
471471
handler = mock.MagicMock(return_value=False)
472472
s.on('connect', handler, namespace='/foo')
473473
_run(s._handle_eio_connect('123', 'environ'))
474-
_run(s._handle_eio_message('123', '0/foo'))
474+
_run(s._handle_eio_message('123', '0/foo,'))
475475
assert not s.manager.is_connected('1', '/foo')
476476
handler.assert_called_once_with('1', 'environ')
477477
s.eio.send.mock.assert_any_call(
@@ -498,7 +498,7 @@ def test_handle_connect_namespace_rejected_always_connect(self, eio):
498498
handler = mock.MagicMock(return_value=False)
499499
s.on('connect', handler, namespace='/foo')
500500
_run(s._handle_eio_connect('123', 'environ'))
501-
_run(s._handle_eio_message('123', '0/foo'))
501+
_run(s._handle_eio_message('123', '0/foo,'))
502502
assert not s.manager.is_connected('1', '/foo')
503503
handler.assert_called_once_with('1', 'environ')
504504
s.eio.send.mock.assert_any_call('123', '0/foo,{"sid":"1"}')
@@ -545,7 +545,7 @@ def test_handle_connect_namespace_rejected_with_exception(self, eio):
545545
)
546546
s.on('connect', handler, namespace='/foo')
547547
_run(s._handle_eio_connect('123', 'environ'))
548-
_run(s._handle_eio_message('123', '0/foo'))
548+
_run(s._handle_eio_message('123', '0/foo,'))
549549
assert not s.manager.is_connected('1', '/foo')
550550
handler.assert_called_once_with('1', 'environ')
551551
s.eio.send.mock.assert_called_once_with(
@@ -560,7 +560,7 @@ def test_handle_connect_namespace_rejected_with_empty_exception(self, eio):
560560
)
561561
s.on('connect', handler, namespace='/foo')
562562
_run(s._handle_eio_connect('123', 'environ'))
563-
_run(s._handle_eio_message('123', '0/foo'))
563+
_run(s._handle_eio_message('123', '0/foo,'))
564564
assert not s.manager.is_connected('1', '/foo')
565565
handler.assert_called_once_with('1', 'environ')
566566
s.eio.send.mock.assert_called_once_with(
@@ -588,7 +588,7 @@ def test_handle_disconnect_namespace(self, eio):
588588
handler_namespace = mock.MagicMock()
589589
s.on('disconnect', handler_namespace, namespace='/foo')
590590
_run(s._handle_eio_connect('123', 'environ'))
591-
_run(s._handle_eio_message('123', '0/foo'))
591+
_run(s._handle_eio_message('123', '0/foo,'))
592592
_run(s._handle_eio_disconnect('123'))
593593
handler.assert_not_called()
594594
handler_namespace.assert_called_once_with('1')
@@ -602,8 +602,8 @@ def test_handle_disconnect_only_namespace(self, eio):
602602
handler_namespace = mock.MagicMock()
603603
s.on('disconnect', handler_namespace, namespace='/foo')
604604
_run(s._handle_eio_connect('123', 'environ'))
605-
_run(s._handle_eio_message('123', '0/foo'))
606-
_run(s._handle_eio_message('123', '1/foo'))
605+
_run(s._handle_eio_message('123', '0/foo,'))
606+
_run(s._handle_eio_message('123', '1/foo,'))
607607
assert handler.call_count == 0
608608
handler_namespace.assert_called_once_with('1')
609609
assert s.environ == {'123': 'environ'}
@@ -756,7 +756,7 @@ def test_send_with_ack_namespace(self, eio):
756756
eio.return_value.send = AsyncMock()
757757
s = asyncio_server.AsyncServer()
758758
_run(s._handle_eio_connect('123', 'environ'))
759-
_run(s._handle_eio_message('123', '0/foo'))
759+
_run(s._handle_eio_message('123', '0/foo,'))
760760
cb = mock.MagicMock()
761761
id = s.manager._generate_ack_id('1', cb)
762762
_run(
@@ -833,9 +833,9 @@ def test_disconnect_namespace(self, eio):
833833
eio.return_value.disconnect = AsyncMock()
834834
s = asyncio_server.AsyncServer()
835835
_run(s._handle_eio_connect('123', 'environ'))
836-
_run(s._handle_eio_message('123', '0/foo'))
836+
_run(s._handle_eio_message('123', '0/foo,'))
837837
_run(s.disconnect('1', namespace='/foo'))
838-
s.eio.send.mock.assert_any_call('123', '1/foo')
838+
s.eio.send.mock.assert_any_call('123', '1/foo,')
839839
assert not s.manager.is_connected('1', '/foo')
840840

841841
def test_disconnect_twice(self, eio):
@@ -854,7 +854,7 @@ def test_disconnect_twice_namespace(self, eio):
854854
eio.return_value.send = AsyncMock()
855855
s = asyncio_server.AsyncServer()
856856
_run(s._handle_eio_connect('123', 'environ'))
857-
_run(s._handle_eio_message('123', '0/foo'))
857+
_run(s._handle_eio_message('123', '0/foo,'))
858858
_run(s.disconnect('1', namespace='/foo'))
859859
calls = s.eio.send.mock.call_count
860860
assert not s.manager.is_connected('1', '/foo')
@@ -884,7 +884,7 @@ async def on_baz(self, sid, data1, data2):
884884
s = asyncio_server.AsyncServer(async_handlers=False)
885885
s.register_namespace(MyNamespace('/foo'))
886886
_run(s._handle_eio_connect('123', 'environ'))
887-
_run(s._handle_eio_message('123', '0/foo'))
887+
_run(s._handle_eio_message('123', '0/foo,'))
888888
assert result['result'] == ('1', 'environ')
889889
_run(s._handle_eio_message('123', '2/foo,["foo","a"]'))
890890
assert result['result'] == ('1', 'a')

tests/common/test_packet.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,13 @@ def test_decode_namespace_with_query_string(self):
111111

112112
def test_encode_namespace_no_data(self):
113113
pkt = packet.Packet(packet_type=packet.EVENT, namespace='/bar')
114-
assert pkt.encode() == '2/bar'
114+
assert pkt.encode() == '2/bar,'
115115

116116
def test_decode_namespace_no_data(self):
117-
pkt = packet.Packet(encoded_packet='2/bar')
117+
pkt = packet.Packet(encoded_packet='2/bar,')
118118
assert pkt.namespace == '/bar'
119-
assert pkt.encode() == '2/bar'
119+
assert pkt.data is None
120+
assert pkt.encode() == '2/bar,'
120121

121122
def test_encode_namespace_with_hyphens(self):
122123
pkt = packet.Packet(

tests/common/test_server.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def test_handle_connect_namespace(self, eio):
359359
handler = mock.MagicMock()
360360
s.on('connect', handler, namespace='/foo')
361361
s._handle_eio_connect('123', 'environ')
362-
s._handle_eio_message('123', '0/foo')
362+
s._handle_eio_message('123', '0/foo,')
363363
assert s.manager.is_connected('1', '/foo')
364364
handler.assert_called_once_with('1', 'environ')
365365
s.eio.send.assert_called_once_with('123', '0/foo,{"sid":"1"}')
@@ -396,7 +396,7 @@ def test_handle_connect_namespace_rejected(self, eio):
396396
handler = mock.MagicMock(return_value=False)
397397
s.on('connect', handler, namespace='/foo')
398398
s._handle_eio_connect('123', 'environ')
399-
s._handle_eio_message('123', '0/foo')
399+
s._handle_eio_message('123', '0/foo,')
400400
assert not s.manager.is_connected('1', '/foo')
401401
handler.assert_called_once_with('1', 'environ')
402402
assert not s.manager.is_connected('1', '/foo')
@@ -422,7 +422,7 @@ def test_handle_connect_namespace_rejected_always_connect(self, eio):
422422
handler = mock.MagicMock(return_value=False)
423423
s.on('connect', handler, namespace='/foo')
424424
s._handle_eio_connect('123', 'environ')
425-
s._handle_eio_message('123', '0/foo')
425+
s._handle_eio_message('123', '0/foo,')
426426
assert not s.manager.is_connected('1', '/foo')
427427
handler.assert_called_once_with('1', 'environ')
428428
s.eio.send.assert_any_call('123', '0/foo,{"sid":"1"}')
@@ -464,7 +464,7 @@ def test_handle_connect_namespace_rejected_with_exception(self, eio):
464464
)
465465
s.on('connect', handler, namespace='/foo')
466466
s._handle_eio_connect('123', 'environ')
467-
s._handle_eio_message('123', '0/foo')
467+
s._handle_eio_message('123', '0/foo,')
468468
assert not s.manager.is_connected('1', '/foo')
469469
s.eio.send.assert_called_once_with(
470470
'123', '4/foo,{"message":"fail_reason","data":1}'
@@ -478,7 +478,7 @@ def test_handle_connect_namespace_rejected_with_empty_exception(self, eio):
478478
)
479479
s.on('connect', handler, namespace='/foo')
480480
s._handle_eio_connect('123', 'environ')
481-
s._handle_eio_message('123', '0/foo')
481+
s._handle_eio_message('123', '0/foo,')
482482
assert not s.manager.is_connected('1', '/foo')
483483
s.eio.send.assert_called_once_with(
484484
'123', '4/foo,{"message":"Connection rejected by server"}')
@@ -503,7 +503,7 @@ def test_handle_disconnect_namespace(self, eio):
503503
handler_namespace = mock.MagicMock()
504504
s.on('disconnect', handler_namespace, namespace='/foo')
505505
s._handle_eio_connect('123', 'environ')
506-
s._handle_eio_message('123', '0/foo')
506+
s._handle_eio_message('123', '0/foo,')
507507
s._handle_eio_disconnect('123')
508508
handler.assert_not_called()
509509
handler_namespace.assert_called_once_with('1')
@@ -516,8 +516,8 @@ def test_handle_disconnect_only_namespace(self, eio):
516516
handler_namespace = mock.MagicMock()
517517
s.on('disconnect', handler_namespace, namespace='/foo')
518518
s._handle_eio_connect('123', 'environ')
519-
s._handle_eio_message('123', '0/foo')
520-
s._handle_eio_message('123', '1/foo')
519+
s._handle_eio_message('123', '0/foo,')
520+
s._handle_eio_message('123', '1/foo,')
521521
assert handler.call_count == 0
522522
handler_namespace.assert_called_once_with('1')
523523
assert s.environ == {'123': 'environ'}
@@ -651,7 +651,7 @@ def test_send_with_ack(self, eio):
651651
def test_send_with_ack_namespace(self, eio):
652652
s = server.Server()
653653
s._handle_eio_connect('123', 'environ')
654-
s._handle_eio_message('123', '0/foo')
654+
s._handle_eio_message('123', '0/foo,')
655655
cb = mock.MagicMock()
656656
id = s.manager._generate_ack_id('1', cb)
657657
s._emit_internal('123', 'my event', ['foo'], namespace='/foo', id=id)
@@ -711,9 +711,9 @@ def test_disconnect_ignore_queue(self, eio):
711711
def test_disconnect_namespace(self, eio):
712712
s = server.Server()
713713
s._handle_eio_connect('123', 'environ')
714-
s._handle_eio_message('123', '0/foo')
714+
s._handle_eio_message('123', '0/foo,')
715715
s.disconnect('1', namespace='/foo')
716-
s.eio.send.assert_any_call('123', '1/foo')
716+
s.eio.send.assert_any_call('123', '1/foo,')
717717

718718
def test_disconnect_twice(self, eio):
719719
s = server.Server()
@@ -727,7 +727,7 @@ def test_disconnect_twice(self, eio):
727727
def test_disconnect_twice_namespace(self, eio):
728728
s = server.Server()
729729
s._handle_eio_connect('123', 'environ')
730-
s._handle_eio_message('123', '0/foo')
730+
s._handle_eio_message('123', '0/foo,')
731731
s.disconnect('123', namespace='/foo')
732732
calls = s.eio.send.call_count
733733
s.disconnect('123', namespace='/foo')
@@ -755,7 +755,7 @@ def on_baz(self, sid, data1, data2):
755755
s = server.Server(async_handlers=False)
756756
s.register_namespace(MyNamespace('/foo'))
757757
s._handle_eio_connect('123', 'environ')
758-
s._handle_eio_message('123', '0/foo')
758+
s._handle_eio_message('123', '0/foo,')
759759
assert result['result'] == ('1', 'environ')
760760
s._handle_eio_message('123', '2/foo,["foo","a"]')
761761
assert result['result'] == ('1', 'a')

0 commit comments

Comments
 (0)