-
-
Notifications
You must be signed in to change notification settings - Fork 993
Description
It is possible for back-to-back requests to be missing session data.
Say you have a webapp with 2 routes. Route /a stores a value in the session and then redirects to route /b. Route /b simply prints the value stored in the session. If the session store is slow, it is possible to hit route /b before the session is persisted. express-session starts writing a response back to the browser in writetop() before the session is persisted. once the session data is persisted, express-session calls writeend(). When express-session executes writetop(), the browser gets the 302 redirect and performs the get on route /b before the session data is persisted. When route /b prints its session data, the stored value is not there. I believe express-session should not perform writetop() and only call writeend() once the session data is persisted.
Webapp:
/a
req.session.key = 'value';
res.redirect("/b")
/b
console.log(req.session.key)
A sample log file would like this:
GET /a
- start writing session (session store log)
- redirect to /b
GET /b
- get session (session store log)
- done writing session (session store log)
- print session data (req.session.key missing)
Most of the time the session data is persisted before the request for /b and everything proceeds as expected, but once in a while the request for /b will arrive before the session data is persisted causing problems.
To get around this problem, I removed the writetop() from index.js and fixed up the if logic:
// touch session
req.session.touch();
if (shouldSave(req)) {
req.session.save(function onsave(err) {
if (err) {
defer(next, err);
}
return writeend();
});
} else if (storeImplementsTouch && shouldTouch(req)) {
// store implements touch method
debug('touching');
store.touch(req.sessionID, req.session, function ontouch(err) {
if (err) {
defer(next, err);
}
debug('touched');
writeend();
});
return writetop();
} else {
return _end.call(res, chunk, encoding);
}