* added: class HTMLFilter

files: htmlfilter.h htmlfilter.cpp
         this is an html filter used to make the html output looking better
         this is a very lightweight filter
         (without using any dynamic memory - some memory is allocated only at the beginning - in ctors)
         this filter has O(n) complexity over the whole html string
* added: antyspamming method
         if the POST request is sent too fast after the GET
         it is treated as a spam
         only for no logged users and only in 'emacs' and 'createthread' functions
       


git-svn-id: svn://ttmath.org/publicrep/cmslu/trunk@534 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2009-12-09 00:42:40 +00:00
parent 9241fddb1e
commit 717eb526fb
32 changed files with 1356 additions and 198 deletions

View File

@ -21,7 +21,7 @@ cmslu: FORCE
$(CXX) -shared -o cmslu.so $(CXXFLAGS) core/*.o content/*.o templates/*.o templatesnotify/*.o confparser/*.o ../ezc/src/ezc.a -lfcgi -lpq -lz
@cd main ; $(MAKE) -e
# use the full path with cmslu.so
$(CXX) -o cmslu $(CXXFLAGSMAIN) main/*.o /home/tomek/roboczy/cmslu/bin/cmslu.so
$(CXX) -o cmslu $(CXXFLAGSMAIN) main/*.o /home/tomek/roboczy/cmslu/cmslu.so
clean:
@ -48,9 +48,9 @@ depend:
@cd ../ezc/src ; $(MAKE) -e depend
@cd main ; $(MAKE) -e depend
install: all
mkdir -p bin
rm -f bin/cmslu.so
rm -f bin/cmslu
cp cmslu.so bin/
cp cmslu bin/
#install: all
# mkdir -p bin
# rm -f bin/cmslu.so
# rm -f bin/cmslu
# cp cmslu.so bin/
# cp cmslu bin/

View File

@ -6,19 +6,20 @@ cat.o: ../core/requesttypes.h ../core/session.h ../core/done.h ../core/item.h
cat.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h
cat.o: ../core/function.h ../core/thread.h ../core/compress.h
cat.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
cat.o: ../core/error.h
cat.o: ../core/htmlfilter.h ../core/error.h
content.o: content.h ../core/item.h ../templates/templates.h
content.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
content.o: ../core/requesttypes.h ../core/session.h ../core/done.h
content.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
content.o: ../core/rebus.h ../core/function.h ../core/thread.h
content.o: ../core/compress.h ../core/acceptencodingparser.h
content.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
content.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
content.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
content.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
content.o: ../core/mount.h ../core/misc.h ../core/plugin.h ../core/request.h
content.o: ../core/data.h ../core/pluginmsg.h
content.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
content.o: ../core/db.h ../core/group.h ../core/dircontainer.h
content.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h
content.o: ../core/users.h ../core/groups.h ../core/functions.h
content.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
content.o: ../core/misc.h ../core/plugin.h ../core/request.h ../core/data.h
content.o: ../core/pluginmsg.h
createthread.o: content.h ../core/item.h ../templates/templates.h
createthread.o: ../templates/patterncacher.h ../core/thread.h
createthread.o: ../core/request.h ../core/requesttypes.h ../core/session.h
@ -26,9 +27,9 @@ createthread.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
createthread.o: ../core/user.h ../core/rebus.h ../core/function.h
createthread.o: ../core/thread.h ../core/compress.h
createthread.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
createthread.o: ../core/error.h ../core/db.h ../core/group.h
createthread.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/mount.h
createthread.o: ../core/data.h ../core/dirs.h ../core/users.h
createthread.o: ../core/htmlfilter.h ../core/error.h ../core/db.h
createthread.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
createthread.o: ../core/mount.h ../core/data.h ../core/dirs.h ../core/users.h
createthread.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
createthread.o: ../core/mounts.h ../core/mount.h
default.o: content.h ../core/item.h ../templates/templates.h
@ -37,22 +38,22 @@ default.o: ../core/requesttypes.h ../core/session.h ../core/done.h
default.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
default.o: ../core/rebus.h ../core/function.h ../core/thread.h
default.o: ../core/compress.h ../core/acceptencodingparser.h
default.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
default.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
default.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
default.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
default.o: ../core/mount.h
default.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
default.o: ../core/db.h ../core/group.h ../core/dircontainer.h
default.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h
default.o: ../core/users.h ../core/groups.h ../core/functions.h
default.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
emacs.o: content.h ../core/item.h ../templates/templates.h
emacs.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
emacs.o: ../core/requesttypes.h ../core/session.h ../core/done.h
emacs.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
emacs.o: ../core/rebus.h ../core/function.h ../core/thread.h
emacs.o: ../core/compress.h ../core/acceptencodingparser.h
emacs.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
emacs.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
emacs.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
emacs.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
emacs.o: ../core/mount.h ../core/notify.h
emacs.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
emacs.o: ../core/db.h ../core/group.h ../core/dircontainer.h
emacs.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
emacs.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
emacs.o: ../core/mounts.h ../core/mount.h ../core/notify.h
emacs.o: ../templatesnotify/templatesnotify.h ../core/mount.h ../core/misc.h
last.o: content.h ../core/item.h ../templates/templates.h
last.o: ../templates/patterncacher.h ../core/thread.h
@ -62,39 +63,41 @@ login.o: ../core/requesttypes.h ../core/session.h ../core/done.h
login.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
login.o: ../core/rebus.h ../core/function.h ../core/thread.h
login.o: ../core/compress.h ../core/acceptencodingparser.h
login.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
login.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
login.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
login.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
login.o: ../core/mount.h
login.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
login.o: ../core/db.h ../core/group.h ../core/dircontainer.h
login.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
login.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
login.o: ../core/mounts.h ../core/mount.h
logout.o: content.h ../core/item.h ../templates/templates.h
logout.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
logout.o: ../core/requesttypes.h ../core/session.h ../core/done.h
logout.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
logout.o: ../core/rebus.h ../core/function.h ../core/thread.h
logout.o: ../core/compress.h ../core/acceptencodingparser.h
logout.o: ../core/acceptbaseparser.h ../core/data.h ../core/dirs.h
logout.o: ../core/dircontainer.h ../core/users.h ../core/ugcontainer.h
logout.o: ../core/groups.h ../core/group.h ../core/functions.h
logout.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
logout.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/data.h
logout.o: ../core/dirs.h ../core/dircontainer.h ../core/users.h
logout.o: ../core/ugcontainer.h ../core/groups.h ../core/group.h
logout.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
logout.o: ../core/mount.h
ls.o: content.h ../core/item.h ../templates/templates.h
ls.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
ls.o: ../core/requesttypes.h ../core/session.h ../core/done.h ../core/item.h
ls.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h
ls.o: ../core/function.h ../core/thread.h ../core/compress.h
ls.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h ../core/db.h
ls.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
ls.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
ls.o: ../core/htmlfilter.h ../core/db.h ../core/group.h
ls.o: ../core/dircontainer.h ../core/ugcontainer.h
mkdir.o: content.h ../core/item.h ../templates/templates.h
mkdir.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
mkdir.o: ../core/requesttypes.h ../core/session.h ../core/done.h
mkdir.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
mkdir.o: ../core/rebus.h ../core/function.h ../core/thread.h
mkdir.o: ../core/compress.h ../core/acceptencodingparser.h
mkdir.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
mkdir.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
mkdir.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
mkdir.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
mkdir.o: ../core/mount.h ../core/notify.h
mkdir.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
mkdir.o: ../core/db.h ../core/group.h ../core/dircontainer.h
mkdir.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
mkdir.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
mkdir.o: ../core/mounts.h ../core/mount.h ../core/notify.h
mkdir.o: ../templatesnotify/templatesnotify.h ../core/mount.h
node.o: content.h ../core/item.h ../templates/templates.h
node.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
@ -102,52 +105,52 @@ node.o: ../core/requesttypes.h ../core/session.h ../core/done.h
node.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
node.o: ../core/rebus.h ../core/function.h ../core/thread.h
node.o: ../core/compress.h ../core/acceptencodingparser.h
node.o: ../core/acceptbaseparser.h
node.o: ../core/acceptbaseparser.h ../core/htmlfilter.h
priv.o: content.h ../core/item.h ../templates/templates.h
priv.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
priv.o: ../core/requesttypes.h ../core/session.h ../core/done.h
priv.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
priv.o: ../core/rebus.h ../core/function.h ../core/thread.h
priv.o: ../core/compress.h ../core/acceptencodingparser.h
priv.o: ../core/acceptbaseparser.h ../core/error.h ../core/db.h
priv.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
priv.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
priv.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
priv.o: ../core/mount.h
priv.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
priv.o: ../core/db.h ../core/group.h ../core/dircontainer.h
priv.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
priv.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
priv.o: ../core/mounts.h ../core/mount.h
reload.o: content.h ../core/item.h ../templates/templates.h
reload.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
reload.o: ../core/requesttypes.h ../core/session.h ../core/done.h
reload.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
reload.o: ../core/rebus.h ../core/function.h ../core/thread.h
reload.o: ../core/compress.h ../core/acceptencodingparser.h
reload.o: ../core/acceptbaseparser.h ../core/error.h
reload.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/error.h
rm.o: content.h ../core/item.h ../templates/templates.h
rm.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
rm.o: ../core/requesttypes.h ../core/session.h ../core/done.h ../core/item.h
rm.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h
rm.o: ../core/function.h ../core/thread.h ../core/compress.h
rm.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
rm.o: ../core/error.h ../core/db.h ../core/group.h ../core/dircontainer.h
rm.o: ../core/ugcontainer.h ../core/data.h ../core/dirs.h ../core/users.h
rm.o: ../core/groups.h ../core/functions.h ../core/lastcontainer.h
rm.o: ../core/mounts.h ../core/mount.h
rm.o: ../core/htmlfilter.h ../core/error.h ../core/db.h ../core/group.h
rm.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
rm.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
rm.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
run.o: content.h ../core/item.h ../templates/templates.h
run.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
run.o: ../core/requesttypes.h ../core/session.h ../core/done.h ../core/item.h
run.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h
run.o: ../core/function.h ../core/thread.h ../core/compress.h
run.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
run.o: ../core/error.h
run.o: ../core/htmlfilter.h ../core/error.h
thread.o: content.h ../core/item.h ../templates/templates.h
thread.o: ../templates/patterncacher.h ../core/thread.h ../core/request.h
thread.o: ../core/requesttypes.h ../core/session.h ../core/done.h
thread.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
thread.o: ../core/rebus.h ../core/function.h ../core/thread.h
thread.o: ../core/compress.h ../core/acceptencodingparser.h
thread.o: ../core/acceptbaseparser.h ../core/db.h ../core/group.h
thread.o: ../core/dircontainer.h ../core/ugcontainer.h ../core/data.h
thread.o: ../core/dirs.h ../core/users.h ../core/groups.h ../core/functions.h
thread.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
thread.o: ../core/mount.h
thread.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/db.h
thread.o: ../core/group.h ../core/dircontainer.h ../core/ugcontainer.h
thread.o: ../core/data.h ../core/dirs.h ../core/users.h ../core/groups.h
thread.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
thread.o: ../core/mount.h ../core/mount.h
who.o: content.h ../core/item.h ../templates/templates.h
who.o: ../templates/patterncacher.h ../core/thread.h

View File

@ -189,6 +189,10 @@ void Content::MakePost()
switch( request.pfunction->code )
{
case FUN_RUN:
PostFunRun();
break;
case FUN_EMACS:
PostFunEmacs();
break;
@ -215,7 +219,6 @@ void Content::MakePost()
default:
log << log1 << "Content: unknown post function" << logend;
// !! moze daj tutaj tez access denied?
break;
}
}
@ -235,20 +238,19 @@ void Content::Make()
{
if( DirsHaveReadExecPerm() )
{
if( request.method == Request::post )
MakePost();
if( !request.redirect_to.empty() )
return;
if( request.status == Error::ok )
if( request.redirect_to.empty() && request.status == Error::ok )
MakeStandardFunction();
}
else
request.status = Error::permision_denied;
}
if( request.session->spam_score > 0 )
log << log1 << "Content: spam score: " << request.session->spam_score << logend;
if( !request.redirect_to.empty() )
return;
@ -375,6 +377,10 @@ bool Content::CheckRebus()
// logged user don't have to use the rebus
return true;
if( request.session->rebus_checked )
return true;
request.session->rebus_checked = true;
if( !request.session->rebus_item )
{
@ -394,6 +400,8 @@ bool Content::CheckRebus()
}
log << log1 << "Content: rebus has an incorrect answer" << logend;
// don't add request.session->spam_score when the rebus has incorrect answer
// a user could have made a mistake
return false;
}
@ -412,3 +420,26 @@ void Content::SetUser(Item & item)
request.PostVar("guestname", item.guest_name);
}
}
void Content::CheckGetPostTimes(time_t difference)
{
time_t now = std::time(0);
if( request.session->puser )
return;
if( request.method != Request::post )
return;
if( now - request.session->last_time_get >= (time_t)difference )
return;
if( request.AllPostVarEmpty() )
return;
request.session->spam_score += 1;
log << log1 << "Content: spam +1: POST after GET sent too fast" << logend;
}

View File

@ -55,6 +55,7 @@ class Content
void FunMkdir();
void FunDefault();
void FunRun();
void PostFunRun();
void FunWho();
void FunLast();
@ -77,11 +78,13 @@ class Content
void PostFunPriv(Item & item);
bool FunCreateThreadCheckAccess();
bool FunCreateThreadCheckAbuse();
void PostFunCreateThread();
void RedirectTo(const Item & item);
void RedirectTo(long item_id);
void CheckGetPostTimes(time_t difference = 10);
public:

View File

@ -28,20 +28,44 @@ return true;
}
bool Content::FunCreateThreadCheckAbuse()
{
if( !CheckRebus() )
{
request.status = Error::incorrect_rebus;
request.session->done = Done::added_thread;
request.session->done_status = Error::incorrect_rebus;
return false;
}
CheckGetPostTimes();
if( request.session->spam_score > 0 )
{
request.status = Error::spam;
request.session->done = Done::added_thread;
request.session->done_status = Error::spam;
log << log1 << "Content: ignoring due to suspected spamming" << logend;
return false;
}
return true;
}
void Content::PostFunCreateThread()
{
if( !FunCreateThreadCheckAccess() )
return;
if( !CheckRebus() )
if( !FunCreateThreadCheckAbuse() )
{
request.status = Error::rebus_bad_answer;
request.PostVar("url", request.item.url);
request.PostVar("subject", request.item.subject);
request.PostVar("content", request.item.content);
SetUser(request.item);
return;
}
@ -68,12 +92,11 @@ void Content::PostFunCreateThread()
if( request.session->done_status == Error::ok )
{
request.session->done = Done::added_thread;
log << log2 << "Content: added a new thread" << logend;
RedirectTo(*request.dir_table.back());
}
}
}

View File

@ -62,6 +62,7 @@ void Content::PostFunEmacsAdd()
if( request.session->done_status == Error::ok )
{
log << log2 << "Content: added a new item" << logend;
request.notify_code |= CMSLU_NOTIFY_ITEM_ADD;
}
}
@ -83,6 +84,7 @@ void Content::PostFunEmacsEdit(bool with_url)
if( request.session->done_status == Error::ok )
{
TemplatesFunctions::pattern_cacher.UpdatePattern(request.item);
log << log2 << "Content: modified an item" << logend;
request.notify_code |= CMSLU_NOTIFY_ITEM_EDIT;
}
@ -142,8 +144,25 @@ bool adding = !request.is_item;
if( !CheckRebus() )
{
request.status = Error::rebus_bad_answer;
request.status = Error::spam;
SetUser(request.item);
request.session->done = (adding)? Done::added_item : Done::edited_item;
request.session->done_status = Error::incorrect_rebus;
return;
}
// !! is tested in createthread once
CheckGetPostTimes();
if( request.session->spam_score > 0 )
{
request.status = Error::spam;
SetUser(request.item);
request.session->done = (adding)? Done::added_item : Done::edited_item;
request.session->done_status = Error::spam;
log << log1 << "Content: ignoring due to suspected spamming" << logend;
return;
}

View File

@ -41,6 +41,7 @@ void Content::PostFunLogin()
if( login && pass && db.CheckUser(*login, *pass, user_id) )
{
request.session->puser = data.users.GetUser(user_id);
request.session->spam_score = 0;
if( !request.session->puser )
{

View File

@ -19,7 +19,6 @@ void Content::FunReloadTemplates()
request.session->done = Done::reloaded_templates;
request.session->done_status = Error::ok;
request.session->done_timer = 1;
}

View File

@ -31,5 +31,8 @@ void Content::FunRun()
}
void Content::PostFunRun()
{
FunRun();
}

View File

@ -6,7 +6,8 @@ config.o: config.h ../confparser/confparser.h log.h data.h dirs.h item.h
config.o: dircontainer.h users.h user.h ugcontainer.h groups.h group.h
config.o: functions.h function.h lastcontainer.h mounts.h mount.h rebus.h
config.o: plugin.h request.h requesttypes.h session.h done.h error.h thread.h
config.o: compress.h acceptencodingparser.h acceptbaseparser.h pluginmsg.h
config.o: compress.h acceptencodingparser.h acceptbaseparser.h htmlfilter.h
config.o: pluginmsg.h
data.o: data.h dirs.h item.h dircontainer.h users.h user.h ugcontainer.h
data.o: log.h groups.h group.h functions.h function.h lastcontainer.h
data.o: mounts.h mount.h rebus.h
@ -27,9 +28,11 @@ functionparser.o: dirs.h dircontainer.h users.h user.h ugcontainer.h groups.h
functionparser.o: group.h functions.h function.h lastcontainer.h mounts.h
functionparser.o: mount.h rebus.h db.h thread.h request.h session.h done.h
functionparser.o: compress.h acceptencodingparser.h acceptbaseparser.h
functionparser.o: htmlfilter.h
functions.o: functions.h function.h item.h
groups.o: groups.h group.h ugcontainer.h log.h db.h item.h user.h thread.h
groups.o: error.h dircontainer.h
htmlfilter.o: htmlfilter.h
httpsimpleparser.o: httpsimpleparser.h
lastcontainer.o: lastcontainer.h log.h
log.o: log.h
@ -42,22 +45,22 @@ mounts.o: mounts.h mount.h data.h dirs.h item.h dircontainer.h users.h user.h
mounts.o: ugcontainer.h log.h groups.h group.h functions.h function.h
mounts.o: lastcontainer.h rebus.h request.h requesttypes.h session.h done.h
mounts.o: error.h thread.h compress.h acceptencodingparser.h
mounts.o: acceptbaseparser.h mountparser.h db.h
mounts.o: acceptbaseparser.h htmlfilter.h mountparser.h db.h
notify.o: log.h notify.h ../templatesnotify/templatesnotify.h ../core/mount.h
notify.o: data.h dirs.h item.h dircontainer.h users.h user.h ugcontainer.h
notify.o: groups.h group.h functions.h function.h lastcontainer.h mounts.h
notify.o: mount.h rebus.h misc.h request.h requesttypes.h session.h done.h
notify.o: error.h thread.h compress.h acceptencodingparser.h
notify.o: acceptbaseparser.h
notify.o: acceptbaseparser.h htmlfilter.h
plugin.o: plugin.h request.h requesttypes.h session.h done.h item.h error.h
plugin.o: log.h user.h rebus.h function.h thread.h compress.h
plugin.o: acceptencodingparser.h acceptbaseparser.h data.h dirs.h
plugin.o: dircontainer.h users.h ugcontainer.h groups.h group.h functions.h
plugin.o: lastcontainer.h mounts.h mount.h pluginmsg.h
plugin.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h data.h
plugin.o: dirs.h dircontainer.h users.h ugcontainer.h groups.h group.h
plugin.o: functions.h lastcontainer.h mounts.h mount.h pluginmsg.h
rebus.o: log.h rebus.h misc.h item.h
request.o: request.h requesttypes.h session.h done.h item.h error.h log.h
request.o: user.h rebus.h function.h thread.h compress.h
request.o: acceptencodingparser.h acceptbaseparser.h getparser.h
request.o: acceptencodingparser.h acceptbaseparser.h htmlfilter.h getparser.h
request.o: httpsimpleparser.h postparser.h cookieparser.h data.h dirs.h
request.o: dircontainer.h users.h ugcontainer.h groups.h group.h functions.h
request.o: lastcontainer.h mounts.h mount.h plugin.h pluginmsg.h misc.h
@ -69,8 +72,8 @@ requestcontroller.o: functionparser.h requesttypes.h data.h dirs.h
requestcontroller.o: dircontainer.h users.h ugcontainer.h groups.h group.h
requestcontroller.o: functions.h function.h lastcontainer.h mounts.h mount.h
requestcontroller.o: request.h thread.h compress.h acceptencodingparser.h
requestcontroller.o: acceptbaseparser.h postparser.h httpsimpleparser.h
requestcontroller.o: cookieparser.h notify.h
requestcontroller.o: acceptbaseparser.h htmlfilter.h postparser.h
requestcontroller.o: httpsimpleparser.h cookieparser.h notify.h
requestcontroller.o: ../templatesnotify/templatesnotify.h ../core/mount.h
session.o: session.h done.h item.h error.h log.h user.h rebus.h
sessioncontainer.o: sessioncontainer.h session.h done.h item.h error.h log.h
@ -80,9 +83,10 @@ sessioncontainer.o: lastcontainer.h mounts.h mount.h
sessionmanager.o: sessionmanager.h sessioncontainer.h session.h done.h item.h
sessionmanager.o: error.h log.h user.h rebus.h request.h requesttypes.h
sessionmanager.o: function.h thread.h compress.h acceptencodingparser.h
sessionmanager.o: acceptbaseparser.h data.h dirs.h dircontainer.h users.h
sessionmanager.o: ugcontainer.h groups.h group.h functions.h lastcontainer.h
sessionmanager.o: mounts.h mount.h sessionparser.h
sessionmanager.o: acceptbaseparser.h htmlfilter.h data.h dirs.h
sessionmanager.o: dircontainer.h users.h ugcontainer.h groups.h group.h
sessionmanager.o: functions.h lastcontainer.h mounts.h mount.h
sessionmanager.o: sessionparser.h
sessionparser.o: sessionparser.h session.h done.h item.h error.h log.h user.h
sessionparser.o: rebus.h sessioncontainer.h data.h dirs.h dircontainer.h
sessionparser.o: users.h ugcontainer.h groups.h group.h functions.h

View File

@ -1 +1 @@
o = acceptbaseparser.o compress.o config.o data.o db.o db_itemcolumns.o dircontainer.o dirs.o done.o error.o function.o functioncodeparser.o functionparser.o functions.o groups.o httpsimpleparser.o lastcontainer.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o rebus.o request.o requestcontroller.o session.o sessioncontainer.o sessionmanager.o sessionparser.o users.o
o = acceptbaseparser.o compress.o config.o data.o db.o db_itemcolumns.o dircontainer.o dirs.o done.o error.o function.o functioncodeparser.o functionparser.o functions.o groups.o htmlfilter.o httpsimpleparser.o lastcontainer.o log.o misc.o mount.o mountparser.o mounts.o notify.o plugin.o rebus.o request.o requestcontroller.o session.o sessioncontainer.o sessionmanager.o sessionparser.o users.o

View File

@ -126,6 +126,8 @@ void Config::AssignValues()
std::string p = Text("plugin");
data.plugin_file.push_back(p);
data.html_filter = Bool("html_filter");
}
@ -179,7 +181,7 @@ bool Config::Bool(const char * name)
return default_int;
}
bool res = default_int;
bool res = default_bool;
if( i->second == "true" || i->second == "1" || i->second == "yes" )
res = true;

View File

@ -98,6 +98,9 @@ public:
// plugins
std::vector<std::string> plugin_file;
// the html code is cleaned by our filter
bool html_filter;
// end config members
// -----------------------------------------------------------------

View File

@ -51,7 +51,8 @@ public:
no_thread,
empty,
rebus_bad_answer,
spam,
incorrect_rebus,
unknown = 1000

799
core/htmlfilter.cpp Executable file
View File

@ -0,0 +1,799 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* All rights reserved.
*
*/
#include "htmlfilter.h"
void HTMLFilter::Item::Clear()
{
name[0] = 0;
name_len = 0;
type = none;
new_line = false;
}
HTMLFilter::Item::Item()
{
Clear();
}
void HTMLFilter::Filter(const char * in, std::string & out)
{
pchar = in;
stack_len = 0;
out_string = &out;
last_new_line = false;
out_string->clear();
Read();
}
void HTMLFilter::Filter(const std::string & in, std::string & out)
{
out.reserve(in.size() * 2 + 1);
Filter(in.c_str(), out);
}
HTMLFilter::HTMLFilter()
{
pstack = new Item[CMSLU_HTMLFILTER_STACK_MAXLEN];
buffer = new char[CMSLU_HTMLFILTER_BUFFER_MAXLEN];
tab_size = 2;
trim_white = false;
break_long_lines = false;
}
HTMLFilter::HTMLFilter(const HTMLFilter & f)
{
// don't need to copy the stack
pstack = new Item[CMSLU_HTMLFILTER_STACK_MAXLEN];
buffer = new char[CMSLU_HTMLFILTER_BUFFER_MAXLEN];
}
HTMLFilter & HTMLFilter::operator=(const HTMLFilter & f)
{
// don't need to copy the stack
pstack = new Item[CMSLU_HTMLFILTER_STACK_MAXLEN];
buffer = new char[CMSLU_HTMLFILTER_BUFFER_MAXLEN];
return *this;
}
HTMLFilter::~HTMLFilter()
{
delete [] pstack;
delete [] buffer;
}
void HTMLFilter::BreakLongLines(bool break_lines)
{
break_long_lines = break_lines;
}
void HTMLFilter::TrimWhite(bool trim)
{
trim_white = trim;
}
void HTMLFilter::InsertTabs(size_t tabsize)
{
tab_size = tabsize;
if( tab_size > 1000 )
tab_size = 1000;
}
HTMLFilter::Item & HTMLFilter::GetItem(size_t i)
{
if( i >= stack_len )
{
empty.Clear();
return empty;
}
return pstack[i];
}
HTMLFilter::Item & HTMLFilter::LastItem()
{
if( stack_len == 0 )
{
empty.Clear();
return empty;
}
return pstack[stack_len-1];
}
bool HTMLFilter::PushStack()
{
if( stack_len == CMSLU_HTMLFILTER_STACK_MAXLEN )
// oops, too many items
return false;
pstack[stack_len].Clear();
stack_len += 1;
return true;
}
void HTMLFilter::PopStack()
{
if( stack_len == 0 )
// oops
return;
stack_len -= 1;
pstack[stack_len].Clear();
}
bool HTMLFilter::IsWhite(int c)
{
// dont use c==10 here
if( c==' ' || c=='\t' || c==13 )
return true;
return false;
}
void HTMLFilter::SkipWhite()
{
while( IsWhite(*pchar) )
++pchar;
}
void HTMLFilter::SkipWhiteLines()
{
while( *pchar==10 || IsWhite(*pchar) )
++pchar;
}
bool HTMLFilter::SkipTagCheck()
{
pchar += 1;
SkipWhite();
if( *pchar == '/' )
{
pchar += 1;
SkipWhite();
if( IsNameEqual(pchar, LastItem().name, LastItem().name_len) )
{
pchar += LastItem().name_len;
SkipWhite();
if( *pchar == '>' )
{
pchar += 1;
return true;
}
}
}
return false;
}
void HTMLFilter::SkipNormalText()
{
while( *pchar!=0 && *pchar!='<' )
++pchar;
}
void HTMLFilter::CheckNewLine()
{
const char * start = pchar;
SkipWhite();
last_new_line = (*pchar==10);
pchar = start;
}
void HTMLFilter::PutLastTagWithClosingTag()
{
const char * start = pchar;
while( *pchar != 0 )
{
if( *pchar == '<' )
{
if( SkipTagCheck() )
{
PopStack();
CheckNewLine();
break;
}
}
else
{
pchar += 1;
}
}
Put(start, pchar);
}
void HTMLFilter::SkipItem()
{
while( *pchar!=0 && *pchar!='>' )
++pchar;
if( *pchar == '>' )
++pchar;
}
void HTMLFilter::SkipItemCheckXmlSimple()
{
while( *pchar!=0 )
{
while( *pchar!=0 && *pchar!='>' && *pchar!='/')
++pchar;
if( *pchar == '/' ) // closing xml tag
{
++pchar;
SkipWhite();
if( *pchar == '>' )
{
++pchar;
LastItem().type = Item::simple;
break;
}
}
else
if( *pchar == '>' )
{
++pchar;
break;
}
}
}
bool HTMLFilter::IsValidCharForName(int c)
{
if( (c>='a' && c<='z') ||
(c>='A' && c<='Z') ||
(c>='0' && c<='9') ||
c=='-' || c=='!' )
return true;
return false;
}
void HTMLFilter::ReadItemName()
{
size_t i;
for( i=0 ; IsValidCharForName(*pchar) && i<CMSLU_HTMLFILTER_ITEM_MAXLEN-1 ; ++i )
{
LastItem().name[i] = *pchar;
++pchar;
}
LastItem().name[i] = 0;
LastItem().name_len = i;
}
void HTMLFilter::Put(const char * str, const char * end)
{
if( str>=end )
return;
size_t len = end - str;
out_string->append(str, len);
}
size_t HTMLFilter::PutTrimFillBuffer(const char * & str, const char * & end)
{
size_t non_whites = 0;
size_t i = 0;
bool was_white;
for( ; str < end && i<CMSLU_HTMLFILTER_BUFFER_MAXLEN-1 ; ++str )
{
was_white = false;
if( *str==10 || IsWhite(*str) )
{
// skipping the whole white string
for( ; (*str==10 || IsWhite(*str)) && str < end ; ++str );
was_white = true;
non_whites = 0;
}
else
{
non_whites += 1;
}
if( (non_whites>60 && break_long_lines) || was_white )
{
buffer[i] = ' ';
i += 1;
non_whites = 0;
}
if( str < end )
{
buffer[i] = *str;
i += 1;
}
}
return i;
}
// if there are more than one white characters then they will be changed into one space
// and putting a space between 50 characters (if there were not any other white characters between them)
void HTMLFilter::PutTrim(const char * str, const char * end)
{
size_t buf_len;
// this buffer must have at least 2 bytes (PutTrimFillBuffer needs it)
if( !trim_white || CMSLU_HTMLFILTER_BUFFER_MAXLEN < 2 )
{
Put(str, end);
return;
}
while( str < end )
{
buf_len = PutTrimFillBuffer(str, end);
Put(buffer, buffer+buf_len);
}
}
void HTMLFilter::PutOpeningTag(const char * tag)
{
size_t i;
if( CMSLU_HTMLFILTER_BUFFER_MAXLEN < CMSLU_HTMLFILTER_ITEM_MAXLEN+2 )
return;
buffer[0] = '<';
for(i=1 ; *tag ; ++i, ++tag)
buffer[i] = *tag;
buffer[i] = '>';
i += 1;
Put(buffer, buffer+i);
}
void HTMLFilter::PutClosingTag(const char * tag)
{
size_t i;
if( CMSLU_HTMLFILTER_BUFFER_MAXLEN < CMSLU_HTMLFILTER_ITEM_MAXLEN+3 )
return;
buffer[0] = '<';
buffer[1] = '/';
for(i=2 ; *tag ; ++i, ++tag)
buffer[i] = *tag;
buffer[i] = '>';
i += 1;
Put(buffer, buffer+i);
}
void HTMLFilter::PutTabs(size_t len)
{
if( len == 0 )
return;
if( len > 20 )
len = 20;
// how many spaces do you want
size_t spaces = (len-1) * tab_size;
size_t i;
if( spaces < CMSLU_HTMLFILTER_BUFFER_MAXLEN )
{
for(i=0 ; i<spaces ; ++i)
buffer[i] = ' ';
Put(buffer, buffer+i);
}
}
void HTMLFilter::PutNewLine()
{
if( !trim_white )
// new line characters will be directly from the source html
return;
buffer[0] = 10;
Put(buffer, buffer+1);
}
bool HTMLFilter::IsOpeningCommentaryTag()
{
static char comm_open[] = "<!--";
size_t comm_open_len = sizeof(comm_open) / sizeof(char) - 1;
return IsNameEqual(pchar, comm_open, comm_open_len);
}
// skipping the commentary tag if exists
bool HTMLFilter::SkipCommentaryTagIfExists()
{
static char comm_close[] = "-->";
size_t comm_close_len = sizeof(comm_close) / sizeof(char) - 1;
if( !IsOpeningCommentaryTag() )
return false;
pchar += 4; // size of commentary opening tag
// looking for "-->"
while( *pchar!=0 && !IsNameEqual(pchar, comm_close, comm_close_len) )
++pchar;
if( *pchar!= 0 )
pchar += comm_close_len;
CheckNewLine();
return true;
}
void HTMLFilter::ReadNormalText()
{
const char * start = pchar;
SkipWhiteLines();
if( *pchar!=0 && (IsOpeningCommentaryTag() || *pchar!='<') && last_new_line )
{
if( *pchar == '<' )
// skipping some white characters before a opening commentary tag
// (but only a tag in a new line)
start = pchar;
PutNewLine();
PutTabs(stack_len+1);
last_new_line = false; // in normal text we don't allow a new line character
}
while( *pchar != 0 )
{
if( !SkipCommentaryTagIfExists() )
{
if( *pchar == '<' )
break;
pchar += 1;
}
}
PutTrim(start, pchar);
}
void HTMLFilter::PrintItem(const char * start, const char * end)
{
if( LastItem().type != Item::closing )
{
if( last_new_line )
{
if( stack_len > 0 )
PutNewLine();
if( stack_len > 1 )
PutTabs(stack_len);
}
// closing tags will be printed later
// (when we check the stack)
Put(start, pchar);
}
}
bool HTMLFilter::ReadItem()
{
const char * start;
if( *pchar == 0 )
return false;
// we have '<'
start = pchar;
pchar += 1;
SkipWhite();
if( PushStack() )
{
if( *pchar == '/' ) // we have a closing tag
{
pchar += 1;
SkipWhite();
LastItem().type = Item::closing;
}
ReadItemName();
if( LastItem().type != Item::closing )
LastItem().type = (LastItem().name[0] == '!') ? Item::special : Item::opening;
SkipItemCheckXmlSimple();
PrintItem(start, pchar);
CheckNewLine();
LastItem().new_line = last_new_line;
return true;
}
pchar = start;
return false;
}
int HTMLFilter::ToLower(int c)
{
if( c>='A' && c<='Z' )
return c - 'A' + 'a';
return c;
}
bool HTMLFilter::IsNameEqual(const char * name1, const char * name2)
{
for( ; *name1!=0 && *name2!=0 ; ++name1, ++name2 )
if( ToLower(*name1) != ToLower(*name2) )
return false;
if( *name1==0 && *name2==0 )
return true;
return false;
}
// len characters from both strings must be equal
bool HTMLFilter::IsNameEqual(const char * name1, const char * name2, size_t len)
{
for( ; *name1!=0 && *name2!=0 && len>0 ; ++name1, ++name2, --len )
if( ToLower(*name1) != ToLower(*name2) )
return false;
if( len == 0 )
return true;
return false;
}
bool HTMLFilter::IsLastTag(const char * name)
{
const char * tag = LastItem().name;
return IsNameEqual(name, tag);
}
// checking exceptions for opening tags
void HTMLFilter::CheckExceptions()
{
if( IsLastTag("meta") ||
IsLastTag("input") ||
IsLastTag("br") ||
IsLastTag("img") ||
IsLastTag("link") )
{
LastItem().type = Item::simple;
PopStack();
return;
}
if( IsLastTag("script") || IsLastTag("pre") || IsLastTag("textarea") )
PutLastTagWithClosingTag();
}
void HTMLFilter::AddForgottenTags()
{
int i;
if( stack_len < 3 )
return;
// we have forgotten to close some tags
// looking whether there is a matching opening tag
for(i=int(stack_len)-3 ; i>=0 ; --i)
if( IsNameEqual(pstack[i].name, pstack[stack_len-1].name) )
break;
if( i < 0 )
{
// oops, there is no such a tag
// we don't print the closing and the missing opening tag
PopStack();
return;
}
for(int z=(int)stack_len-2 ; z>=i ; --z)
{
if( pstack[z].new_line )
{
PutNewLine();
PutTabs(z+1);
}
PutClosingTag(pstack[z].name);
pstack[z].Clear();
}
last_new_line = pstack[stack_len-1].new_line;
// invalidate tags
stack_len = i;
}
void HTMLFilter::CheckClosingTags()
{
if( stack_len == 0 )
return;
// on the stack we have only opening tags
// but only the last tag is a closing tag
if( stack_len == 1 )
{
// there is only last closing tag
// we dont print it
PopStack();
return;
}
// there are more than one tag
if( IsNameEqual(pstack[stack_len-1].name, pstack[stack_len-2].name) )
{
// last closing tag is from the previous one
if( pstack[stack_len-2].new_line )
{
PutNewLine();
PutTabs(stack_len-1);
}
PutClosingTag(pstack[stack_len-1].name);
last_new_line = pstack[stack_len-1].new_line;
PopStack();
PopStack();
return;
}
AddForgottenTags();
}
void HTMLFilter::PrintRest()
{
const char * start = pchar;
while( *pchar )
++pchar;
if( pchar > start )
Put(start, pchar);
}
void HTMLFilter::Read()
{
// white characters at the beginning are skipped
SkipWhiteLines();
// it can be some text before the first html tag (we print it)
ReadNormalText();
while( *pchar && ReadItem() )
{
if( LastItem().type == Item::opening )
{
CheckExceptions();
}
else
if( LastItem().type == Item::special || LastItem().type == Item::simple )
{
if( stack_len > 1 )
{
pstack[stack_len-2].new_line = LastItem().new_line;
}
else
{
// one new line after a simple or special tag
// (if the tag has level 0 in the tree - it not means that this is a first tag)
// for example can be DOCTYPE
PutNewLine();
}
PopStack();
}
else
if( LastItem().type == Item::closing )
{
CheckClosingTags();
}
ReadNormalText();
}
// sometimes ReadItem() can return a false (when there is no space on the stack)
// we print the rest html without filtering
PrintRest();
}

