added: SessionContainer special container used by SessionManager

sessions are indexed by id and time (last used time)
changed: old sessions are deleted
       parameter: session_max_iddle in the config file
added: function 'who'


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@483 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
2009-01-31 06:53:36 +00:00
parent a48766871d
commit 7d73d048c8
29 changed files with 540 additions and 61 deletions

View File

@@ -1,4 +1,4 @@
o = data.o log.o sessionmanager.o requestcontroller.o dircontainer.o session.o main.o done.o request.o misc.o httpsimpleparser.o db.o error.o db_itemcolumns.o users.o config.o dirs.o groups.o function.o functionparser.o functions.o functioncodeparser.o
o = data.o log.o sessionmanager.o requestcontroller.o dircontainer.o session.o main.o done.o request.o misc.o httpsimpleparser.o db.o error.o db_itemcolumns.o users.o config.o dirs.o groups.o function.o functionparser.o functions.o functioncodeparser.o sessioncontainer.o

View File

@@ -38,7 +38,8 @@ main.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
main.o: ../core/users.h ../core/groups.h ../core/log.h
main.o: ../templates/patterncacher.h ../app/templates.h ../core/misc.h
main.o: ../core/function.h ../core/functionparser.h ../app/content.h
main.o: sessionmanager.h config.h ../confparser/confparser.h
main.o: sessionmanager.h sessioncontainer.h config.h
main.o: ../confparser/confparser.h
misc.o: misc.h log.h item.h
request.o: request.h requesttypes.h log.h session.h error.h item.h done.h
request.o: user.h getparser.h httpsimpleparser.h postparser.h cookieparser.h
@@ -56,12 +57,14 @@ requestcontroller.o: ../core/group.h ../core/users.h ../core/groups.h
requestcontroller.o: ../core/log.h ../templates/patterncacher.h
requestcontroller.o: ../app/templates.h ../core/misc.h ../core/function.h
requestcontroller.o: ../core/functionparser.h ../app/content.h
requestcontroller.o: sessionmanager.h
requestcontroller.o: sessionmanager.h sessioncontainer.h
session.o: session.h requesttypes.h error.h log.h item.h done.h user.h
sessioncontainer.o: sessioncontainer.h session.h requesttypes.h error.h log.h
sessioncontainer.o: item.h done.h user.h
sessionmanager.o: sessionmanager.h request.h requesttypes.h log.h session.h
sessionmanager.o: error.h item.h done.h user.h getparser.h httpsimpleparser.h
sessionmanager.o: postparser.h cookieparser.h function.h data.h misc.h dirs.h
sessionmanager.o: db.h dircontainer.h group.h ugcontainer.h users.h groups.h
sessionmanager.o: functions.h functioncodeparser.h
sessionmanager.o: functions.h functioncodeparser.h sessioncontainer.h
users.o: users.h user.h db.h log.h item.h misc.h error.h dircontainer.h
users.o: group.h ugcontainer.h

View File

@@ -113,11 +113,14 @@ void Config::AssignValues()
data.priv_no_user = Text("priv_no_user");
data.priv_no_group = Text("priv_no_group");
data.session_max_iddle = Int("session_max_iddle");
}
// !! mozna dodac drugi argument -- wartosc domyslna
std::string & Config::Text(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);
@@ -135,7 +138,7 @@ return i->second;
// !! mozna dodac drugi argument -- wartosc domyslna
int Config::Int(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);
@@ -154,6 +157,7 @@ return res;
// !! mozna dodac drugi argument -- wartosc domyslna
bool Config::Bool(const char * name)
{
ConfParser::Table::iterator i = conf_parser.table.find(name);

View File

@@ -83,6 +83,8 @@ public:
std::string priv_no_user;
std::string priv_no_group;
// time in second when the user will be automatically logged out (iddle time)
int session_max_iddle;
// end config members
// -----------------------------------------------------------------

View File

@@ -1,3 +1,12 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#include "db.h"

View File

@@ -27,6 +27,9 @@
#define FUN_LOGIN 9
#define FUN_LOGOUT 10
#define FUN_RUN 11
#define FUN_WHO 12
class Function
@@ -48,7 +51,8 @@ public:
rm,
login,
logout,
run
run,
who
};

View File

@@ -79,10 +79,15 @@ void Functions::ReadFunctions()
f.item.url = "run";
table.insert( std::make_pair(f.item.url, f) );
f.code = FUN_WHO;
f.item.url = "who";
table.insert( std::make_pair(f.item.url, f) );
// -----------
FunctionCodeParser fc;
fc.Parse(Item()); // temporary for linking
// FunctionCodeParser fc;
// fc.Parse(Item()); // temporary for linking
}

