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:
Tomasz Sowa 2009-01-31 06:53:36 +00:00
parent a48766871d
commit 7d73d048c8
29 changed files with 540 additions and 61 deletions

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.
*
*/
#ifndef headerfileappcontent
#define headerfileappcontent

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.
*
*/
#ifndef headerfileapptemplates
#define headerfileapptemplates

View File

@ -157,4 +157,17 @@ run.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
run.o: ../core/users.h ../core/groups.h ../core/log.h
run.o: ../templates/patterncacher.h ../app/templates.h ../core/misc.h
run.o: ../core/function.h ../core/functionparser.h ../core/request.h
run.o: ../core/data.h ../app/content.h ../core/functioncodeparser.h
run.o: ../core/data.h ../app/content.h
who.o: content.h ../templates/templates.h ../../ezc/src/ezc.h ../core/data.h
who.o: ../core/misc.h ../core/log.h ../core/item.h ../core/error.h
who.o: ../core/dirs.h ../core/db.h ../core/dircontainer.h ../core/user.h
who.o: ../core/group.h ../core/ugcontainer.h ../core/users.h ../core/groups.h
who.o: ../core/functions.h ../core/function.h ../core/functioncodeparser.h
who.o: ../core/request.h ../core/requesttypes.h ../core/session.h
who.o: ../core/done.h ../core/getparser.h ../core/httpsimpleparser.h
who.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
who.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
who.o: ../core/users.h ../core/groups.h ../core/log.h
who.o: ../templates/patterncacher.h ../app/templates.h ../core/misc.h
who.o: ../core/function.h ../core/functionparser.h ../core/request.h
who.o: ../core/data.h ../app/content.h

View File

@ -53,6 +53,7 @@ class Content
void FunMkdir();
void FunDefault();
void FunRun();
void FunWho();
void PostFunLogin();

View File

@ -9,7 +9,6 @@
#include "content.h"
#include "../app/content.h"
#include "../core/functioncodeparser.h"
@ -28,15 +27,6 @@ void Content::FunRun()
request.status = Error::permision_denied;
return;
}
FunctionCodeParser fc;
int c = fc.Parse(request.item);
#ifdef APPFUNCTIONS
if( c != FUN_NONE )
AppContent::AppFunction(c);
#endif
}

25
content/who.cpp Executable file
View File

@ -0,0 +1,25 @@
/*
* 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 "content.h"
#include "../app/content.h"
void Content::FunRun()
{
}

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,7 +25,15 @@ 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,21 +10,11 @@
#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,14 +107,15 @@ 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;
@ -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;
SessionContainer session_table;
SessionTable session_table;
bool IsSession(long s);
@ -39,6 +42,10 @@ public:
void SetSession();
void DeleteOldSessions();
SessionContainer::Iterator SessionBegin();
SessionContainer::Iterator SessionEnd();
};

View File

@ -1,4 +1,4 @@
o = templates.o sys.o item.o doc.o user.o dir.o done.o priv.o patterncacher.o
o = templates.o sys.o item.o doc.o user.o dir.o done.o priv.o patterncacher.o who.o
all: templates.a

View File

@ -91,3 +91,18 @@ user.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
user.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
user.o: ../core/users.h ../core/groups.h ../core/log.h patterncacher.h
user.o: ../app/templates.h
who.o: templates.h ../../ezc/src/ezc.h ../core/data.h ../core/misc.h
who.o: ../core/log.h ../core/item.h ../core/error.h ../core/dirs.h
who.o: ../core/db.h ../core/dircontainer.h ../core/user.h ../core/group.h
who.o: ../core/ugcontainer.h ../core/users.h ../core/groups.h
who.o: ../core/functions.h ../core/function.h ../core/functioncodeparser.h
who.o: ../core/request.h ../core/requesttypes.h ../core/session.h
who.o: ../core/done.h ../core/getparser.h ../core/httpsimpleparser.h
who.o: ../core/postparser.h ../core/cookieparser.h ../core/item.h
who.o: ../core/db.h ../core/error.h ../core/user.h ../core/group.h
who.o: ../core/users.h ../core/groups.h ../core/log.h patterncacher.h
who.o: ../app/templates.h ../core/sessioncontainer.h
who.o: ../core/requestcontroller.h ../core/data.h ../core/request.h
who.o: ../content/content.h ../templates/templates.h ../core/misc.h
who.o: ../core/function.h ../core/functionparser.h ../app/content.h
who.o: ../core/sessionmanager.h ../core/sessioncontainer.h

View File

@ -22,6 +22,7 @@ Ezc::Pattern pat_fun_mkdir;
Ezc::Pattern pat_fun_default;
Ezc::Pattern pat_fun_priv;
Ezc::Pattern pat_fun_rm;
Ezc::Pattern pat_fun_who;
Ezc::Pattern pat_err_item_required;
Ezc::Pattern pat_err_404;
Ezc::Pattern pat_err_per_denied;
@ -96,6 +97,10 @@ Ezc::Pattern * p = 0;
p = pattern_cacher.GetPattern(request.item);
break;
case FUN_WHO:
p = &pat_fun_who;
break;
default:
break;
}
@ -278,6 +283,16 @@ void Templates::CreateFunctions()
functions.Insert("content", content);
/*
who
*/
functions.Insert("who_tab", who_tab);
functions.Insert("who_tab_lp", who_tab_lp);
functions.Insert("who_tab_user", who_tab_user);
functions.Insert("who_tab_time", who_tab_time);
functions.Insert("who_tab_last_time", who_tab_last_time);
// !! tymczasowa
functions.Insert("is_group_tv", is_group_tv);
@ -331,6 +346,9 @@ void Templates::Read()
pat_err_others.Directory(data.templates);
pat_err_others.ParseFile("err_others.html");
pat_fun_who.Directory(data.templates);
pat_fun_who.ParseFile("who.html");
CreateFunctions();
#ifdef APPTEMPLATES