166
core/htmlfilter.h Executable file
View File

@ -0,0 +1,166 @@
/*
* This file is a part of CMSLU -- Content Management System like Unix
* and is not publicly distributed
*
* Copyright (c) 2008-2009, Tomasz Sowa
* All rights reserved.
*
*/
#ifndef headerfilecmslucorehtmlfilter
#define headerfilecmslucorehtmlfilter
#include <string>
// max length of a name of a html tag (with terminating null)
#define CMSLU_HTMLFILTER_ITEM_MAXLEN 30
// depth of the html tree
#define CMSLU_HTMLFILTER_STACK_MAXLEN 100
// length of a buffer used for printing
// it should be at least: CMSLU_HTMLFILTER_ITEM_MAXLEN+3
#define CMSLU_HTMLFILTER_BUFFER_MAXLEN 1024
/*!
very lightweight filter for html
(without using any dynamic memory - some memory is allocated only at the beginning - in ctors)
this filter has O(n) complexity over the whole html string
such tags as: <script> <pre> <textarea> are treated in a special way
all characters between the opening and closing tag (<script>....</script>) are untouched
if the filter finds that there are not closed tags it will close them,
if the filter finds a closing tag which doesn't have an opening tag - it will skip it
tags which don't need to be closed: meta, input, br, img, link
look at CheckExceptions() method
the filter recognizes xml simple tags (with / at the end) such as: <br />
*/
class HTMLFilter
{
public:
HTMLFilter();
HTMLFilter(const HTMLFilter & f);
HTMLFilter & operator=(const HTMLFilter & f);
~HTMLFilter();
// main methods used for filtering
void Filter(const char * in, std::string & out);
void Filter(const std::string & in, std::string & out);
// insert a white space into long lines
// only between html tags
// skipped in such tags: script, pre, textarea
// false by default
void BreakLongLines(bool break_lines);
// trimming white characters (with new lines)
// at the beginning, at the end and in the middle of a string
// only between html tags
// at the beginning and at the end only one space is left
// skipped in such tags: script, pre, textarea
// false by default
void TrimWhite(bool trim);
// first tabs in a tree
// default: 2 (spaces)
// set 0 to turn off
void InsertTabs(size_t tabsize);
protected:
struct Item
{
char name[CMSLU_HTMLFILTER_ITEM_MAXLEN];
size_t name_len;
enum Type
{
opening,
closing,
simple,
special,
none
} type;
// is there a new line after this tag
bool new_line;
void Clear();
Item();
};
// only this method have direct access to the output string
// you can easily change the output from a std::string to something else
void Put(const char * str, const char * end);
Item & GetItem(size_t i);
Item & LastItem();
int ToLower(int c);
bool IsNameEqual(const char * name1, const char * name2);
bool IsNameEqual(const char * name1, const char * name2, size_t len);
bool IsLastTag(const char * name);
bool IsWhite(int c);
void SkipWhite();
void SkipWhiteLines();
bool SkipTagCheck();
void SkipNormalText();
bool IsOpeningCommentaryTag();
bool SkipCommentaryTagIfExists();
void SkipItem();
void SkipItemCheckXmlSimple();
void PopStack();
bool PushStack();
bool IsValidCharForName(int c);
void CheckNewLine();
void CheckExceptions();
void AddForgottenTags();
void CheckClosingTags();
void ReadNormalText();
void PrintRest();
void PrintItem(const char * start, const char * end);
void ReadItemName();
bool ReadItem();
void Read();
size_t PutTrimFillBuffer(const char * & str, const char * & end);
void PutTrim(const char * str, const char * end);
void PutLastTagWithClosingTag();
void PutOpeningTag(const char * tag);
void PutClosingTag(const char * tag);
void PutTabs(size_t len);
void PutNewLine();
const char * pchar;
Item empty;
Item * pstack; // stack pointer
size_t stack_len; // length of the stack
char * buffer; // buffer used when printing
std::string * out_string;
bool last_new_line;
bool break_long_lines; // insert a space into long lines
bool trim_white; // trimming white characters
size_t tab_size;
};
#endif