View File

@@ -26,7 +26,7 @@ Log log;
Request request;
Db db;
Config config;
RequestController req_controller;
@@ -57,7 +57,6 @@ void print_syntax()
int main(int argv, char ** argc)
{
RequestController req_controller;
std::srand(std::time(0));

View File

@@ -187,4 +187,24 @@ return out.str();
const char * DateToStr(int month, int day, int hour, int min, int sec)
{
static const char * month_letter[] = { "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII" };
static char buffer[100];
--month;
if( month < 0 )
month = 0;
if( month > 11 )
month = 11;
sprintf(buffer, "%s.%02d %02d:%02d:%02d", month_letter[month], day, hour, min, sec);
// warning: not thread safe (we do not use threads)
return buffer;
}

View File

@@ -31,6 +31,7 @@ void SetUrlFromSubject(Item & item);
void HtmlEscape(std::ostringstream & out, const std::string & in);
std::string HtmlEscape(const std::string & in);
const char * DateToStr(int month, int day, int hour, int min, int sec);
#endif

View File

@@ -145,6 +145,7 @@ void RequestController::Loop()
// and then BaseUrlRedirect() will be called (for performance)
if( !BaseUrlRedirect() )
{
session_manager.DeleteOldSessions();
session_manager.SetSession(); // set request.session as well
request.session->CheckTimers();
@@ -177,3 +178,16 @@ void RequestController::Loop()
}
}
}
SessionContainer::Iterator RequestController::SessionBegin()
{
return session_manager.SessionBegin();
}
SessionContainer::Iterator RequestController::SessionEnd()
{
return session_manager.SessionEnd();
}

View File

@@ -45,7 +45,13 @@ public:
void Close();
void Loop();
SessionContainer::Iterator SessionBegin();
SessionContainer::Iterator SessionEnd();
};
extern RequestController req_controller;
#endif

View File

@@ -15,6 +15,10 @@ Session::Session()
Clear();
time = std::time(0);
tm_time = *std::localtime(&time);
last_time = time;
tm_last_time = tm_time;
}

View File

@@ -25,8 +25,16 @@ struct Session
long id;
// when this session was created
int time;
// (the same values)
time_t time;
tm tm_time;
// when this session was last used
// (the same values)
time_t last_time;
tm tm_last_time;
// 0 - means that nobody is logged
User * puser;

139
core/sessioncontainer.cpp Executable file
View File

@@ -0,0 +1,139 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#include "sessioncontainer.h"
void SessionContainer::Clear()
{
table.clear();
index_id.clear();
index_time.clear();
}
SessionContainer::Iterator SessionContainer::Begin()
{
return table.begin();
}
SessionContainer::Iterator SessionContainer::End()
{
return table.end();
}
Session & SessionContainer::Back()
{
return table.back();
}
bool SessionContainer::PushBack(const Session & session)
{
if( index_id.find(session.id) != index_id.end() )
// that element already exists
return false;
Iterator last = table.insert(table.end(), session);
index_id.insert( std::make_pair(session.id, last) );
index_time.insert( std::make_pair(session.last_time, last) );
log << log3 << "SC: added session, id: " << session.id << logend;
return true;
}
SessionContainer::Iterator SessionContainer::FindById(long id)
{
IndexId::iterator i;
i = index_id.find(id);
if( i == index_id.end() )
return table.end();
return i->second;
}
void SessionContainer::DelFirstByTimeInterval(time_t interval)
{
IndexTime::iterator i = index_time.begin();
IndexTime::iterator iold;
time_t limit = std::time(0) - interval;
for( ; i != index_time.end() && i->second->last_time < limit ; )
{
long id = i->second->id;
iold = i;
++i;
// we're logging session.id (call this before table.erase())
DelFromIdIndex(iold->second);
table.erase(iold->second);
index_time.erase(iold);
log << log3 << "SC: deleted index_time for session id: " << id << logend;
log << log3 << "SC: deleted session, id: " << id << logend;
}
}
void SessionContainer::DelFromIdIndex(SessionContainer::Iterator iter)
{
IndexId::iterator i;
for( i = index_id.begin() ; i!=index_id.end() ; ++i)
{
if( i->second == iter )
{
index_id.erase(i);
log << log3 << "SC: deleted index_id for session id: " << iter->id << logend;
break;
}
}
}
void SessionContainer::UpdateLastTime(SessionContainer::Iterator iter, time_t new_time)
{
IndexTime::iterator i = index_time.lower_bound(iter->last_time);
bool found = false;
for( ; i != index_time.end() ; ++i)
{
if( i->second == iter )
{
index_time.erase(i);
index_time.insert( std::make_pair(new_time, iter) );
iter->last_time = new_time;
iter->tm_last_time = *std::localtime(&new_time);
log << log3 << "SC: last time and the time index for session id: " << iter->id << " updated" << logend;
found = true;
break;
}
}
if( !found )
log << log1 << "SC: cannot update the time, time index not found for session id: " << iter->id << logend;
}

