mirror of https://github.com/adamdruppe/arsd.git
experimental memory session
This commit is contained in:
parent
e1de7a72d5
commit
a41478afe1
53
web.d
53
web.d
|
@ -1524,6 +1524,9 @@ void run(Provider)(Cgi cgi, Provider instantiation, size_t pathInfoStartingPoint
|
||||||
cgi.write(result.result.str, true);
|
cgi.write(result.result.str, true);
|
||||||
} else assert(0);
|
} else assert(0);
|
||||||
break;
|
break;
|
||||||
|
case "download":
|
||||||
|
cgi.header("Content-Disposition: attachment; filename=\"data.csv\"");
|
||||||
|
goto case;
|
||||||
case "none":
|
case "none":
|
||||||
cgi.setResponseContentType("text/plain");
|
cgi.setResponseContentType("text/plain");
|
||||||
|
|
||||||
|
@ -2916,6 +2919,9 @@ class Session {
|
||||||
return new Session(cgi, cookieParams, useFile, true);
|
return new Session(cgi, cookieParams, useFile, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
version(webd_memory_sessions)
|
||||||
|
__gshared static string[string][string] sessions;
|
||||||
|
|
||||||
/// Loads the session if available, and creates one if not.
|
/// Loads the session if available, and creates one if not.
|
||||||
/// May write a session id cookie to the passed cgi object.
|
/// May write a session id cookie to the passed cgi object.
|
||||||
this(Cgi cgi, CookieParams cookieParams = CookieParams(), bool useFile = true, bool readOnly = false) {
|
this(Cgi cgi, CookieParams cookieParams = CookieParams(), bool useFile = true, bool readOnly = false) {
|
||||||
|
@ -2984,6 +2990,10 @@ class Session {
|
||||||
/// becomes very easy; even easier than a normal session id since they just reply it.
|
/// becomes very easy; even easier than a normal session id since they just reply it.
|
||||||
/// (you should really ssl encrypt all sessions for any real protection btw)
|
/// (you should really ssl encrypt all sessions for any real protection btw)
|
||||||
private void loadSpecialSession(Cgi cgi) {
|
private void loadSpecialSession(Cgi cgi) {
|
||||||
|
// Note: this won't work with memory sessions
|
||||||
|
version(webd_memory_sessions)
|
||||||
|
throw new Exception("You cannot access sessions this way.");
|
||||||
|
else {
|
||||||
version(no_session_override)
|
version(no_session_override)
|
||||||
throw new Exception("You cannot access sessions this way.");
|
throw new Exception("You cannot access sessions this way.");
|
||||||
else {
|
else {
|
||||||
|
@ -3008,10 +3018,14 @@ class Session {
|
||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Call this periodically to clean up old session files. The finalizer param can cancel the deletion
|
/// Call this periodically to clean up old session files. The finalizer param can cancel the deletion
|
||||||
/// of a file by returning false.
|
/// of a file by returning false.
|
||||||
public static void garbageCollect(bool delegate(string[string] data) finalizer = null, Duration maxAge = dur!"hours"(4)) {
|
public static void garbageCollect(bool delegate(string[string] data) finalizer = null, Duration maxAge = dur!"hours"(4)) {
|
||||||
|
version(webd_memory_sessions)
|
||||||
|
return; // blargh. FIXME really, they should be null so the gc can free them
|
||||||
|
|
||||||
auto ctime = Clock.currTime();
|
auto ctime = Clock.currTime();
|
||||||
foreach(DirEntry e; dirEntries(getTempDirectory(), "arsd_session_file_*", SpanMode.shallow)) {
|
foreach(DirEntry e; dirEntries(getTempDirectory(), "arsd_session_file_*", SpanMode.shallow)) {
|
||||||
try {
|
try {
|
||||||
|
@ -3091,8 +3105,16 @@ class Session {
|
||||||
/// (If you don't commit, the data will be lost when this object is deleted.)
|
/// (If you don't commit, the data will be lost when this object is deleted.)
|
||||||
void regenerateId() {
|
void regenerateId() {
|
||||||
// we want to clean up the old file, but keep the data we have in memory.
|
// we want to clean up the old file, but keep the data we have in memory.
|
||||||
|
|
||||||
|
version(webd_memory_sessions) {
|
||||||
|
synchronized {
|
||||||
|
if(sessionId in sessions)
|
||||||
|
sessions.remove(sessionId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if(std.file.exists(getFilePath()))
|
if(std.file.exists(getFilePath()))
|
||||||
std.file.remove(getFilePath());
|
std.file.remove(getFilePath());
|
||||||
|
}
|
||||||
|
|
||||||
// and new cookie -> new session id -> new csrf token
|
// and new cookie -> new session id -> new csrf token
|
||||||
makeSessionId(makeNewCookie());
|
makeSessionId(makeNewCookie());
|
||||||
|
@ -3111,9 +3133,15 @@ class Session {
|
||||||
/// Odds are, invalidate() is what you really want.
|
/// Odds are, invalidate() is what you really want.
|
||||||
void clear() {
|
void clear() {
|
||||||
assert(!_readOnly); // or should I throw an exception or just silently ignore it???
|
assert(!_readOnly); // or should I throw an exception or just silently ignore it???
|
||||||
|
version(webd_memory_sessions) {
|
||||||
|
synchronized {
|
||||||
|
if(sessionId in sessions)
|
||||||
|
sessions.remove(sessionId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if(std.file.exists(getFilePath()))
|
if(std.file.exists(getFilePath()))
|
||||||
std.file.remove(getFilePath());
|
std.file.remove(getFilePath());
|
||||||
|
}
|
||||||
data = null;
|
data = null;
|
||||||
_hasData = false;
|
_hasData = false;
|
||||||
changed = false;
|
changed = false;
|
||||||
|
@ -3243,6 +3271,19 @@ class Session {
|
||||||
/// Discards your changes, reloading the session data from the disk file.
|
/// Discards your changes, reloading the session data from the disk file.
|
||||||
void reload() {
|
void reload() {
|
||||||
data = null;
|
data = null;
|
||||||
|
|
||||||
|
|
||||||
|
version(webd_memory_sessions) {
|
||||||
|
synchronized {
|
||||||
|
if(auto s = sessionId in sessions) {
|
||||||
|
foreach(k, v; *s)
|
||||||
|
data[k] = v;
|
||||||
|
_hasData = true;
|
||||||
|
} else {
|
||||||
|
_hasData = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
auto path = getFilePath();
|
auto path = getFilePath();
|
||||||
try {
|
try {
|
||||||
data = Session.loadData(path);
|
data = Session.loadData(path);
|
||||||
|
@ -3255,6 +3296,7 @@ class Session {
|
||||||
std.file.remove(path);
|
std.file.remove(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: there's a race condition here - if the user is using the session
|
// FIXME: there's a race condition here - if the user is using the session
|
||||||
// from two windows, one might write to it as we're executing, and we won't
|
// from two windows, one might write to it as we're executing, and we won't
|
||||||
|
@ -3265,6 +3307,14 @@ class Session {
|
||||||
if(_readOnly)
|
if(_readOnly)
|
||||||
return;
|
return;
|
||||||
if(force || changed) {
|
if(force || changed) {
|
||||||
|
|
||||||
|
|
||||||
|
version(webd_memory_sessions) {
|
||||||
|
synchronized {
|
||||||
|
sessions[sessionId] = data;
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
std.file.write(getFilePath(), toJson(data));
|
std.file.write(getFilePath(), toJson(data));
|
||||||
changed = false;
|
changed = false;
|
||||||
// We have to make sure that only we can read this file,
|
// We have to make sure that only we can read this file,
|
||||||
|
@ -3278,6 +3328,7 @@ class Session {
|
||||||
// on Windows too.
|
// on Windows too.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string[string] data;
|
private string[string] data;
|
||||||
private bool _hasData;
|
private bool _hasData;
|
||||||
|
|
Loading…
Reference in New Issue