diff options
| -rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 43 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.h | 2 | ||||
| -rw-r--r-- | project2/cgi/cgiStageFail.cpp | 52 | ||||
| -rw-r--r-- | project2/common/commonObjects.cpp | 13 | ||||
| -rw-r--r-- | project2/common/config.cpp | 13 | ||||
| -rw-r--r-- | project2/common/iHaveParameters.cpp | 7 | ||||
| -rw-r--r-- | project2/common/session.cpp | 3 | ||||
| -rw-r--r-- | project2/common/session.h | 7 | ||||
| -rw-r--r-- | project2/common/sessionContainer.cpp | 2 | ||||
| -rw-r--r-- | project2/common/sessionContainer.h | 5 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.cpp | 17 | ||||
| -rw-r--r-- | project2/url/curlHelper.cpp | 74 | ||||
| -rw-r--r-- | project2/url/curlHelper.h | 36 | ||||
| -rw-r--r-- | project2/url/urlRows.cpp | 29 | ||||
| -rw-r--r-- | project2/url/urlRows.h | 11 | ||||
| -rw-r--r-- | project2/xml/sessionXml.cpp | 110 | ||||
| -rw-r--r-- | project2/xml/sessionXml.h | 5 | ||||
| -rw-r--r-- | project2/xml/xslPreFetch.cpp | 4 | ||||
| -rw-r--r-- | project2/xml/xslPreFetch.h | 4 | ||||
| -rw-r--r-- | project2/xml/xslRows.cpp | 4 | ||||
| -rw-r--r-- | project2/xml/xslRows.h | 4 | ||||
| -rw-r--r-- | project2/xml/xslRowsCache.cpp | 31 | ||||
| -rw-r--r-- | project2/xml/xslRowsCache.h | 5 | 
23 files changed, 284 insertions, 197 deletions
| diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 2c4feb0..877f9a6 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -17,17 +17,23 @@ 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) :  	ApplicationEngine("web/host"),  	_env(e),  	sessionsContainer(LoaderBase::getLoader<SessionContainerLoader, NotSupported>(e->sessionModule)->open()),  	IO(io)  { -	BOOST_FOREACH(const cgicc::HTTPCookie c, e->getCookieList()) { -		if (c.getName() == SESSIONID) { -			sessionID = c.getValue(); -		} -	} +	UUID sessID = getSessionID(e->getCookieList()); +	cursession = sessionsContainer->GetSession(sessID);  	currentStage = NextStage(new InitialStage(e));  } @@ -80,10 +86,8 @@ CgiApplicationEngine::process() const  		addEnvData(currentStage.get<3>().get());  	}  	HttpHeaderPtr header = rs->getHeader(); -	if (!sessionID.is_nil()) { -		header->setCookie(cgicc::HTTPCookie(SESSIONID, sessionID.str(), "Session ID", -					_env->getServerName().substr(_env->getServerName().find(".")), env()->sessionTimeOut, "/", false)); -	} +	header->setCookie(cgicc::HTTPCookie(SESSIONID, cursession->ID.str(), "Session ID", +				_env->getServerName().substr(_env->getServerName().find(".")), env()->sessionTimeOut, "/", false));  	header->render(IO);  	if (currentStage.get<2>()) {  		TransformSourcePtr ts = currentStage.get<2>(); @@ -98,6 +102,7 @@ CgiApplicationEngine::process() const  			delete ddd;  		}  	} +	sessionsContainer->SaveSession(cursession);  }  CgiApplicationEngine::Stage::Stage(const CgiEnvironment * env) : @@ -139,18 +144,16 @@ CgiApplicationEngine::addAppData(const Presenter * p) const  {  	addCoreAppData(p);  	// Sessions variables -	if (!sessionID.is_nil()) { -		p->pushSub("session", env()->xmlPrefix); -		p->addField("id", sessionID.str()); -		Session::Values session(sessionsContainer->GetSession(sessionID)->GetValuesCopy()); -		BOOST_FOREACH(Session::Values::value_type sv, session) { -			p->pushSub("var", env()->xmlPrefix); -			p->addAttr("value", sv.second); -			p->addAttr("name", sv.first); -			p->popSub(); -		} +	p->pushSub("session", env()->xmlPrefix); +	p->addField("id", cursession->ID.str()); +	Session::Values session(cursession->GetValuesCopy()); +	BOOST_FOREACH(Session::Values::value_type sv, session) { +		p->pushSub("var", env()->xmlPrefix); +		p->addAttr("value", sv.second); +		p->addAttr("name", sv.first);  		p->popSub();  	} +	p->popSub();  	// Timing info  	p->pushSub("timing", env()->xmlPrefix); @@ -165,7 +168,7 @@ CgiApplicationEngine::addAppData(const Presenter * p) const  SessionPtr  CgiApplicationEngine::session() const  { -	return sessionsContainer->GetSession(sessionID); +	return cursession;  }  bool diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 0f534e8..6e202e4 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -143,7 +143,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink  	private:  		mutable NextStage currentStage; -		mutable UUID sessionID; +		SessionPtr cursession;  		mutable std::ostream & IO;  }; diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp new file mode 100644 index 0000000..04e131b --- /dev/null +++ b/project2/cgi/cgiStageFail.cpp @@ -0,0 +1,52 @@ +#include <pch.hpp> +#include "cgiAppEngine.h" +#include "cgiEnvironment.h" +#include "cgiHttpHeader.h" +#include "logger.h" + +namespace CgiApplicationExtras { +	class FailStage : public CgiApplicationEngine::ResponseStage { +		public: +			FailStage(const CgiEnvironment * env, int c, const std::string & m) : +				ResponseStage(env), +				code(c), +				message(m) { +			} + +			CgiApplicationEngine::HttpHeaderPtr getHeader() const +			{ +				Project2HttpHeader * header = new Project2HttpHeader(boost::lexical_cast<std::string>(code) + " " + message); +				return CgiApplicationEngine::HttpHeaderPtr(header); +			} + +			CgiApplicationEngine::NextStage run() +			{ +				return CgiApplicationEngine::NextStage(NULL, this, NULL, NULL); +			} +		private: +			const int code; +			const std::string message; +	}; + +	class CgiFail : public View { +		public: +			CgiFail(const xmlpp::Element * e) : +				SourceObject(e), +				View(e), +				code(e, "code", false, 500), +				message(e, "message", false, "Application error") { +				} +			void loadComplete(const CommonObjects *) { +			} +			void execute(const Presenter *) const { +				throw CgiApplicationEngine::ResponseStagePtr( +						new FailStage(dynamic_cast<const CgiEnvironment *>(Environment::getCurrent()), code(), message())); +			} +		private: +			Variable code, message; +	}; +} + +typedef CgiApplicationExtras::CgiFail cgif; +DECLARE_LOADER("cgifail", cgif); + diff --git a/project2/common/commonObjects.cpp b/project2/common/commonObjects.cpp index f398e07..2ffa353 100644 --- a/project2/common/commonObjects.cpp +++ b/project2/common/commonObjects.cpp @@ -1,5 +1,6 @@  #include <pch.hpp>  #include "commonObjects.h" +#include "safeMapFind.h"  #include "appEngine.h"  #include "xmlObjectLoader.h"  #include "xmlScriptParser.h" @@ -11,11 +12,7 @@ CommonObjects::~CommonObjects()  RowSetPtr  CommonObjects::getSource(const std::string & name) const  { -	RowSets::const_iterator i = rowSets.find(name); -	if (i != rowSets.end()) { -		return i->second; -	} -	throw CommonObjects::DataSourceNotFound(name); +	return safeMapFind<DataSourceNotFound>(rowSets, name)->second;  }  CommonObjects::DataSources::const_iterator @@ -28,10 +25,6 @@ CommonObjects::loadDataSource(const std::string & name) const  	loader.supportedStorers.insert(Storer::into(&datasources));  	loader.collectAll(xml.get_document()->get_root_node(), false); -	DataSources::const_iterator i = datasources.find(name); -	if (i == datasources.end()) { -		throw DataSourceNotFound(name); -	} -	return i; +	return safeMapFind<DataSourceNotFound>(datasources, name);  } diff --git a/project2/common/config.cpp b/project2/common/config.cpp index adeacf2..6f5b243 100644 --- a/project2/common/config.cpp +++ b/project2/common/config.cpp @@ -1,5 +1,6 @@  #include <pch.hpp>  #include "config.h" +#include "safeMapFind.h"  #include "exceptions.h"  #include <boost/filesystem/operations.hpp>  #include <boost/foreach.hpp> @@ -50,21 +51,13 @@ Configuration::getCurrentConfig() const  {  	load();  	Glib::ustring platformName(resolveCurrentConfig()); -	Platforms::const_iterator i = platforms.find(platformName); -	if (i == platforms.end()) { -		throw NoSuchPlatform(platformName); -	} -	return i->second; +	return safeMapFind<NoSuchPlatform>(platforms, platformName)->second;  }  const Glib::ustring &  Configuration::Platform::getValue(const Glib::ustring & key) const  { -	Values::const_iterator i = values.find(key); -	if (i == values.end()) { -		throw NoSuchConfigurationValue(key); -	} -	return i->second; +	return safeMapFind<NoSuchConfigurationValue>(values, key)->second;  }  Configuration::Platform::Platform(const xmlpp::Element * e) diff --git a/project2/common/iHaveParameters.cpp b/project2/common/iHaveParameters.cpp index d3f9776..7d750b3 100644 --- a/project2/common/iHaveParameters.cpp +++ b/project2/common/iHaveParameters.cpp @@ -1,6 +1,7 @@  #include <pch.hpp>  #include "iHaveParameters.h"  #include "exceptions.h" +#include "safeMapFind.h"  #include "appEngine.h"  #include <boost/foreach.hpp> @@ -22,11 +23,7 @@ IHaveParameters::~IHaveParameters()  VariableType  IHaveParameters::getParameter(const Glib::ustring & name) const  { -	Parameters::const_iterator i = parameters.find(name); -	if (i != parameters.end()) { -		return i->second; -	} -	throw ParamNotFound(name); +	return safeMapFind<ParamNotFound>(parameters, name)->second;  }  void diff --git a/project2/common/session.cpp b/project2/common/session.cpp index 548fa4f..d796f83 100644 --- a/project2/common/session.cpp +++ b/project2/common/session.cpp @@ -1,7 +1,8 @@  #include <pch.hpp>  #include "session.h" -Session::Session() +Session::Session(const UUID & sid) : +	ID(sid)  {  } diff --git a/project2/common/session.h b/project2/common/session.h index 7b66db9..ea72c54 100644 --- a/project2/common/session.h +++ b/project2/common/session.h @@ -1,6 +1,7 @@  #ifndef SESSION_H  #define SESSION_H +#include <uuid.h>  #include <map>  #include <glibmm/ustring.h>  #include <boost/intrusive_ptr.hpp> @@ -14,15 +15,17 @@ class Session : public virtual IntrusivePtrBase {  		SimpleMessageException(VariableNotFound);  		typedef std::map<Glib::ustring, VariableType> Values; -		Session(); +		Session(const UUID & id);  		virtual ~Session() = 0; -		virtual const VariableType & GetValue(const Glib::ustring & name) const = 0; +		virtual VariableType GetValue(const Glib::ustring & name) const = 0;  		virtual Values GetValuesCopy() const = 0;  		virtual void SetValue(const Glib::ustring & name, const VariableType & value) = 0;  		virtual void ClearValue(const Glib::ustring & name) = 0;  		virtual time_t ExpiryTime() const = 0; +		const UUID ID; +  	protected:  		virtual void ExpiryTime(time_t) = 0;  		friend class SessionContainer; diff --git a/project2/common/sessionContainer.cpp b/project2/common/sessionContainer.cpp index 15e8d47..87c5729 100644 --- a/project2/common/sessionContainer.cpp +++ b/project2/common/sessionContainer.cpp @@ -11,7 +11,7 @@ SessionContainer::~SessionContainer()  }  SessionPtr -SessionContainer::GetSession(UUID & id) +SessionContainer::GetSession(UUID & id) const  {  	SessionPtr s = getSession(id);  	s->ExpiryTime(time(NULL) + Environment::getCurrent()->sessionTimeOut); diff --git a/project2/common/sessionContainer.h b/project2/common/sessionContainer.h index fcad4b9..9f1851a 100644 --- a/project2/common/sessionContainer.h +++ b/project2/common/sessionContainer.h @@ -10,10 +10,11 @@ class SessionContainer : public IntrusivePtrBase {  		SessionContainer();  		virtual ~SessionContainer() = 0; -		SessionPtr GetSession(UUID & sid); +		SessionPtr GetSession(UUID & sid) const; +		virtual void SaveSession(SessionPtr sess) const = 0;  	protected: -		virtual SessionPtr getSession(UUID & sid) = 0; +		virtual SessionPtr getSession(UUID & sid) const = 0;  };  typedef boost::intrusive_ptr<SessionContainer> SessionContainerPtr; diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index c5b9e3f..f2dcaa8 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -1,6 +1,7 @@  #include <pch.hpp>  #include "consoleAppEngine.h"  #include "consoleEnvironment.h" +#include "safeMapFind.h"  #include "iterate.h"  #include "xmlObjectLoader.h"  #include <boost/foreach.hpp> @@ -12,20 +13,16 @@ SimpleMessageException(UnknownPlatformAlias);  /// Session implementation that stores its contents locally in memory, it has no long term persistence  class ConsoleSession : public Session {  	public: -		ConsoleSession() : expiry(0) +		ConsoleSession() : Session(UUID::generate_random()), expiry(0)  		{  		}  		virtual ~ConsoleSession()  		{  		} -		virtual const VariableType & GetValue(const Glib::ustring & name) const +		virtual VariableType GetValue(const Glib::ustring & name) const  		{ -			Values::const_iterator i = vars.find(name); -			if (i == vars.end()) { -				throw Session::VariableNotFound(name); -			} -			return i->second; +			return safeMapFind<VariableNotFound>(vars, name)->second;  		}  		virtual Values GetValuesCopy() const  		{ @@ -110,11 +107,7 @@ ConsoleApplicationEngine::addAppData(const Presenter *) const  Glib::ustring  ConsoleApplicationEngine::resolveCurrentConfig() const  { -	ConsolePlatforms::const_iterator i = conplat.find(_env->getPlatform()); -	if (i != conplat.end()) { -		return i->second; -	} -	throw UnknownPlatformAlias(_env->getPlatform()); +	return safeMapFind<UnknownPlatformAlias>(conplat, _env->getPlatform())->second;  }  void diff --git a/project2/url/curlHelper.cpp b/project2/url/curlHelper.cpp index bec779e..1b98d3b 100644 --- a/project2/url/curlHelper.cpp +++ b/project2/url/curlHelper.cpp @@ -1,6 +1,6 @@  #include "curlHelper.h" -CurlHelper::CurlHelper(const xmlpp::Element * p) : +VariableCurlHelper::VariableCurlHelper(const xmlpp::Element * p) :  	url(p, "url"),  	userAgent(p, "useragent", false, "project2/0.3"),  	cookieJar(p, "cookiejar", false), @@ -13,17 +13,45 @@ CurlHelper::CurlHelper(const xmlpp::Element * p) :  {  } +VariableCurlHelper::~VariableCurlHelper() +{ +} + +CurlHelper::CurlHelper() +{ +} +  CurlHelper::~CurlHelper()  {  } -CurlHandle::Ptr +size_t +Curl::curlReadHelperHandle(const char * ptr, size_t size, size_t nmemb, void *stream) +{ +	return (*static_cast<const Curl::ReadHandler *>(stream))(ptr, size * nmemb); +} + +size_t +Curl::curlSendHelperHandle(char * ptr, size_t size, size_t nmemb, void *stream) +{ +	return (*static_cast<const Curl::SendHandler *>(stream))(ptr, size * nmemb); +} + +CurlPtr  CurlHelper::newCurl() const  { -	CurlHandle::Ptr c = new CurlHandle(); +	CurlPtr c = new Curl();  	c->setopt(CURLOPT_FOLLOWLOCATION, 1);  	c->setopt(CURLOPT_ENCODING, "deflate, gzip"); -	setopt_s(c, CURLOPT_URL, url()); +	c->setopt(CURLOPT_URL, getUrl().c_str()); +	c->setopt(CURLOPT_FAILONERROR, 1); +	return c; +} + +CurlPtr +VariableCurlHelper::newCurl() const +{ +	CurlPtr c = CurlHelper::newCurl();  	setopt_s(c, CURLOPT_USERAGENT, userAgent());  	setopt_s(c, CURLOPT_PROXY, proxy());  	setopt_s(c, CURLOPT_REFERER, referer()); @@ -34,14 +62,48 @@ CurlHelper::newCurl() const  }  void -CurlHelper::setopt_s(CurlHandle::Ptr c, CURLoption o, const char * v) +Curl::performRead(const ReadHandler & h) +{ +	setReadHandler(h); +	CurlHandle::perform(); +} + +void +Curl::setReadHandler(const ReadHandler & h) +{ +	setopt(CURLOPT_WRITEDATA, &h); +	setopt(CURLOPT_WRITEFUNCTION, &curlReadHelperHandle); +} + +void +Curl::performSend(const SendHandler & h) +{ +	setSendHandler(h); +	CurlHandle::perform(); +} + +void +Curl::setSendHandler(const SendHandler & h) +{ +	setopt(CURLOPT_READDATA, &h); +	setopt(CURLOPT_READFUNCTION, &curlSendHelperHandle); +} + +void +VariableCurlHelper::setopt_s(CurlPtr c, CURLoption o, const char * v)  {  	c->setopt(o, v);  }  void -CurlHelper::setopt_l(CurlHandle::Ptr c, CURLoption o, int64_t v) +VariableCurlHelper::setopt_l(CurlPtr c, CURLoption o, int64_t v)  {  	c->setopt(o, (long)v);  } +std::string +VariableCurlHelper::getUrl() const +{ +	return url(); +} + diff --git a/project2/url/curlHelper.h b/project2/url/curlHelper.h index 111823f..28395e5 100644 --- a/project2/url/curlHelper.h +++ b/project2/url/curlHelper.h @@ -5,20 +5,48 @@  #include "variables.h"  #include "../libmisc/curlsup.h" +class Curl : public CurlHandle { +	public: +		typedef boost::function2<size_t, const char *, size_t> ReadHandler; +		typedef boost::function2<size_t, char *, size_t> SendHandler; +		void performRead(const ReadHandler &); +		void setReadHandler(const ReadHandler &); +		void performSend(const SendHandler &); +		void setSendHandler(const SendHandler &); + +	private: +		static size_t curlReadHelperHandle(const char * ptr, size_t size, size_t nmemb, void *stream); +		static size_t curlSendHelperHandle(char * ptr, size_t size, size_t nmemb, void *stream); +}; +typedef boost::intrusive_ptr<Curl> CurlPtr; +  /// Project2 helper component to provide common access to remote resources via libcurl  class CurlHelper {  	public: -		CurlHelper(const xmlpp::Element * p); +		CurlHelper();  		~CurlHelper(); +		virtual CurlPtr newCurl() const; + +	protected: +		virtual std::string getUrl() const = 0; +}; + +/// Project2 helper component to configure CurlHelper from variables +class VariableCurlHelper : public CurlHelper { +	public: +		VariableCurlHelper(const xmlpp::Element * p); +		~VariableCurlHelper(); +  		const Variable url;  	protected: -		CurlHandle::Ptr newCurl() const; +		virtual CurlPtr newCurl() const; +		virtual std::string getUrl() const;  	private: -		static void setopt_s(CurlHandle::Ptr, CURLoption, const char *); -		static void setopt_l(CurlHandle::Ptr, CURLoption, int64_t); +		static void setopt_s(CurlPtr, CURLoption, const char *); +		static void setopt_l(CurlPtr, CURLoption, int64_t);  		const Variable userAgent;  		const Variable cookieJar; diff --git a/project2/url/urlRows.cpp b/project2/url/urlRows.cpp index f8f7eed..cfacea4 100644 --- a/project2/url/urlRows.cpp +++ b/project2/url/urlRows.cpp @@ -10,7 +10,7 @@ DECLARE_LOADER("urlrows", UrlRows);  UrlRows::UrlRows(const xmlpp::Element * p) :  	StreamRows(p), -	CurlHelper(p), +	VariableCurlHelper(p),  	convertRequired(encoding != "utf-8")  {  } @@ -25,20 +25,12 @@ UrlRows::loadComplete(const CommonObjects *)  }  size_t -UrlRows::handleDataHelper(const char * ptr, size_t size, size_t nmemb, void *stream) -{ -	const callback * cb = static_cast<const callback *>(stream); -	size_t used = cb->urlRows->handleData(cb->ps, ptr, size * nmemb); -	return used; -} - -size_t -UrlRows::handleData(ParseState & ps, const char * bytes, size_t bytesLen) const +UrlRows::handleData(ParseState * ps, const char * bytes, size_t bytesLen) const  {  	size_t used = 0, len = 0;  	const gchar * utf8 = convertRequired ? g_convert(bytes, bytesLen, "utf-8", encoding.c_str(), &used, &len, NULL) : bytes;  	for (const gchar * iter = utf8; *iter; iter = g_utf8_next_char(iter)) { -		this->pushChar(*iter, ps); +		this->pushChar(*iter, *ps);  	}  	if (convertRequired) {  		// We allocated it.. sooo.... @@ -53,17 +45,8 @@ UrlRows::handleData(ParseState & ps, const char * bytes, size_t bytesLen) const  void  UrlRows::execute(const Glib::ustring &, const RowProcessor * rp) const  { -	CurlHandle::Ptr c = newCurl(); -	callback cb(this, rp); -	c->setopt(CURLOPT_WRITEDATA, &cb); -	c->setopt(CURLOPT_WRITEFUNCTION, &handleDataHelper); -	c->perform(); -} - -UrlRows::callback::callback(const UrlRows * u, const RowProcessor * r) : -	urlRows(u), -	rp(r), -	ps(u, r) -{ +	ParseState ps(this, rp); +	CurlPtr c = newCurl(); +	c->performRead(boost::bind(&UrlRows::handleData, this, &ps, _1, _2));  } diff --git a/project2/url/urlRows.h b/project2/url/urlRows.h index 98273bd..cd209c8 100644 --- a/project2/url/urlRows.h +++ b/project2/url/urlRows.h @@ -9,7 +9,7 @@  #include "curlHelper.h"  /// Project2 component to create a row set from the contents of a file accessible via libcurl -class UrlRows : public StreamRows, CurlHelper { +class UrlRows : public StreamRows, VariableCurlHelper {  	public:  		UrlRows(const xmlpp::Element * p);  		~UrlRows(); @@ -18,15 +18,8 @@ class UrlRows : public StreamRows, CurlHelper {  		void execute(const Glib::ustring &, const RowProcessor *) const;  	private: -		struct callback { -			callback(const UrlRows * urlRows, const RowProcessor * rp); -			const UrlRows * urlRows; -			const RowProcessor * rp; -			mutable ParseState ps; -		}; -		static size_t handleDataHelper(const char * ptr, size_t size, size_t nmemb, void * stream); -		size_t handleData(ParseState &, const char * bytes, size_t bytesLen) const;  		bool convertRequired; +		size_t handleData(ParseState * ps, const char * bytes, size_t bytesLen) const;  }; diff --git a/project2/xml/sessionXml.cpp b/project2/xml/sessionXml.cpp index dd4e01c..b363f65 100644 --- a/project2/xml/sessionXml.cpp +++ b/project2/xml/sessionXml.cpp @@ -17,15 +17,13 @@ class SessionXml : public Session {  		SessionXml(const xmlpp::Element *);  		virtual ~SessionXml(); -		const VariableType & GetValue(const Glib::ustring & name) const; +		VariableType GetValue(const Glib::ustring & name) const;  		Values GetValuesCopy() const;  		void SetValue(const Glib::ustring & name, const VariableType & value);  		void ClearValue(const Glib::ustring & name);  		time_t ExpiryTime() const;  		void ExpiryTime(time_t); -		const UUID sessionID; -  	private:  		Values vars;  		time_t expires; @@ -63,71 +61,71 @@ SessionContainerXml::SessionContainerXml()  SessionContainerXml::~SessionContainerXml()  { -	if (currentSession) { -		xmlpp::DomParser parser; -		xmlpp::Document * doc; -		try { -			parser.parse_file(xmlFile); -			doc = parser.get_document(); -			char xpath[200]; -			snprintf(xpath, 200, "/sessions/session[@id='%s' or @expires < %lu]", -					currentSession->sessionID.str().c_str(), time(NULL)); -			xmlpp::NodeSet sess = doc->get_root_node()->find(xpath); -			BOOST_FOREACH(xmlpp::Node * n, sess) { -				n->get_parent()->remove_child(n); -			} -		} -		catch (...) { -			doc = new xmlpp::Document(); -			doc->create_root_node("sessions"); -		} -		xmlpp::Element * sess = doc->get_root_node()->add_child("session"); -		sess->set_attribute("id", currentSession->sessionID.str()); -		sess->set_attribute("expires", boost::lexical_cast<Glib::ustring>(currentSession->expires)); -		BOOST_FOREACH(const SessionXml::Values::value_type & nvp, currentSession->vars) { -			xmlpp::Element * v = sess->add_child("var"); -			v->add_child_text(nvp.second); -			v->set_attribute("name", nvp.first); -		} -		doc->write_to_file(xmlFile); -		if (!parser) { -			delete doc; +} + +void +SessionContainerXml::SaveSession(SessionPtr currentSession) const +{ +	xmlpp::DomParser parser; +	xmlpp::Document * doc; +	try { +		parser.parse_file(xmlFile); +		doc = parser.get_document(); +		char xpath[200]; +		snprintf(xpath, 200, "/sessions/session[@id='%s' or @expires < %lu]", +				currentSession->ID.str().c_str(), time(NULL)); +		xmlpp::NodeSet sess = doc->get_root_node()->find(xpath); +		BOOST_FOREACH(xmlpp::Node * n, sess) { +			n->get_parent()->remove_child(n);  		} -		currentSession = NULL;  	} +	catch (...) { +		doc = new xmlpp::Document(); +		doc->create_root_node("sessions"); +	} +	xmlpp::Element * sess = doc->get_root_node()->add_child("session"); +	sess->set_attribute("id", currentSession->ID.str()); +	sess->set_attribute("expires", boost::lexical_cast<Glib::ustring>(currentSession->ExpiryTime())); +	BOOST_FOREACH(const Session::Values::value_type & nvp, currentSession->GetValuesCopy()) { +		xmlpp::Element * v = sess->add_child("var"); +		v->add_child_text(nvp.second); +		v->set_attribute("name", nvp.first); +	} +	doc->write_to_file(xmlFile); +	if (!parser) { +		delete doc; +	} +	currentSession = NULL;  }  SessionPtr -SessionContainerXml::getSession(UUID & sid) +SessionContainerXml::getSession(UUID & sid) const  { -	if (!currentSession || currentSession->sessionID != sid) { -		try { -			xmlpp::DomParser sessions(xmlFile); -			char xpath[200]; -			snprintf(xpath, 200, "/sessions/session[@id='%s' and @expires > %lu]", -					sid.str().c_str(), time(NULL)); -			xmlpp::NodeSet sess = sessions.get_document()->get_root_node()->find(xpath); -			if (sess.size() == 1) { -				currentSession = new SessionXml(dynamic_cast<const xmlpp::Element *>(sess[0])); -			} -			else { -				currentSession = new SessionXml(sid); -			} +	try { +		xmlpp::DomParser sessions(xmlFile); +		char xpath[200]; +		snprintf(xpath, 200, "/sessions/session[@id='%s' and @expires > %lu]", +				sid.str().c_str(), time(NULL)); +		xmlpp::NodeSet sess = sessions.get_document()->get_root_node()->find(xpath); +		if (sess.size() == 1) { +			return new SessionXml(dynamic_cast<const xmlpp::Element *>(sess[0]));  		} -		catch (...) { -			currentSession = new SessionXml(sid); +		else { +			return new SessionXml(sid);  		}  	} -	return currentSession; +	catch (...) { +		return new SessionXml(sid); +	}  }  SessionXml::SessionXml(UUID & sid) : -	sessionID(sid.is_nil() ? sid = UUID::generate_random() : sid) +	Session(sid)  {  }  SessionXml::SessionXml(const xmlpp::Element * p) : -	sessionID(p->get_attribute_value("id")), +	Session(UUID(p->get_attribute_value("id"))),  	expires(boost::lexical_cast<time_t>(p->get_attribute_value("expires")))  {  	xmlpp::NodeSet xvars = p->find("var"); @@ -155,14 +153,10 @@ SessionXml::ExpiryTime() const  	return expires;  } -const VariableType & +VariableType  SessionXml::GetValue(const Glib::ustring & name) const  { -	Values::const_iterator i = vars.find(name); -	if (i == vars.end()) { -		throw Session::VariableNotFound(name); -	} -	return i->second; +	return safeMapFind<VariableNotFound>(vars, name)->second;  }  void diff --git a/project2/xml/sessionXml.h b/project2/xml/sessionXml.h index 9b5c3e1..96cd1d2 100644 --- a/project2/xml/sessionXml.h +++ b/project2/xml/sessionXml.h @@ -10,10 +10,9 @@ class SessionContainerXml : public SessionContainer {  		SessionContainerXml();  		~SessionContainerXml(); +		void SaveSession(SessionPtr) const;  	protected: -		SessionPtr getSession(UUID & sid); -		typedef boost::intrusive_ptr<SessionXml> SessionXmlPtr; -		SessionXmlPtr currentSession; +		SessionPtr getSession(UUID & sid) const;  	private:  		// Configurables diff --git a/project2/xml/xslPreFetch.cpp b/project2/xml/xslPreFetch.cpp index 136e20f..74cb0eb 100644 --- a/project2/xml/xslPreFetch.cpp +++ b/project2/xml/xslPreFetch.cpp @@ -8,7 +8,7 @@ XslPreFetch::XslPreFetch(const xmlpp::Element * p) :  	SourceObject(p),  	View(p),  	Task(p), -	CurlHelper(p), +	VariableCurlHelper(p),  	html(p->get_attribute_value("html") == "true"),  	warnings(p->get_attribute_value("warnings") != "false"),  	encoding(p, "encoding", false) @@ -37,7 +37,7 @@ XslPreFetch::loadComplete(const CommonObjects *)  } -CurlHandle::Ptr +CurlPtr  XslPreFetch::newCurl() const  {  	return CurlHelper::newCurl(); diff --git a/project2/xml/xslPreFetch.h b/project2/xml/xslPreFetch.h index c9e6a9a..fb453d5 100644 --- a/project2/xml/xslPreFetch.h +++ b/project2/xml/xslPreFetch.h @@ -8,7 +8,7 @@  #include <libxml++/nodes/element.h>  /// Project2 component to queue up CURL objects to be downloaded -class XslPreFetch : public View, public Task, XslRowsCache, CurlHelper { +class XslPreFetch : public View, public Task, XslRowsCache, VariableCurlHelper {  	public:  		XslPreFetch(const xmlpp::Element * p);  		~XslPreFetch(); @@ -21,7 +21,7 @@ class XslPreFetch : public View, public Task, XslRowsCache, CurlHelper {  		const bool warnings;  		const Variable encoding; -		CurlHandle::Ptr newCurl() const; +		CurlPtr newCurl() const;  		bool asHtml() const;  		bool withWarnings() const;  }; diff --git a/project2/xml/xslRows.cpp b/project2/xml/xslRows.cpp index 666b607..38b7338 100644 --- a/project2/xml/xslRows.cpp +++ b/project2/xml/xslRows.cpp @@ -19,7 +19,7 @@ SimpleMessageException(XpathEvalError);  XslRows::XslRows(const xmlpp::Element * p) :  	RowSet(p), -	CurlHelper(p), +	VariableCurlHelper(p),  	html(p->get_attribute_value("html") == "true"),  	warnings(p->get_attribute_value("warnings") != "false"),  	encoding(p, "encoding", false) @@ -60,7 +60,7 @@ XslRows::withWarnings() const  	return warnings;  } -CurlHandle::Ptr +CurlPtr  XslRows::newCurl() const  {  	return CurlHelper::newCurl(); diff --git a/project2/xml/xslRows.h b/project2/xml/xslRows.h index e33932f..9611ca4 100644 --- a/project2/xml/xslRows.h +++ b/project2/xml/xslRows.h @@ -12,7 +12,7 @@  #include "definedColumns.h"  /// Project2 component to create a row set based on the contents of an XML resource and specific XPaths with its hierarchy -class XslRows : public RowSet, XslRowsCache, CurlHelper { +class XslRows : public RowSet, XslRowsCache, VariableCurlHelper {  	public:  		XslRows(const xmlpp::Element * p);  		~XslRows(); @@ -44,7 +44,7 @@ class XslRows : public RowSet, XslRowsCache, CurlHelper {  		typedef std::map<const Glib::ustring, FilterViewPtr> FilterViews;  		FilterViews fvs; -		virtual CurlHandle::Ptr newCurl() const; +		virtual CurlPtr newCurl() const;  		virtual bool asHtml() const;  		virtual bool withWarnings() const; diff --git a/project2/xml/xslRowsCache.cpp b/project2/xml/xslRowsCache.cpp index 51fd6c0..f229dda 100644 --- a/project2/xml/xslRowsCache.cpp +++ b/project2/xml/xslRowsCache.cpp @@ -3,6 +3,8 @@  #include <string.h>  #include <libxml/HTMLparser.h>  #include "exceptions.h" +#include "curlHelper.h" +#include "safeMapFind.h"  XslRowsCache::Documents XslRowsCache::documents;  XslRowsCache::Queued XslRowsCache::queued; @@ -13,15 +15,15 @@ SimpleMessageException(DownloadFailed);  class XslCachePopulator : public CurlCompleteCallback {  	public: -		XslCachePopulator(CurlHandle::Ptr ch, const Glib::ustring & u, bool h, bool w, const char * e) : +		XslCachePopulator(CurlPtr ch, const Glib::ustring & u, bool h, bool w, const char * e) :  			CurlCompleteCallback(ch), +			handler(boost::bind(&XslCachePopulator::append, this, _1, _2)),  			url(u),  			html(h),  			warnings(w),  			encoding(e ? strdup(e) : NULL)  		{ -			curl->setopt(CURLOPT_WRITEDATA, &buf); -			curl->setopt(CURLOPT_WRITEFUNCTION, &XslRowsCache::handleDataHelper); +			ch->setReadHandler(handler);  		}  		~XslCachePopulator()  		{ @@ -40,7 +42,13 @@ class XslCachePopulator : public CurlCompleteCallback {  			XslRowsCache::documents.insert(XslRowsCache::Documents::value_type(url,  						XslRowsCache::Documents::value_type::second_type(doc, xmlFreeDoc)));  		} +		size_t append(const char * c, size_t b) +		{ +			buf.append(c, b); +			return b; +		} +		Curl::ReadHandler handler;  		std::string buf;  		const Glib::ustring url;  		const bool html; @@ -48,14 +56,6 @@ class XslCachePopulator : public CurlCompleteCallback {  		char * encoding;  }; -size_t -XslRowsCache::handleDataHelper(const char * ptr, size_t size, size_t nmemb, void *stream) -{ -	std::string * buf = static_cast<std::string *>(stream); -	buf->append(ptr, size * nmemb); -	return size * nmemb; -} -  xmlDocPtr  XslRowsCache::getDocument(const Glib::ustring & url, const char * encoding) const  { @@ -65,14 +65,7 @@ XslRowsCache::getDocument(const Glib::ustring & url, const char * encoding) cons  		cbf.perform();  		queued.clear();  	} -	i = documents.find(url); -	if (i == documents.end()) { -		// This should never happen -		throw DownloadFailed(url); -	} -	else { -		return i->second.get(); -	} +	return safeMapFind<DownloadFailed>(documents, url)->second.get();  }  void diff --git a/project2/xml/xslRowsCache.h b/project2/xml/xslRowsCache.h index 55b8674..8fb9940 100644 --- a/project2/xml/xslRowsCache.h +++ b/project2/xml/xslRowsCache.h @@ -5,7 +5,7 @@  #include <boost/shared_ptr.hpp>  #include <map>  #include <set> -#include "../libmisc/curlsup.h" +#include <curlHelper.h>  #include <glibmm/ustring.h>  class XslRowsCache { @@ -18,7 +18,7 @@ class XslRowsCache {  		void queue(const Glib::ustring & url, const char * encoding) const; -		virtual CurlHandle::Ptr newCurl() const = 0; +		virtual CurlPtr newCurl() const = 0;  		virtual bool asHtml() const = 0;  		virtual bool withWarnings() const = 0; @@ -26,7 +26,6 @@ class XslRowsCache {  		xmlDocPtr getDocument(const Glib::ustring & url, const char * encoding) const;  	private: -		static size_t handleDataHelper(const char * ptr, size_t size, size_t nmemb, void *stream);  		static CurlBulkFetcher cbf;  		friend class XslCachePopulator; | 
