Skip to content

Commit

Permalink
Correct handling of user session (Fixes #585)
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Dec 14, 2020
1 parent 3ae3697 commit a61d59c
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 18 deletions.
6 changes: 4 additions & 2 deletions socketio/asyncio_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ async def get_session(self, sid, namespace=None):
the user session, use the ``session`` context manager instead.
"""
namespace = namespace or '/'
eio_session = await self.eio.get_session(sid)
eio_sid = self.manager.eio_sid_from_sid(sid, namespace)
eio_session = await self.eio.get_session(eio_sid)
return eio_session.setdefault(namespace, {})

async def save_session(self, sid, session, namespace=None):
Expand All @@ -271,7 +272,8 @@ async def save_session(self, sid, session, namespace=None):
the default namespace is used.
"""
namespace = namespace or '/'
eio_session = await self.eio.get_session(sid)
eio_sid = self.manager.eio_sid_from_sid(sid, namespace)
eio_session = await self.eio.get_session(eio_sid)
eio_session[namespace] = session

def session(self, sid, namespace=None):
Expand Down
6 changes: 4 additions & 2 deletions socketio/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,8 @@ def get_session(self, sid, namespace=None):
is used.
"""
namespace = namespace or '/'
eio_session = self.eio.get_session(sid)
eio_sid = self.manager.eio_sid_from_sid(sid, namespace)
eio_session = self.eio.get_session(eio_sid)
return eio_session.setdefault(namespace, {})

def save_session(self, sid, session, namespace=None):
Expand All @@ -456,7 +457,8 @@ def save_session(self, sid, session, namespace=None):
the default namespace is used.
"""
namespace = namespace or '/'
eio_session = self.eio.get_session(sid)
eio_sid = self.manager.eio_sid_from_sid(sid, namespace)
eio_session = self.eio.get_session(eio_sid)
eio_session[namespace] = session

def session(self, sid, namespace=None):
Expand Down
20 changes: 13 additions & 7 deletions tests/asyncio/test_asyncio_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,11 +730,13 @@ def test_send_with_ack_namespace(self, eio):
def test_session(self, eio):
fake_session = {}

async def fake_get_session(sid):
async def fake_get_session(eio_sid):
assert eio_sid == '123'
return fake_session

async def fake_save_session(sid, session):
async def fake_save_session(eio_sid, session):
global fake_session
assert eio_sid == '123'
fake_session = session

eio.return_value.send = AsyncMock()
Expand All @@ -744,17 +746,21 @@ async def fake_save_session(sid, session):

async def _test():
await s._handle_eio_connect('123', 'environ')
await s.save_session('123', {'foo': 'bar'})
async with s.session('123') as session:
await s._handle_eio_message('123', '0')
await s._handle_eio_message('123', '0/ns')
sid = s.manager.sid_from_eio_sid('123', '/')
sid2 = s.manager.sid_from_eio_sid('123', '/ns')
await s.save_session(sid, {'foo': 'bar'})
async with s.session(sid) as session:
assert session == {'foo': 'bar'}
session['foo'] = 'baz'
session['bar'] = 'foo'
assert await s.get_session('123') == {'foo': 'baz', 'bar': 'foo'}
assert await s.get_session(sid) == {'foo': 'baz', 'bar': 'foo'}
assert fake_session == {'/': {'foo': 'baz', 'bar': 'foo'}}
async with s.session('123', namespace='/ns') as session:
async with s.session(sid2, namespace='/ns') as session:
assert session == {}
session['a'] = 'b'
assert await s.get_session('123', namespace='/ns') == {'a': 'b'}
assert await s.get_session(sid2, namespace='/ns') == {'a': 'b'}
assert fake_session == {
'/': {'foo': 'baz', 'bar': 'foo'},
'/ns': {'a': 'b'},
Expand Down
20 changes: 13 additions & 7 deletions tests/common/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -627,28 +627,34 @@ def test_send_with_ack_namespace(self, eio):
def test_session(self, eio):
fake_session = {}

def fake_get_session(sid):
def fake_get_session(eio_sid):
assert eio_sid == '123'
return fake_session

def fake_save_session(sid, session):
def fake_save_session(eio_sid, session):
global fake_session
assert eio_sid == '123'
fake_session = session

s = server.Server()
s.eio.get_session = fake_get_session
s.eio.save_session = fake_save_session
s._handle_eio_connect('123', 'environ')
s.save_session('123', {'foo': 'bar'})
with s.session('123') as session:
s._handle_eio_message('123', '0')
s._handle_eio_message('123', '0/ns')
sid = s.manager.sid_from_eio_sid('123', '/')
sid2 = s.manager.sid_from_eio_sid('123', '/ns')
s.save_session(sid, {'foo': 'bar'})
with s.session(sid) as session:
assert session == {'foo': 'bar'}
session['foo'] = 'baz'
session['bar'] = 'foo'
assert s.get_session('123') == {'foo': 'baz', 'bar': 'foo'}
assert s.get_session(sid) == {'foo': 'baz', 'bar': 'foo'}
assert fake_session == {'/': {'foo': 'baz', 'bar': 'foo'}}
with s.session('123', namespace='/ns') as session:
with s.session(sid2, namespace='/ns') as session:
assert session == {}
session['a'] = 'b'
assert s.get_session('123', namespace='/ns') == {'a': 'b'}
assert s.get_session(sid2, namespace='/ns') == {'a': 'b'}
assert fake_session == {
'/': {'foo': 'baz', 'bar': 'foo'},
'/ns': {'a': 'b'},
Expand Down

0 comments on commit a61d59c

Please sign in to comment.