View File

@ -42,7 +42,7 @@ void * Notify::ThreadRoutine(void * arg)
while( true )
{
CheckQueue();
sleep(30);
sleep(1); // !! was 30
}
}
@ -61,7 +61,7 @@ std::list<NotifyMsg>::iterator i = obj->notify_pool.begin();
i = obj->notify_pool.erase(i);
obj->Unlock();
sleep(3);
//sleep(3); // !!
}
}

View File

@ -33,7 +33,7 @@ public:
bool Init(const std::string & tdir);
/*
this method added an item to our special pool
this method addes an item to our special pool
the pool is used by a second thread
*/
void ItemChanged(int notify_code);

View File

@ -266,6 +266,18 @@ void Request::CheckMethod()
}
bool Request::AllPostVarEmpty()
{
PostTable::iterator i;
for(i=post_table.begin() ; i!=post_table.end() ; ++i)
if( !i->second.empty() )
return false;
return true;
}
void Request::ReadParameters()
{
GetParser get_parser(env_request_uri, get_table);
@ -330,11 +342,8 @@ void Request::SendSessionCookie()
}
void Request::SendAll()
void Request::SendHeaders(bool compressing)
{
SendSessionCookie();
if( !redirect_to.empty() )
{
FCGX_PutS("Status: 301 Moved Permanently\r\n", out);
@ -348,43 +357,69 @@ void Request::SendAll()
FCGX_PutS("Content-Type: Text/Html\r\n", out);
}
bool compressing = data.compression && !browser_msie && accept_encoding_parser.AcceptDeflate();
if( compressing )
FCGX_PutS("Content-Encoding: deflate\r\n", out);
FCGX_PutS(headers.str().c_str(), out);
FCGX_PutS("\r\n", out);
if( !redirect_to.empty() )
// if there is a redirect we do not send a content
return;
//
const std::string & source = page.str();
if( compressing )
{
compress.CompressAndPut(source.c_str(), source.length(), out);
}
else
{
FCGX_PutS(source.c_str(), out);
}
void Request::AddDebugInfo()
{
const std::string & d = debug.str();
if( !d.empty() )
{
FCGX_PutS("\n<!--\n", out);
FCGX_PutS(d.c_str(), out);
FCGX_PutS("\n-->\n", out);
page << "\n<!--\n";
page << d;
page << "\n-->\n";
}
}
void Request::SendPage(bool compressing)
{
const std::string & source_ref = page.str();
const std::string * source = &source_ref;
if( data.html_filter )
{
html_filter.TrimWhite(true);
html_filter.BreakLongLines(true);
html_filter.InsertTabs(2);
html_filter.Filter(*source, clean_html);
source = &clean_html;
}
if( compressing )
compress.CompressAndPut(source->c_str(), source->length(), out);
else
FCGX_PutS(source->c_str(), out);
}
void Request::SendAll()
{
bool compressing = data.compression && !browser_msie && accept_encoding_parser.AcceptDeflate();
SendSessionCookie();
SendHeaders(compressing);
if( !redirect_to.empty() )
// if there is a redirect we do not send a content
return;
// adding debug info if exists
AddDebugInfo();
// sending content
SendPage(compressing);
}

View File

@ -23,6 +23,8 @@
#include "thread.h"
#include "compress.h"
#include "acceptencodingparser.h"
#include "htmlfilter.h"
struct Request
@ -118,7 +120,7 @@ struct Request
bool IsPostVar(const char * var);
std::string * PostVar(const char * var); // it can return null when there is no such a post variable
bool PostVar(const char * var, std::string & result);
bool AllPostVarEmpty(); // returning true if all post vars are empty
void ReadEnvVariables();
void CheckMethod();
@ -150,18 +152,23 @@ private:
void SendSessionCookie();
void CheckIE();
void SendHeaders(bool compressing);
void AddDebugInfo();
void SendPage(bool compressing);
// used to set some env_* variables into it, when the server didn't set that variable
// it contains '\0'
const char char_empty;
const char * SetEnvVar(const char * var);
void StandardLog();
Compress compress;
AcceptEncodingParser accept_encoding_parser;
HTMLFilter html_filter;
// html after filtering
std::string clean_html;
};

