summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-08-31 19:51:02 +0000
committerrandomdan <randomdan@localhost>2010-08-31 19:51:02 +0000
commit5d1e3055929e4ae47c2aaa9100a1c8fee9afb295 (patch)
treee4fcd16d531847ad17961f97d0d588e4cf659400
parentAdd alarm to be called when p2web has been idle for 60seconds (diff)
downloadproject2-5d1e3055929e4ae47c2aaa9100a1c8fee9afb295.tar.bz2
project2-5d1e3055929e4ae47c2aaa9100a1c8fee9afb295.tar.xz
project2-5d1e3055929e4ae47c2aaa9100a1c8fee9afb295.zip
Drop the pain in the ass SHM session container in favour of an XML one
Fix setting the environment up in p2console
-rw-r--r--project2/cgi/cgiAppEngine.cpp6
-rw-r--r--project2/console/consoleAppEngine.cpp3
-rw-r--r--project2/console/consoleEnvironment.cpp1
-rw-r--r--project2/sessionShm.cpp143
-rw-r--r--project2/sessionShm.h38
-rw-r--r--project2/sessionXml.cpp171
-rw-r--r--project2/sessionXml.h18
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