diff options
| -rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 6 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.cpp | 3 | ||||
| -rw-r--r-- | project2/console/consoleEnvironment.cpp | 1 | ||||
| -rw-r--r-- | project2/sessionShm.cpp | 143 | ||||
| -rw-r--r-- | project2/sessionShm.h | 38 | ||||
| -rw-r--r-- | project2/sessionXml.cpp | 171 | ||||
| -rw-r--r-- | project2/sessionXml.h | 18 | 
7 files changed, 195 insertions, 185 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index f37172e..e419ddf 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -9,14 +9,14 @@  #include <boost/bind.hpp>  #include <boost/lexical_cast.hpp>  #include <boost/uuid/uuid_io.hpp> -#include "../sessionShm.h" +#include "../sessionXml.h"  #include <boost/uuid/uuid_generators.hpp>  const std::string SESSIONID = "sessionID";  typedef boost::uuids::uuid SIDKey;  typedef std::string SValue; -SessionContainer * sessionsContainer = new SessionContainerShm(); +SessionContainer * sessionsContainer = new SessionContainerXml();  CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) :  	ApplicationEngine(), @@ -118,7 +118,7 @@ CgiApplicationEngine::PresentStage::getDataDocument() const  		xmlpp::Element * sessionXml = responseRoot->add_child("session", "project2");  		sessionXml->set_attribute("id", boost::lexical_cast<Glib::ustring>(appEngine->sessionID));  		Session::Values session(sessionsContainer->GetSession(appEngine->sessionID)->GetValuesCopy()); -		BOOST_FOREACH(SessionShm::Values::value_type sv, session) { +		BOOST_FOREACH(Session::Values::value_type sv, session) {  			xmlpp::Element * param = sessionXml->add_child("var", "project2");  			param->add_child_text(sv.second);  			param->set_attribute("name", sv.first); diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 035f60a..e58bf5d 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -5,7 +5,8 @@  #include <libxml/xinclude.h>  ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * env, const boost::filesystem::path & f) : -	ApplicationEngine() +	ApplicationEngine(), +	_env(env)  {  	xmlpp::DomParser request(f.string());  	while (xmlXIncludeProcessFlags(request.get_document()->cobj(), XML_PARSE_NOXINCNODE) > 0); diff --git a/project2/console/consoleEnvironment.cpp b/project2/console/consoleEnvironment.cpp index 314f465..0d2f026 100644 --- a/project2/console/consoleEnvironment.cpp +++ b/project2/console/consoleEnvironment.cpp @@ -2,6 +2,7 @@  #include <sys/utsname.h>  #include <syslog.h>  #include <errno.h> +#include <stdio.h>  #include <string.h>  ConsoleEnvironment::ConsoleEnvironment(int argc, char ** argv) : diff --git a/project2/sessionShm.cpp b/project2/sessionShm.cpp deleted file mode 100644 index 8064142..0000000 --- a/project2/sessionShm.cpp +++ /dev/null @@ -1,143 +0,0 @@ -#include "sessionShm.h" -#include <syslog.h> -#include <set> -#include <boost/uuid/uuid.hpp> -#include <boost/foreach.hpp> -#include <boost/uuid/uuid_generators.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/uuid/uuid_io.hpp> - -using namespace boost::interprocess; -using namespace boost::uuids; -class SessionShmData { -	public: -		typedef boost::interprocess::string SKey; -		typedef boost::interprocess::string SValue; - -		typedef std::pair<const SKey, SValue> SValueType; -		typedef boost::interprocess::allocator<SValueType, boost::interprocess::managed_mapped_file::segment_manager> AllocatorValueType; -		typedef boost::interprocess::map<SKey, SValue, std::less<SKey>, AllocatorValueType> SessionValues; - -		SessionShmData(); -		~SessionShmData(); - -		SessionValues svs; -		time_t expiryTime; - -		static boost::interprocess::managed_mapped_file & shm(); -		static boost::shared_ptr<boost::interprocess::managed_mapped_file> _shm; -		friend class SessionContainerShm; -}; - -const char * shmFile = "/tmp/project2.sessions"; - -boost::shared_ptr<boost::interprocess::managed_mapped_file> SessionShmData::_shm; - -SessionContainerShm::SessionContainerShm() -{ -} - -SessionContainerShm::~SessionContainerShm() -{ -} - -void -SessionContainerShm::CleanUp() -{ -	std::set<std::string> toDelete; -	for (managed_mapped_file::const_named_iterator i = SessionShmData::shm().named_begin(); -			i != SessionShmData::shm().named_end(); i++) { -		const SessionShmData * s = static_cast<const SessionShmData *>(i->value()); -		if (s) { -			if (s->expiryTime < time(NULL)) { -				toDelete.insert(i->name()); -			} -		} -	} -	for(std::set<std::string>::const_iterator s = toDelete.begin(); s != toDelete.end(); s++) { -		SessionShmData::shm().destroy<const SessionShmData>(s->c_str()); -	} -} - -SessionPtr -SessionContainerShm::getSession(boost::uuids::uuid & sid) -{ -	if (sid.is_nil()) { -		sid = boost::uuids::random_generator()(); -	} -	return SessionPtr(new SessionShm( -			SessionShmData::shm().find_or_construct<SessionShmData>(boost::lexical_cast<std::string>(sid).c_str())())); -} - -SessionShm::SessionShm(SessionShmData * d) : data(d) -{ -} - -SessionShm::~SessionShm() -{ -} - -void -SessionShm::ExpiryTime(time_t t) -{ -	data->expiryTime = t; -} - -time_t -SessionShm::ExpiryTime() const -{ -	return data->expiryTime; -} - -SessionShmData::SessionShmData() : -	svs(std::less<SKey>(), AllocatorValueType(shm().get_segment_manager())) -{ -} - -SessionShmData::~SessionShmData() -{ -} - -boost::interprocess::managed_mapped_file & -SessionShmData::shm() -{ -	if (!_shm) { -		_shm = boost::shared_ptr<boost::interprocess::managed_mapped_file>( -				new boost::interprocess::managed_mapped_file(open_or_create, shmFile, 1024 * 1024)); -	} -	return *_shm; -} - -Glib::ustring -SessionShm::GetValue(const Glib::ustring & name) const -{ -	SessionShmData::SessionValues::const_iterator i = data->svs.find(name.c_str()); -	if (i == data->svs.end()) { -		throw Session::VariableNotFound(); -	} -	return i->second.c_str(); -} - -void -SessionShm::SetValue(const Glib::ustring & name, const Glib::ustring & value) -{ -	data->svs.erase(name.c_str()); -	data->svs.insert(std::pair<SessionShmData::SKey, SessionShmData::SValue>(name.c_str(), value.c_str())); -} - -void -SessionShm::ClearValue(const Glib::ustring & name) -{ -	data->svs.erase(name.c_str()); -} - -Session::Values -SessionShm::GetValuesCopy() const -{ -	Values v; -	BOOST_FOREACH(SessionShmData::SessionValues::value_type kvp, data->svs) { -		v[kvp.first.c_str()] = kvp.second.c_str(); -	} -	return v; -} - diff --git a/project2/sessionShm.h b/project2/sessionShm.h deleted file mode 100644 index 2794303..0000000 --- a/project2/sessionShm.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef SESSIONSHM_H -#define SESSIONSHM_H - -#include "session.h" -#include <boost/interprocess/containers/string.hpp> -#include <boost/interprocess/managed_mapped_file.hpp> -#include <boost/interprocess/allocators/allocator.hpp> -#include <boost/interprocess/containers/map.hpp> - -class SessionShmData; -class SessionShm : public Session { -	public: -		SessionShm(SessionShmData *); -		virtual ~SessionShm(); - -		Glib::ustring GetValue(const Glib::ustring & name) const; -		Values GetValuesCopy() const; -		void SetValue(const Glib::ustring & name, const Glib::ustring & value); -		void ClearValue(const Glib::ustring & name); -		time_t ExpiryTime() const; -		void ExpiryTime(time_t); - -	private: -		SessionShmData * data; -}; - -class SessionContainerShm : public SessionContainer { -	public: -		SessionContainerShm(); -		~SessionContainerShm(); - -		void CleanUp(); - -	protected: -		SessionPtr getSession(boost::uuids::uuid & sid); -}; - -#endif diff --git a/project2/sessionXml.cpp b/project2/sessionXml.cpp new file mode 100644 index 0000000..68e19ea --- /dev/null +++ b/project2/sessionXml.cpp @@ -0,0 +1,171 @@ +#include "sessionXml.h" +#include <libxml++/nodes/element.h> +#include <libxml++/parsers/domparser.h> +#include <libxml++/nodes/textnode.h> +#include <set> +#include <boost/uuid/uuid.hpp> +#include <boost/foreach.hpp> +#include <boost/uuid/uuid_generators.hpp> +#include <boost/lexical_cast.hpp> +#include <boost/uuid/uuid_io.hpp> + +using namespace boost::uuids; +class SessionXml : public Session { +	public: +		SessionXml(boost::uuids::uuid & sid); +		SessionXml(const xmlpp::Element *); +		virtual ~SessionXml(); + +		Glib::ustring GetValue(const Glib::ustring & name) const; +		Values GetValuesCopy() const; +		void SetValue(const Glib::ustring & name, const Glib::ustring & value); +		void ClearValue(const Glib::ustring & name); +		time_t ExpiryTime() const; +		void ExpiryTime(time_t); + +		const uuid sessionID; + +	private: +		Values vars; +		time_t expires; + +		friend class SessionContainerXml; +}; +typedef boost::intrusive_ptr<SessionXml> SessionXmlPtr; + + +const char * xmlFile = "/tmp/project2sessions.xml"; +SessionXmlPtr currentSession; + +SessionContainerXml::SessionContainerXml() +{ +} + +SessionContainerXml::~SessionContainerXml() +{ +	CleanUp(); +} + +void +SessionContainerXml::CleanUp() +{ +	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]", +					boost::lexical_cast<std::string>(currentSession->sessionID).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", boost::lexical_cast<Glib::ustring>(currentSession->sessionID)); +		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; +		} +		currentSession = NULL; +	} +} + +SessionPtr +SessionContainerXml::getSession(boost::uuids::uuid & sid) +{ +	if (!currentSession || currentSession->sessionID != sid) { +		try { +			xmlpp::DomParser sessions(xmlFile); +			char xpath[200]; +			snprintf(xpath, 200, "/sessions/session[@id='%s' and @expires > %lu]", +					boost::lexical_cast<std::string>(sid).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); +			} +		} +		catch (...) { +			currentSession = new SessionXml(sid); +		} +	} +	return currentSession; +} + +SessionXml::SessionXml(boost::uuids::uuid & sid) : +	sessionID(sid.is_nil() ? sid = boost::uuids::random_generator()() : sid) +{ +} + +SessionXml::SessionXml(const xmlpp::Element * p) : +	sessionID(boost::lexical_cast<uuid>(p->get_attribute_value("id"))), +	expires(boost::lexical_cast<time_t>(p->get_attribute_value("expires"))) +{ +	xmlpp::NodeSet xvars = p->find("var"); +	BOOST_FOREACH(const xmlpp::Node * n, xvars) { +		const xmlpp::Element * e = dynamic_cast<const xmlpp::Element *>(n); +		if (e) { +			vars[e->get_attribute_value("name")] = e->get_child_text()->get_content(); +		} +	} +} + +SessionXml::~SessionXml() +{ +} + +void +SessionXml::ExpiryTime(time_t t) +{ +	expires = t; +} + +time_t +SessionXml::ExpiryTime() const +{ +	return expires; +} + +Glib::ustring +SessionXml::GetValue(const Glib::ustring & name) const +{ +	Values::const_iterator i = vars.find(name); +	if (i == vars.end()) { +		throw Session::VariableNotFound(); +	} +	return i->second; +} + +void +SessionXml::SetValue(const Glib::ustring & name, const Glib::ustring & value) +{ +	vars[name] = value; +} + +void +SessionXml::ClearValue(const Glib::ustring & name) +{ +	vars.erase(name); +} + +Session::Values +SessionXml::GetValuesCopy() const +{ +	return vars; +} + diff --git a/project2/sessionXml.h b/project2/sessionXml.h new file mode 100644 index 0000000..6995826 --- /dev/null +++ b/project2/sessionXml.h @@ -0,0 +1,18 @@ +#ifndef SESSIONXML_H +#define SESSIONXML_H + +#include "session.h" +#include <map> + +class SessionContainerXml : public SessionContainer { +	public: +		SessionContainerXml(); +		~SessionContainerXml(); + +		void CleanUp(); + +	protected: +		SessionPtr getSession(boost::uuids::uuid & sid); +}; + +#endif  | 