View File

@ -20,6 +20,9 @@ Session::Session()
last_time = time;
tm_last_time = tm_time;
// the first request can be a POST (it doesn't matter)
last_time_get = time;
}
@ -33,8 +36,10 @@ void Session::Clear()
item.Clear();
done_timer = 0;
rebus_item = 0;
rebus_checked = false;
remember_me = false;
new_session = true;
spam_score = 0;
dir_old.clear();
}
@ -53,7 +58,7 @@ bool Session::operator<(const Session & s) const
/*
bool Session::DecTimer(int & timer)
{
if( timer == 0 )
@ -77,6 +82,29 @@ void Session::CheckTimers()
done_status = Error::ok;
}
}
*/
void Session::DecTimer(int & timer)
{
if( timer == 0 )
return;
--timer;
}
void Session::CheckTimers()
{
DecTimer(done_timer);
if( done_timer == 0 )
{
done = Done::none;
done_status = Error::ok;
}
}
void Session::IncrementTimersIfExist()
{

View File

@ -36,6 +36,9 @@ struct Session
time_t last_time;
tm tm_last_time;
// when there was a last get request
// (used to calculate spam)
time_t last_time_get;
// 0 - means that nobody is logged
User * puser;
@ -55,16 +58,20 @@ struct Session
// rebus - set by rebus_question(Info & i) from templates
Rebus::Item * rebus_item;
bool rebus_checked;
std::string dir_old;
int spam_score;
// -------------------
Session();
void Clear();
bool operator==(const Session & s) const;
bool operator<(const Session & s) const;
bool DecTimer(int & timer);
void DecTimer(int & timer);
void CheckTimers();
void IncrementTimersIfExist();
};

