Skip to content

Commit bf9a5f0

Browse files
Fix session resetting before expiry. (#671)
1 parent 36b8a0a commit bf9a5f0

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

aiohttp_session/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,10 +137,12 @@ def __getitem__(self, key: str) -> Any:
137137
def __setitem__(self, key: str, value: Any) -> None:
138138
self._mapping[key] = value
139139
self._changed = True
140+
self._created = int(time.time())
140141

141142
def __delitem__(self, key: str) -> None:
142143
del self._mapping[key]
143144
self._changed = True
145+
self._created = int(time.time())
144146

145147

146148
SESSION_KEY = "aiohttp_session"

tests/test_abstract_storage.py

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import time
3-
from typing import Any, Dict
3+
from functools import partial
4+
from typing import Any, Dict, Optional
45
from unittest import mock
56

67
from aiohttp import web
@@ -31,7 +32,7 @@ def create_app(handler: Handler) -> web.Application:
3132

3233

3334
async def test_max_age_also_returns_expires(aiohttp_client: AiohttpClient) -> None:
34-
async def handler(request: web.Request) -> web.StreamResponse:
35+
async def handler(request: web.Request) -> web.Response:
3536
session = await get_session(request)
3637
session["c"] = 3
3738
return web.Response(body=b"OK")
@@ -41,6 +42,52 @@ async def handler(request: web.Request) -> web.StreamResponse:
4142

4243
client = await aiohttp_client(create_app(handler))
4344
make_cookie(client, {"a": 1, "b": 2})
44-
resp = await client.get("/")
45-
assert resp.status == 200
46-
assert "expires=Thu, 01-Jan-1970 00:00:10 GMT" in resp.headers["SET-COOKIE"]
45+
async with client.get("/") as resp:
46+
assert resp.status == 200
47+
assert "expires=Thu, 01-Jan-1970 00:00:10 GMT" in resp.headers["SET-COOKIE"]
48+
49+
50+
async def test_max_age_session_reset(aiohttp_client: AiohttpClient) -> None:
51+
async def handler(request: web.Request, n: Optional[str] = None) -> web.Response:
52+
session = await get_session(request)
53+
if n:
54+
session[n] = True
55+
return web.json_response(session._mapping)
56+
57+
app = create_app(handler)
58+
app.router.add_route("GET", "/a", partial(handler, n="a"))
59+
app.router.add_route("GET", "/b", partial(handler, n="b"))
60+
app.router.add_route("GET", "/c", partial(handler, n="c"))
61+
client = await aiohttp_client(app)
62+
63+
with mock.patch("time.time") as m_clock:
64+
m_clock.return_value = 0.0
65+
# Initialise the session (with a 10 second max_age).
66+
async with client.get("/a") as resp:
67+
c = resp.cookies["AIOHTTP_SESSION"]
68+
assert "00:00:10" in c["expires"]
69+
assert {"a"} == json.loads(c.value)["session"].keys()
70+
71+
m_clock.return_value = 8.0
72+
# Here we update the session, which should reset expiry time to 18 seconds past.
73+
async with client.get("/b") as resp:
74+
c = resp.cookies["AIOHTTP_SESSION"]
75+
assert "00:00:18" in c["expires"]
76+
assert {"a", "b"} == json.loads(c.value)["session"].keys()
77+
78+
m_clock.return_value = 15.0
79+
# Because the session has been updated, it should not have expired yet.
80+
async with client.get("/") as resp:
81+
sess = await resp.json()
82+
assert {"a", "b"} == sess.keys()
83+
84+
async with client.get("/c") as resp:
85+
c = resp.cookies["AIOHTTP_SESSION"]
86+
assert "00:00:25" in c["expires"]
87+
assert {"a", "b", "c"} == json.loads(c.value)["session"].keys()
88+
89+
m_clock.return_value = 30.0
90+
# Here the session should have expired.
91+
async with client.get("/") as resp:
92+
sess = await resp.json()
93+
assert sess == {}

0 commit comments

Comments
 (0)