View File

@ -11,6 +11,8 @@
#define headerfiletemplates
#include <iomanip>
#include <set>
#include "../../ezc/src/ezc.h"
#include "../core/data.h"
@ -152,6 +154,16 @@ namespace TemplatesFunctions
void done_loggedout(Info & i);
/*
who
*/
void who_tab(Info & i);
void who_tab_lp(Info & i);
void who_tab_user(Info & i);
void who_tab_time(Info & i);
void who_tab_last_time(Info & i);
} // namespace TemplatesFunctions

102
templates/who.cpp Executable file
View File

@ -0,0 +1,102 @@
/*
* 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 "templates.h"
#include "../core/sessioncontainer.h"
#include "../core/requestcontroller.h"
#include "../core/misc.h"
namespace TemplatesFunctions
{
static size_t who_reqid = 0;
SessionContainer::Iterator who_iterator;
size_t who_lp;
bool who_init()
{
if( who_reqid != request.id )
{
who_reqid = request.id;
who_iterator = req_controller.SessionBegin();
who_lp = 1;
}
return who_iterator != req_controller.SessionEnd();
}
void who_tab(Info & i)
{
who_init();
if( i.iter != 0 && who_iterator != req_controller.SessionEnd() )
{
++who_iterator;
++who_lp;
}
i.result = who_iterator != req_controller.SessionEnd();
}
void who_tab_lp(Info & i)
{
if( !who_init() )
return;
i.out << who_lp;
}
void who_tab_user(Info & i)
{
if( !who_init() )
return;
if( who_iterator->puser )
i.out << who_iterator->puser->name;
}
void who_tab_time(Info & i)
{
if( !who_init() )
return;
i.out << DateToStr( who_iterator->tm_time.tm_mon + 1,
who_iterator->tm_time.tm_mday,
who_iterator->tm_time.tm_hour,
who_iterator->tm_time.tm_min,
who_iterator->tm_time.tm_sec );
}
void who_tab_last_time(Info & i)
{
if( !who_init() )
return;
i.out << DateToStr( who_iterator->tm_last_time.tm_mon + 1,
who_iterator->tm_last_time.tm_mday,
who_iterator->tm_last_time.tm_hour,
who_iterator->tm_last_time.tm_min,
who_iterator->tm_last_time.tm_sec );
}
} // namespace TemplatesFunctions