View File

@ -110,6 +110,34 @@ int attempts = 100;
bool SessionManager::SetSessionFromCookie(const std::string & cookie)
{
long id = atol(cookie.c_str());
SessionContainer::Iterator s = session_table.FindById(id);
if( s == session_table.End() )
return false;
// that session is in the table
request.session = &(*s);
request.session->new_session = false;
session_table.UpdateLastTime(s, std::time(0));
if( request.method == Request::get )
request.session->last_time_get = request.session->last_time;
log << log2 << "SM: session: " << s->id;
if( request.session->puser )
log << log2 << ", user: " << request.session->puser->name << ", id: " << request.session->puser->id;
log << log2 << logend;
return true;
}
void SessionManager::SetSession()
{
CookieTable::iterator i = request.cookie_table.find(data.http_session_id_name);
@ -120,25 +148,7 @@ void SessionManager::SetSession()
}
else
{
long id = atol(i->second.c_str());
SessionContainer::Iterator s = session_table.FindById(id);
if( s != session_table.End() )
{
// that session is in the table
request.session = &(*s);
request.session->new_session = false;
session_table.UpdateLastTime(s, std::time(0));
log << log2 << "SM: session: " << s->id;
if( request.session->puser )
log << log2 << ", user: " << request.session->puser->name << ", id: " << request.session->puser->id;
log << log2 << logend;
}
else
if( !SetSessionFromCookie(i->second) )
{
// there is no such a session
// deleting the old cookie
@ -149,8 +159,6 @@ void SessionManager::SetSession()
}
}
// request.session is set now
}

