diff options
| -rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 16 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.h | 10 | ||||
| -rw-r--r-- | project2/cgi/cgiCommon.cpp | 9 | ||||
| -rw-r--r-- | project2/cgi/cgiCommon.h | 3 | ||||
| -rw-r--r-- | project2/cgi/cgiEnvironment.cpp | 48 | ||||
| -rw-r--r-- | project2/cgi/cgiEnvironment.h | 22 | ||||
| -rw-r--r-- | project2/cgi/p2webCgi.cpp | 3 | ||||
| -rw-r--r-- | project2/cgi/p2webFCgi.cpp | 3 | ||||
| -rw-r--r-- | project2/cgi/testCgi.cpp | 3 | ||||
| -rw-r--r-- | project2/common/environment.cpp | 47 | ||||
| -rw-r--r-- | project2/common/environment.h | 8 | ||||
| -rw-r--r-- | project2/common/optionsSource.h | 1 | ||||
| -rw-r--r-- | project2/console/claOptions.cpp | 10 | ||||
| -rw-r--r-- | project2/files/optionsSource.cpp | 20 | ||||
| -rw-r--r-- | project2/files/optionsSource.h | 3 | 
15 files changed, 144 insertions, 62 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index c08eb3e..07aa737 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -15,22 +15,18 @@ typedef std::string SValue;  SimpleMessageException(UnknownDomain); -static UUID -getSessionID(const std::vector<cgicc::HTTPCookie> & cookies) { -	BOOST_FOREACH(const cgicc::HTTPCookie & c, cookies) { -		if (c.getName() == SESSIONID) { -			return c.getValue(); -		} -	} -	return UUID(); -}  CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e, std::ostream & io) :  	_env(e),  	sessionsContainer(LoaderBase::getLoader<SessionContainerLoader, NotSupported>(e->sessionModule)->open()),  	IO(io),  	outputCachingActive(false)  { -	cursession = sessionsContainer->GetSession(getSessionID(e->getCookieList())); +	try { +		cursession = sessionsContainer->GetSession(e->getCookieValue(SESSIONID)); +	} +	catch (const NoSuchCookie &) { +		cursession = sessionsContainer->GetSession(UUID()); +	}  	currentStage = NextStage(new InitialStage(e));  } diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index b362ece..154ca09 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -15,8 +15,9 @@  #include <boost/tuple/tuple.hpp>  #include "cgiOutputOptions.h"  #include "cgiHttpHeader.h" +#include "cgiEnvironment.h" +#include <cgicc/Cgicc.h> -class CgiEnvironment;  class Session;  namespace cgicc {  	class HTTPHeader; @@ -43,10 +44,9 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  		SessionContainerPtr sessionsContainer;  		// Helpers  		void addVarToPresenter(const MultiRowSetPresenter * p, const Glib::ustring & name, const VariableType &) const; -		typedef std::string (cgicc::CgiEnvironment::*StrEnvGetter)() const; -		template <class X> -		void addEnvToPresenter(const MultiRowSetPresenter * p, const char * name, X (cgicc::CgiEnvironment::*getter)() const) const { -			addVarToPresenter(p, name, (_env->*getter)()); +		template <class X, class Y> +		void addEnvToPresenter(const MultiRowSetPresenter * p, const char * name, X (Y::*getter)() const) const { +			addVarToPresenter(p, name, (_env->cgi->getEnvironment().*getter)());  		}  	public: diff --git a/project2/cgi/cgiCommon.cpp b/project2/cgi/cgiCommon.cpp index 7559ea7..ac3e6d4 100644 --- a/project2/cgi/cgiCommon.cpp +++ b/project2/cgi/cgiCommon.cpp @@ -5,7 +5,6 @@  #include <cgicc/CgiEnvironment.h>  #include <cgicc/HTTPContentHeader.h>  #include <cgicc/HTTPStatusHeader.h> -#include "cgiEnvironment.h"  #include "cgiAppEngine.h"  #include <boost/bind.hpp>  #include <cxxabi.h> @@ -38,13 +37,13 @@ doExceptionReporting(const E & e, std::ostream & IO)  }  void -cgiServe(cgicc::CgiInput * i, std::ostream & IO) +cgiServe(cgicc::CgiInput * i, CgiEnvironment * env, std::ostream & IO)  {  	cgicc::Cgicc cgi(i); -	CgiEnvironment env(&cgi); -	env.init(); +	env->setCGICC(&cgi); +	env->init();  	try { -		CgiApplicationEngine app(&env, IO); +		CgiApplicationEngine app(env, IO);  		LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1));  		Logger()->messagef(LOG_DEBUG, "%s: Processing request", __FUNCTION__); diff --git a/project2/cgi/cgiCommon.h b/project2/cgi/cgiCommon.h index 489e3fb..ce6108e 100644 --- a/project2/cgi/cgiCommon.h +++ b/project2/cgi/cgiCommon.h @@ -1,5 +1,6 @@  #include <ostream>  #include <cgicc/Cgicc.h> +#include "cgiEnvironment.h" -void cgiServe(cgicc::CgiInput * i, std::ostream & o); +void cgiServe(cgicc::CgiInput * i, CgiEnvironment *, std::ostream & o); diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp index 001d4bd..2e977b2 100644 --- a/project2/cgi/cgiEnvironment.cpp +++ b/project2/cgi/cgiEnvironment.cpp @@ -23,10 +23,7 @@ makeVector(const boost::filesystem::path & y)  	return r;  } -CgiEnvironment::CgiEnvironment(cgicc::Cgicc * c) : -	cgicc::CgiEnvironment(c->getEnvironment()), -	elems(makeVector(boost::filesystem::path(getRedirectURL()))), -	cgi(c), +CgiEnvironment::CgiEnvironment() :  	cgiOptions("Project2 CGI options"),  	hpi(new HostnamePlatformIdentifier())  { @@ -69,6 +66,48 @@ CgiEnvironment::~CgiEnvironment()  {  } +void +CgiEnvironment::setCGICC(const cgicc::Cgicc * c) +{ +	cgi = c; +	elems = makeVector(boost::filesystem::path(getRedirectURL())); +} + +std::string +CgiEnvironment::getCookieValue(const std::string & name) const +{ +	BOOST_FOREACH(const cgicc::HTTPCookie & c, cgi->getEnvironment().getCookieList()) { +		if (c.getName() == name) { +			return c.getValue(); +		} +	} +	throw NoSuchCookie(name); +} + +std::string +CgiEnvironment::getRequestMethod() const +{ +	return cgi->getEnvironment().getRequestMethod(); +} + +std::string +CgiEnvironment::getRedirectURL() const +{ +	return cgi->getEnvironment().getRedirectURL(); +} + +std::string +CgiEnvironment::getScriptName() const +{ +	return cgi->getEnvironment().getScriptName(); +} + +std::string +CgiEnvironment::getServerName() const +{ +	return cgi->getEnvironment().getServerName(); +} +  const Glib::ustring &  CgiEnvironment::platform() const  { @@ -125,6 +164,7 @@ HostnamePlatformIdentifier::reset() const  {  	if (platform) {  		delete platform; +		platform = NULL;  	}  } diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h index 78f8730..27b1694 100644 --- a/project2/cgi/cgiEnvironment.h +++ b/project2/cgi/cgiEnvironment.h @@ -6,6 +6,8 @@  #include "environment.h"  #include <cgicc/CgiEnvironment.h> +SimpleMessageException(NoSuchCookie); +  namespace cgicc {  	class Cgicc;  } @@ -22,19 +24,23 @@ class HostnamePlatformIdentifier : public Options::Target {  		mutable Glib::ustring * platform;  }; -class CgiEnvironment : public Environment, public cgicc::CgiEnvironment { +class CgiEnvironment : public Environment {  	public: -		CgiEnvironment(cgicc::Cgicc *); +		CgiEnvironment();  		virtual ~CgiEnvironment();  		Glib::ustring getParamUri(unsigned int idx) const;  		unsigned int getParamUriCount() const;  		Glib::ustring getParamQuery(const std::string & idx) const; -		std::string getServerName() const { return cgicc::CgiEnvironment::getServerName(); } -		std::string getScriptName() const { return cgicc::CgiEnvironment::getScriptName(); } +		std::string getServerName() const; +		std::string getScriptName() const; +		std::string getRedirectURL() const; +		std::string getRequestMethod() const; +		std::string getCookieValue(const std::string & name) const; +		void setCGICC(const cgicc::Cgicc *); +		const cgicc::Cgicc * cgi;  		std::vector<std::string> elems; -		const cgicc::Cgicc * const cgi;  	private:  		const Options & engineOptions() const; @@ -52,9 +58,9 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment {  		std::string errorPresentRoot;  		std::string notFoundPresent;  		std::string onErrorPresent; -		std::string	defaultPresenter; -		std::string	sessionModule; -		std::string	outputEncoding; +		std::string defaultPresenter; +		std::string sessionModule; +		std::string outputEncoding;  };  #endif diff --git a/project2/cgi/p2webCgi.cpp b/project2/cgi/p2webCgi.cpp index 0248df6..646d08b 100644 --- a/project2/cgi/p2webCgi.cpp +++ b/project2/cgi/p2webCgi.cpp @@ -6,7 +6,8 @@ int  main(void)  {  	LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); -	cgiServe(NULL, std::cout); +	CgiEnvironment env; +	cgiServe(NULL, &env, std::cout);  	LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1));  	LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1));  	LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp index 3b833ed..a1786d2 100644 --- a/project2/cgi/p2webFCgi.cpp +++ b/project2/cgi/p2webFCgi.cpp @@ -40,11 +40,12 @@ main(void)  			fprintf(stderr, "Failed to set signal handler\n");  		}  		alarm(60); +		CgiEnvironment env;  		LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1));  		while (FCGX_Accept_r(&request) == 0) {  			alarm(0);  			cgicc::FCgiIO IO(request); -			cgiServe(&IO, IO); +			cgiServe(&IO, &env, IO);  			alarm(60);  			LoaderBase::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1));  			if (time(NULL) > lastPeriodic + periodicDelay) { diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index 6250cb0..1d3f72c 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -75,11 +75,12 @@ class TestInput : public cgicc::CgiInput {  		void run()  		{  			for (int run = 0; run < runCount; run += 1) { -				cgiServe(this, std::cout); +				cgiServe(this, &env, std::cout);  			}  		}  	private: +		CgiEnvironment env;  		Options opts;  		int runCount;  }; diff --git a/project2/common/environment.cpp b/project2/common/environment.cpp index 2047813..c0f84a2 100644 --- a/project2/common/environment.cpp +++ b/project2/common/environment.cpp @@ -10,11 +10,11 @@  #include <boost/bind.hpp>  const Environment * Environment::currentEnv(NULL); -int Environment::clLevel(-1); -int Environment::slLevel(-1);  Environment::Environment() : -	commonOptions("Project2 Common options") +	commonOptions("Project2 Common options"), +	clLevel(-1), +	slLevel(-1)  {  	currentEnv = this;  	commonOptions @@ -31,6 +31,10 @@ Environment::Environment() :  		("common.sessionTimeOut", Options::value(&sessionTimeOut, 3600),  		 "The time after which idle sessions are forgotten")  		; +	typedef std::map<std::string, boost::shared_ptr<OptionsSourceLoader> > ConfigParsersMap; +	BOOST_FOREACH(const ConfigParsersMap::value_type & cp, *LoaderBase::objLoaders<OptionsSourceLoader>()) { +		configs.push_back(cp.second->create()); +	}  }  typedef std::vector<const Options *> AllOptions; @@ -66,26 +70,27 @@ class DefaultConfigConsumer : public ConfigConsumer {  void  Environment::init()  { -	DefaultConfigConsumer dcc; -	dcc.allOptions.push_back(&commonOptions); -	dcc.allOptions.push_back(&engineOptions()); -	LoaderBase::onAllComponents(boost::bind(optionsHelper, &dcc.allOptions, boost::bind(&ComponentLoader::options, _1))); +	if (std::find_if(configs.begin(), configs.end(), boost::bind(&OptionsSource::needReload, _1)) != configs.end()) { +		DefaultConfigConsumer dcc; +		dcc.allOptions.push_back(&commonOptions); +		dcc.allOptions.push_back(&engineOptions()); +		LoaderBase::onAllComponents(boost::bind(optionsHelper, &dcc.allOptions, boost::bind(&ComponentLoader::options, _1))); -	BOOST_FOREACH(const AllOptions::value_type & v, dcc.allOptions) { -		v->reset(); -	} - -	typedef std::map<std::string, boost::shared_ptr<OptionsSourceLoader> > ConfigParsersMap; -	BOOST_FOREACH(const ConfigParsersMap::value_type & cp, *LoaderBase::objLoaders<OptionsSourceLoader>()) { -		cp.second->create()->loadInto(dcc); -	} +		BOOST_FOREACH(const AllOptions::value_type & v, dcc.allOptions) { +			v->reset(); +		} -	Logger()->clear(); -	if (clLevel >= 0) { -		Logger()->addLogger(new ConsoleLogDriver(stderr, clLevel, false)); -	} -	if (slLevel >= 0) { -		Logger()->addLogger(new SyslogLogDriver(getScriptName().c_str(), slLevel)); +		BOOST_FOREACH(const ConfigsMap::value_type & c, configs) { +			c->loadInto(dcc); +		} +		Logger()->clear(); +		if (clLevel >= 0) { +			Logger()->addLogger(new ConsoleLogDriver(stderr, clLevel, false)); +		} +		if (slLevel >= 0) { +			Logger()->addLogger(new SyslogLogDriver(getScriptName().c_str(), slLevel)); +		} +		Logger()->message(LOG_DEBUG, "Loaded configuration");  	}  } diff --git a/project2/common/environment.h b/project2/common/environment.h index 0c33283..894b2f8 100644 --- a/project2/common/environment.h +++ b/project2/common/environment.h @@ -5,7 +5,7 @@  #include <glibmm/ustring.h>  #include <boost/function.hpp>  #include <boost/filesystem/path.hpp> -#include "options.h" +#include "optionsSource.h"  #include "exceptions.h"  #include "scripts.h" @@ -36,8 +36,10 @@ class Environment {  		static const Environment * currentEnv; -		static int clLevel; -		static int slLevel; +		int clLevel; +		int slLevel; +		typedef std::vector<OptionsSourcePtr> ConfigsMap; +		ConfigsMap configs;  	public:  		std::string datasourceRoot; diff --git a/project2/common/optionsSource.h b/project2/common/optionsSource.h index c73a500..f238a66 100644 --- a/project2/common/optionsSource.h +++ b/project2/common/optionsSource.h @@ -17,6 +17,7 @@ class ConfigConsumer {  class OptionsSource : public IntrusivePtrBase {  	public:  		virtual void loadInto(const ConfigConsumer &) const = 0; +		virtual bool needReload() const = 0;  };  typedef boost::intrusive_ptr<OptionsSource> OptionsSourcePtr; diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp index b931392..4660134 100644 --- a/project2/console/claOptions.cpp +++ b/project2/console/claOptions.cpp @@ -11,6 +11,9 @@ SimpleMessageException(UnknownOption);  class CommandLineArguments : public OptionsSource {  	public: +		CommandLineArguments() : +			loadedAt(0) { +		}  		void loadInto(const ConfigConsumer & consume) const {  			int argc = ConsoleEnvironment::argc;  			char ** argv = ConsoleEnvironment::argv; @@ -74,7 +77,14 @@ class CommandLineArguments : public OptionsSource {  					}  				}  			} +			time(&loadedAt); +		} +		bool needReload() const +		{ +			return !loadedAt;  		} +	private: +		mutable time_t loadedAt;  };  // A... process first :) diff --git a/project2/files/optionsSource.cpp b/project2/files/optionsSource.cpp index 84c06dc..50e924d 100644 --- a/project2/files/optionsSource.cpp +++ b/project2/files/optionsSource.cpp @@ -5,12 +5,14 @@  #include <boost/algorithm/string/trim.hpp>  FileOptions::FileOptions() : -	file(".p2config") +	file(".p2config"), +	loadedAt(0)  {  }  FileOptions::FileOptions(const Glib::ustring & f) : -	file(f) +	file(f), +	loadedAt(0)  {  } @@ -53,11 +55,25 @@ FileOptions::loadInto(const ConfigConsumer & consume) const {  					break;  			}  		} +		struct stat st; +		if (stat(file.c_str(), &st) == 0) { +			loadedAt = st.st_mtime; +		}  	}  	catch (const Glib::FileError &) {  	}  } +bool +FileOptions::needReload() const +{ +	struct stat st; +	if (stat(file.c_str(), &st) != 0) { +		return true; +	} +	return (loadedAt != st.st_mtime); +} +  // Z... process last :)  DECLARE_COMPONENT_LOADER("Z_configfile", FileOptions, OptionsSourceLoader) diff --git a/project2/files/optionsSource.h b/project2/files/optionsSource.h index 722d7b9..5cd5250 100644 --- a/project2/files/optionsSource.h +++ b/project2/files/optionsSource.h @@ -9,8 +9,11 @@ class FileOptions : public OptionsSource {  		FileOptions(const Glib::ustring & file);  		void loadInto(const ConfigConsumer & consume) const; +		bool needReload() const; +  	private:  		const Glib::ustring file; +		mutable time_t loadedAt;  };  #endif  | 