58
core/sessioncontainer.h Executable file
View File

@@ -0,0 +1,58 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilesessioncontainer
#define headerfilesessioncontainer
#include <list>
#include <map>
#include <ctime>
#include "session.h"
#include "log.h"
class SessionContainer
{
public:
typedef std::list<Session> Table;
typedef Table::iterator Iterator;
typedef std::map<long, Iterator> IndexId;
typedef std::multimap<time_t, Iterator> IndexTime;
private:
Table table;
IndexId index_id;
IndexTime index_time;
void DelFromIdIndex(Iterator iter);
public:
void Clear();
Iterator Begin();
Iterator End();
Session & Back();
bool PushBack(const Session & session);
Iterator FindById(long);
void DelFirstByTimeInterval(time_t interval);
void UpdateLastTime(Iterator iter, time_t new_time);
};
#endif

View File

@@ -10,20 +10,10 @@
#include "sessionmanager.h"
bool SessionManager::IsSession(long s)
bool SessionManager::IsSession(long id)
{
SessionTable::iterator i;
Session temp;
temp.id = s;
i = session_table.find(temp);
if( i == session_table.end() )
if( session_table.FindById(id) == session_table.End() )
return false;
return true;
}
@@ -61,19 +51,19 @@ return id;
void SessionManager::CreateTemporarySession()
{
Session s;
SessionContainer::Iterator i = session_table.FindById( 0 );
s.id = 0;
SessionTable::iterator i = session_table.find( s ); // looking for id=0
if( i == session_table.end() )
if( i == session_table.End() )
{
std::pair<SessionTable::iterator,bool> res = session_table.insert(s);
request.session = const_cast<Session*>( &(*res.first) );
Session s;
s.id = 0;
session_table.PushBack(s);
request.session = &session_table.Back();
}
else
{
request.session = const_cast<Session*>( &(*i) );
request.session = &(*i);
}
}
@@ -87,15 +77,13 @@ int attempts = 100;
{
s.id = CreateSessionId();
std::pair<SessionTable::iterator,bool> res = session_table.insert(s);
bool added = session_table.PushBack(s);
if( res.second == true )
if( added )
{
// the insertion took place
request.session = const_cast<Session*>( &(*res.first) );
request.session = &session_table.Back();
request.SetCookie(data.http_session_id_name.c_str(), request.session->id);
log << log2 << "SM: created a new session: " << s.id << logend;
log << log2 << "SM: created a new session: " << request.session->id << logend;
return;
}
@@ -119,15 +107,16 @@ void SessionManager::SetSession()
}
else
{
Session temp;
temp.id = atol(i->second.c_str());
SessionTable::iterator s = session_table.find(temp);
long id = atol(i->second.c_str());
SessionContainer::Iterator s = session_table.FindById(id);
if( s != session_table.end() )
if( s != session_table.End() )
{
// that session is in the table
request.session = const_cast<Session*>( &(*s) );
request.session = &(*s);
session_table.UpdateLastTime(s, std::time(0));
log << log2 << "SM: session: " << s->id;
if( request.session->puser )
@@ -153,10 +142,23 @@ void SessionManager::SetSession()
SessionContainer::Iterator SessionManager::SessionBegin()
{
return session_table.Begin();
}
SessionContainer::Iterator SessionManager::SessionEnd()
{
return session_table.End();
}
void SessionManager::DeleteOldSessions()
{
session_table.DelFirstByTimeInterval(data.session_max_iddle);
}

View File

@@ -18,16 +18,19 @@
#include "data.h"
#include "session.h"
#include "db.h"
#include "sessioncontainer.h"
class SessionManager
{
// !! zamienic na map
typedef std::set<Session> SessionTable;
//typedef std::set<Session> SessionTable;
//SessionTable session_table;
SessionTable session_table;
SessionContainer session_table;
bool IsSession(long s);
@@ -39,6 +42,10 @@ public:
void SetSession();
void DeleteOldSessions();
SessionContainer::Iterator SessionBegin();
SessionContainer::Iterator SessionEnd();
};