View File

@ -28,7 +28,7 @@ class SessionManager
long CreateSessionId();
void CreateTemporarySession();
void CreateSession();
bool SetSessionFromCookie(const std::string & cookie);
int session_checker;
public:

View File

@ -11,7 +11,7 @@ main.o: ../core/groups.h ../core/group.h ../core/functions.h
main.o: ../core/function.h ../core/lastcontainer.h ../core/mounts.h
main.o: ../core/mount.h ../core/log.h ../core/request.h ../core/thread.h
main.o: ../core/compress.h ../core/acceptencodingparser.h
main.o: ../core/acceptbaseparser.h ../core/db.h ../core/config.h
main.o: ../confparser/confparser.h ../core/notify.h
main.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/db.h
main.o: ../core/config.h ../confparser/confparser.h ../core/notify.h
main.o: ../templatesnotify/templatesnotify.h ../core/mount.h ../core/plugin.h
main.o: ../core/request.h ../core/data.h ../core/pluginmsg.h

View File

@ -5,10 +5,11 @@ dir.o: ../core/requesttypes.h ../core/session.h ../core/done.h ../core/item.h
dir.o: ../core/error.h ../core/log.h ../core/user.h ../core/rebus.h
dir.o: ../core/function.h ../core/thread.h ../core/compress.h
dir.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
dir.o: ../core/data.h ../core/dirs.h ../core/dircontainer.h ../core/users.h
dir.o: ../core/ugcontainer.h ../core/groups.h ../core/group.h
dir.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
dir.o: ../core/mount.h ../core/db.h ../core/log.h ../core/misc.h
dir.o: ../core/htmlfilter.h ../core/data.h ../core/dirs.h
dir.o: ../core/dircontainer.h ../core/users.h ../core/ugcontainer.h
dir.o: ../core/groups.h ../core/group.h ../core/functions.h
dir.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h ../core/db.h
dir.o: ../core/log.h ../core/misc.h
doc.o: templates.h patterncacher.h ../core/item.h ../core/data.h
doc.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h ../core/users.h
doc.o: ../core/user.h ../core/ugcontainer.h ../core/log.h ../core/groups.h
@ -17,13 +18,13 @@ doc.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
doc.o: ../core/rebus.h ../core/request.h ../core/requesttypes.h
doc.o: ../core/session.h ../core/done.h ../core/error.h ../core/thread.h
doc.o: ../core/compress.h ../core/acceptencodingparser.h
doc.o: ../core/acceptbaseparser.h ../core/misc.h
doc.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
done.o: templates.h patterncacher.h ../core/item.h ../core/request.h
done.o: ../core/requesttypes.h ../core/session.h ../core/done.h
done.o: ../core/item.h ../core/error.h ../core/log.h ../core/user.h
done.o: ../core/rebus.h ../core/function.h ../core/thread.h
done.o: ../core/compress.h ../core/acceptencodingparser.h
done.o: ../core/acceptbaseparser.h ../core/misc.h
done.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
item.o: templates.h patterncacher.h ../core/item.h ../core/data.h
item.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h ../core/users.h
item.o: ../core/user.h ../core/ugcontainer.h ../core/log.h ../core/groups.h
@ -32,7 +33,7 @@ item.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
item.o: ../core/rebus.h ../core/request.h ../core/requesttypes.h
item.o: ../core/session.h ../core/done.h ../core/error.h ../core/thread.h
item.o: ../core/compress.h ../core/acceptencodingparser.h
item.o: ../core/acceptbaseparser.h ../core/misc.h
item.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
last.o: templates.h patterncacher.h ../core/item.h ../core/lastcontainer.h
last.o: ../core/data.h ../core/dirs.h ../core/item.h ../core/dircontainer.h
last.o: ../core/users.h ../core/user.h ../core/ugcontainer.h ../core/log.h
@ -42,7 +43,7 @@ last.o: ../core/mount.h ../core/rebus.h ../core/request.h
last.o: ../core/requesttypes.h ../core/session.h ../core/done.h
last.o: ../core/error.h ../core/thread.h ../core/compress.h
last.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
last.o: ../core/misc.h
last.o: ../core/htmlfilter.h ../core/misc.h
mount.o: templates.h patterncacher.h ../core/item.h ../core/data.h
mount.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h ../core/users.h
mount.o: ../core/user.h ../core/ugcontainer.h ../core/log.h ../core/groups.h
@ -63,16 +64,16 @@ priv.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
priv.o: ../core/rebus.h ../core/request.h ../core/requesttypes.h
priv.o: ../core/session.h ../core/done.h ../core/error.h ../core/thread.h
priv.o: ../core/compress.h ../core/acceptencodingparser.h
priv.o: ../core/acceptbaseparser.h ../core/misc.h
priv.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
rebus.o: ../core/request.h ../core/requesttypes.h ../core/session.h
rebus.o: ../core/done.h ../core/item.h ../core/error.h ../core/log.h
rebus.o: ../core/user.h ../core/rebus.h ../core/function.h ../core/thread.h
rebus.o: ../core/compress.h ../core/acceptencodingparser.h
rebus.o: ../core/acceptbaseparser.h ../core/data.h ../core/dirs.h
rebus.o: ../core/dircontainer.h ../core/users.h ../core/ugcontainer.h
rebus.o: ../core/groups.h ../core/group.h ../core/functions.h
rebus.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h templates.h
rebus.o: patterncacher.h ../core/item.h
rebus.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/data.h
rebus.o: ../core/dirs.h ../core/dircontainer.h ../core/users.h
rebus.o: ../core/ugcontainer.h ../core/groups.h ../core/group.h
rebus.o: ../core/functions.h ../core/lastcontainer.h ../core/mounts.h
rebus.o: ../core/mount.h templates.h patterncacher.h ../core/item.h
sys.o: templates.h patterncacher.h ../core/item.h ../core/data.h
sys.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h ../core/users.h
sys.o: ../core/user.h ../core/ugcontainer.h ../core/log.h ../core/groups.h
@ -81,7 +82,7 @@ sys.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
sys.o: ../core/rebus.h ../core/request.h ../core/requesttypes.h
sys.o: ../core/session.h ../core/done.h ../core/error.h ../core/thread.h
sys.o: ../core/compress.h ../core/acceptencodingparser.h
sys.o: ../core/acceptbaseparser.h ../core/misc.h
sys.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
templates.o: templates.h patterncacher.h ../core/item.h ../core/data.h
templates.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h
templates.o: ../core/users.h ../core/user.h ../core/ugcontainer.h
@ -91,8 +92,9 @@ templates.o: ../core/mounts.h ../core/mount.h ../core/rebus.h
templates.o: ../core/request.h ../core/requesttypes.h ../core/session.h
templates.o: ../core/done.h ../core/error.h ../core/thread.h
templates.o: ../core/compress.h ../core/acceptencodingparser.h
templates.o: ../core/acceptbaseparser.h ../core/misc.h ../core/plugin.h
templates.o: ../core/request.h ../core/data.h ../core/pluginmsg.h
templates.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
templates.o: ../core/plugin.h ../core/request.h ../core/data.h
templates.o: ../core/pluginmsg.h
thread.o: templates.h patterncacher.h ../core/item.h ../core/data.h
thread.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h
thread.o: ../core/users.h ../core/user.h ../core/ugcontainer.h ../core/log.h
@ -102,7 +104,7 @@ thread.o: ../core/mount.h ../core/rebus.h ../core/request.h
thread.o: ../core/requesttypes.h ../core/session.h ../core/done.h
thread.o: ../core/error.h ../core/thread.h ../core/compress.h
thread.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
thread.o: ../core/misc.h
thread.o: ../core/htmlfilter.h ../core/misc.h
user.o: templates.h patterncacher.h ../core/item.h ../core/data.h
user.o: ../core/dirs.h ../core/item.h ../core/dircontainer.h ../core/users.h
user.o: ../core/user.h ../core/ugcontainer.h ../core/log.h ../core/groups.h
@ -111,7 +113,7 @@ user.o: ../core/lastcontainer.h ../core/mounts.h ../core/mount.h
user.o: ../core/rebus.h ../core/request.h ../core/requesttypes.h
user.o: ../core/session.h ../core/done.h ../core/error.h ../core/thread.h
user.o: ../core/compress.h ../core/acceptencodingparser.h
user.o: ../core/acceptbaseparser.h ../core/misc.h
user.o: ../core/acceptbaseparser.h ../core/htmlfilter.h ../core/misc.h
who.o: templates.h patterncacher.h ../core/item.h ../core/sessioncontainer.h
who.o: ../core/session.h ../core/done.h ../core/item.h ../core/error.h
who.o: ../core/log.h ../core/user.h ../core/rebus.h
@ -124,4 +126,4 @@ who.o: ../core/groups.h ../core/group.h ../core/functions.h
who.o: ../core/function.h ../core/lastcontainer.h ../core/mounts.h
who.o: ../core/mount.h ../core/request.h ../core/thread.h ../core/compress.h
who.o: ../core/acceptencodingparser.h ../core/acceptbaseparser.h
who.o: ../core/misc.h
who.o: ../core/htmlfilter.h ../core/misc.h

