diff --git a/Makefile b/Makefile index 6103475..c74191f 100755 --- a/Makefile +++ b/Makefile @@ -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/ diff --git a/content/Makefile.dep b/content/Makefile.dep index 70d7dc1..a2a84ed 100755 --- a/content/Makefile.dep +++ b/content/Makefile.dep @@ -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 diff --git a/content/content.cpp b/content/content.cpp index a57ebaa..ce14779 100755 --- a/content/content.cpp +++ b/content/content.cpp @@ -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,8 +400,10 @@ 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; +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; +} + diff --git a/content/content.h b/content/content.h index 5f4ba6f..b7ae7ad 100755 --- a/content/content.h +++ b/content/content.h @@ -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: diff --git a/content/createthread.cpp b/content/createthread.cpp index 6b3dca6..8bedc9d 100755 --- a/content/createthread.cpp +++ b/content/createthread.cpp @@ -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()); } - } - - } diff --git a/content/emacs.cpp b/content/emacs.cpp index 52c6785..077888c 100755 --- a/content/emacs.cpp +++ b/content/emacs.cpp @@ -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,7 +84,8 @@ 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; } diff --git a/content/login.cpp b/content/login.cpp index 925f204..abb9855 100755 --- a/content/login.cpp +++ b/content/login.cpp @@ -41,7 +41,8 @@ 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 ) { log << log1 << "Content: user: " << login << " is in the database but is not in data.users" << logend; diff --git a/content/reload.cpp b/content/reload.cpp index 8af3333..140749e 100755 --- a/content/reload.cpp +++ b/content/reload.cpp @@ -19,7 +19,6 @@ void Content::FunReloadTemplates() request.session->done = Done::reloaded_templates; request.session->done_status = Error::ok; - request.session->done_timer = 1; } diff --git a/content/run.cpp b/content/run.cpp index cb1eb09..889d446 100755 --- a/content/run.cpp +++ b/content/run.cpp @@ -31,5 +31,8 @@ void Content::FunRun() } - +void Content::PostFunRun() +{ + FunRun(); +} diff --git a/core/Makefile.dep b/core/Makefile.dep index ab3d0fa..dbc3ef4 100755 --- a/core/Makefile.dep +++ b/core/Makefile.dep @@ -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 diff --git a/core/Makefile.o.dep b/core/Makefile.o.dep index 52d30b7..17bcbe6 100755 --- a/core/Makefile.o.dep +++ b/core/Makefile.o.dep @@ -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 diff --git a/core/config.cpp b/core/config.cpp index bee976f..84eecb4 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -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; diff --git a/core/data.h b/core/data.h index fbead21..75a2b78 100755 --- a/core/data.h +++ b/core/data.h @@ -98,6 +98,9 @@ public: // plugins std::vector plugin_file; + // the html code is cleaned by our filter + bool html_filter; + // end config members // ----------------------------------------------------------------- diff --git a/core/error.h b/core/error.h index 6a57c91..73339af 100755 --- a/core/error.h +++ b/core/error.h @@ -51,7 +51,8 @@ public: no_thread, empty, - rebus_bad_answer, + spam, + incorrect_rebus, unknown = 1000 diff --git a/core/htmlfilter.cpp b/core/htmlfilter.cpp new file mode 100755 index 0000000..86f6149 --- /dev/null +++ b/core/htmlfilter.cpp @@ -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=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 && i60 && 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" + 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(); +} + + + + + + diff --git a/core/htmlfilter.h b/core/htmlfilter.h new file mode 100755 index 0000000..8410336 --- /dev/null +++ b/core/htmlfilter.h @@ -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 + + + + +// 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: ) 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:
+*/ +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 diff --git a/core/notify.cpp b/core/notify.cpp index e5a96e5..679df27 100755 --- a/core/notify.cpp +++ b/core/notify.cpp @@ -42,7 +42,7 @@ void * Notify::ThreadRoutine(void * arg) while( true ) { CheckQueue(); - sleep(30); + sleep(1); // !! was 30 } } @@ -61,7 +61,7 @@ std::list::iterator i = obj->notify_pool.begin(); i = obj->notify_pool.erase(i); obj->Unlock(); - sleep(3); + //sleep(3); // !! } } diff --git a/core/notify.h b/core/notify.h index 4cb529c..fbed0d3 100755 --- a/core/notify.h +++ b/core/notify.h @@ -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); diff --git a/core/request.cpp b/core/request.cpp index 975694d..51e952e 100755 --- a/core/request.cpp +++ b/core/request.cpp @@ -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); + 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); +} + + diff --git a/core/request.h b/core/request.h index 59f42d2..7098ab1 100755 --- a/core/request.h +++ b/core/request.h @@ -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; }; diff --git a/core/session.cpp b/core/session.cpp index 749b701..c06d617 100755 --- a/core/session.cpp +++ b/core/session.cpp @@ -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; } @@ -31,10 +34,12 @@ void Session::Clear() done = Done::none; done_status = Error::ok; item.Clear(); - done_timer = 0; - rebus_item = 0; + 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() { diff --git a/core/session.h b/core/session.h index 2157fcf..7ab62d3 100755 --- a/core/session.h +++ b/core/session.h @@ -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(); }; diff --git a/core/sessionmanager.cpp b/core/sessionmanager.cpp index ba9f6bc..9ee5bad 100755 --- a/core/sessionmanager.cpp +++ b/core/sessionmanager.cpp @@ -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 } diff --git a/core/sessionmanager.h b/core/sessionmanager.h index dd6f8cc..3097d94 100755 --- a/core/sessionmanager.h +++ b/core/sessionmanager.h @@ -28,7 +28,7 @@ class SessionManager long CreateSessionId(); void CreateTemporarySession(); void CreateSession(); - + bool SetSessionFromCookie(const std::string & cookie); int session_checker; public: diff --git a/main/Makefile.dep b/main/Makefile.dep index 442b6c4..b37814a 100755 --- a/main/Makefile.dep +++ b/main/Makefile.dep @@ -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 diff --git a/templates/Makefile.dep b/templates/Makefile.dep index e74f772..20da302 100755 --- a/templates/Makefile.dep +++ b/templates/Makefile.dep @@ -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 diff --git a/templates/doc.cpp b/templates/doc.cpp index 59b7fbd..02c6d66 100755 --- a/templates/doc.cpp +++ b/templates/doc.cpp @@ -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( request.status ); } diff --git a/templates/done.cpp b/templates/done.cpp index 24c5c5a..b1bb1f0 100755 --- a/templates/done.cpp +++ b/templates/done.cpp @@ -18,9 +18,9 @@ namespace TemplatesFunctions -void done_errors(Info & i) +void done_is_error(Info & i) { - i.result = request.session->done_status != Error::ok; + 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) { diff --git a/templates/rebus.cpp b/templates/rebus.cpp index a95b81e..a044904 100755 --- a/templates/rebus.cpp +++ b/templates/rebus.cpp @@ -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; } } diff --git a/templates/templates.cpp b/templates/templates.cpp index 72859d3..9712508 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -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,10 +207,9 @@ 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,19 +317,21 @@ void Templates::CreateFunctions() /* done */ - functions.Insert("done_errors", done_errors); - 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_added_item", done_added_item); - functions.Insert("done_edited_item", done_edited_item); - functions.Insert("done_deleted_item", done_deleted_item); - functions.Insert("done_privileged_item", done_privileged_item); - functions.Insert("done_loggedout", done_loggedout); - functions.Insert("done_added_dir", done_added_dir); - functions.Insert("done_deleted_dir", done_deleted_dir); - functions.Insert("done_defaulted_dir", done_defaulted_dir); - functions.Insert("done_reloaded_templates", done_reloaded_templates); + 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); + functions.Insert("done_privileged_item", done_privileged_item); + functions.Insert("done_loggedout", done_loggedout); + functions.Insert("done_added_dir", done_added_dir); + functions.Insert("done_deleted_dir", done_deleted_dir); + functions.Insert("done_defaulted_dir", done_defaulted_dir); + functions.Insert("done_reloaded_templates", done_reloaded_templates); /* diff --git a/templates/templates.h b/templates/templates.h index d66ac54..b00c80b 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -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); diff --git a/templatesnotify/templatesnotify.cpp b/templatesnotify/templatesnotify.cpp index e2004b0..14967c5 100755 --- a/templatesnotify/templatesnotify.cpp +++ b/templatesnotify/templatesnotify.cpp @@ -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");