View File

@ -71,13 +71,13 @@ void doc_current_url(Info & i)
void doc_status_error(Info & i)
void doc_is_error(Info & i)
{
i.result = request.status != Error::ok;
}
void doc_status_code(Info & i)
void doc_status(Info & i)
{
i.out << static_cast<int>( request.status );
}

View File

@ -18,7 +18,7 @@ namespace TemplatesFunctions
void done_errors(Info & i)
void done_is_error(Info & i)
{
i.result = request.session->done_status != Error::ok;
}
@ -41,7 +41,15 @@ void done_status_incorrect_dir(Info & i)
i.result = request.session->done_status == Error::incorrect_dir;
}
void done_status_incorrect_rebus(Info & i)
{
i.result = request.session->done_status == Error::incorrect_rebus;
}
void done_status_spam(Info & i)
{
i.result = request.session->done_status == Error::spam;
}
void done_added_item(Info & i)
{

View File

@ -27,6 +27,7 @@ void rebus_init()
if( rebus_reqid != request.id )
{
request.session->rebus_item = data.rebus.Rand();
request.session->rebus_checked = false;
rebus_reqid = request.id;
}
}

View File

@ -136,7 +136,8 @@ Ezc::Pattern * p = 0;
switch( request.status )
{
case Error::ok:
case Error::rebus_bad_answer:
case Error::spam:
case Error::incorrect_rebus:
p = content_for_function();
break;
@ -206,9 +207,8 @@ void Templates::CreateFunctions()
functions.Insert("doc_charset", doc_charset);
functions.Insert("doc_base_url", doc_base_url);
functions.Insert("doc_current_url", doc_current_url);
functions.Insert("doc_status_error", doc_status_error);
functions.Insert("doc_status_code", doc_status_code);
functions.Insert("doc_is_error", doc_is_error);
functions.Insert("doc_status", doc_status);
/*
item
@ -317,10 +317,12 @@ void Templates::CreateFunctions()
/*
done
*/
functions.Insert("done_errors", done_errors);
functions.Insert("done_is_error", done_is_error);
functions.Insert("done_status", done_status);
functions.Insert("done_status_no_item", done_status_no_item);
functions.Insert("done_status_incorrect_dir", done_status_incorrect_dir);
functions.Insert("done_status_incorrect_rebus", done_status_incorrect_rebus);
functions.Insert("done_status_spam", done_status_spam);
functions.Insert("done_added_item", done_added_item);
functions.Insert("done_edited_item", done_edited_item);
functions.Insert("done_deleted_item", done_deleted_item);

View File

@ -46,8 +46,8 @@ namespace TemplatesFunctions
void doc_charset(Info & i);
void doc_base_url(Info & i);
void doc_current_url(Info & i);
void doc_status_error(Info & i);
void doc_status_code(Info & i);
void doc_is_error(Info & i);
void doc_status(Info & i);
/*
@ -158,10 +158,12 @@ namespace TemplatesFunctions
/*
done
*/
void done_errors(Info & i);
void done_is_error(Info & i);
void done_status(Info & i);
void done_status_no_item(Info & i);
void done_status_incorrect_dir(Info & i);
void done_status_incorrect_rebus(Info & i);
void done_status_spam(Info & i);
void done_added_item(Info & i);
void done_edited_item(Info & i);

View File

@ -56,6 +56,7 @@ void TemplatesNotify::Read(const std::string & templates_dir)
{
using namespace TemplatesNotifyFunctions;
pat_notify_email.delete_all_white = true;
pat_notify_email.Directory(templates_dir);
pat_notify_email.ParseFile("notify_email.txt");