summaryrefslogtreecommitdiff
path: root/project2/cgi
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-03-09 16:43:04 +0000
committerrandomdan <randomdan@localhost>2011-03-09 16:43:04 +0000
commit589f65d5748e0055a534d797c9b98206bafedc57 (patch)
tree62de5a89db702ba83f14a5a7a91d19535a06a388 /project2/cgi
parentA good start on docs, WTD (diff)
downloadproject2-589f65d5748e0055a534d797c9b98206bafedc57.tar.bz2
project2-589f65d5748e0055a534d797c9b98206bafedc57.tar.xz
project2-589f65d5748e0055a534d797c9b98206bafedc57.zip
Allow specifying all sorts of previously hardcoded things, most importantly paths
Rework the CGI stage structure to support custom presentations in the event of errors Changes to the Jamfile to ensure each component is complete in itself
Diffstat (limited to 'project2/cgi')
-rw-r--r--project2/cgi/cgiAppEngine.cpp273
-rw-r--r--project2/cgi/cgiAppEngine.h78
-rw-r--r--project2/cgi/cgiEnvironment.cpp12
-rw-r--r--project2/cgi/cgiEnvironment.h6
-rw-r--r--project2/cgi/cgiHttpHeader.cpp29
-rw-r--r--project2/cgi/cgiHttpHeader.h20
-rw-r--r--project2/cgi/cgiStageCustomError.cpp44
-rw-r--r--project2/cgi/cgiStageCustomNotFound.cpp43
-rw-r--r--project2/cgi/cgiStageDefaultError.cpp52
-rw-r--r--project2/cgi/cgiStageDefaultNotFound.cpp44
-rw-r--r--project2/cgi/cgiStageInitial.cpp19
-rw-r--r--project2/cgi/cgiStagePresent.cpp44
-rw-r--r--project2/cgi/cgiStageRequest.cpp60
-rw-r--r--project2/cgi/p2webFCgi.cpp1
14 files changed, 471 insertions, 254 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index 7df0279..547506d 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -2,14 +2,12 @@
#include <cgicc/Cgicc.h>
#include <cgicc/HTTPHeader.h>
#include "cgiEnvironment.h"
-#include "../xmlObjectLoader.h"
#include "../iterate.h"
#include "../logger.h"
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include "../sessionXml.h"
-#include <cxxabi.h>
#include <boost/date_time/microsec_time_clock.hpp>
const std::string SESSIONID = "sessionID";
@@ -20,32 +18,6 @@ SessionContainer * sessionsContainer = new SessionContainerXml();
SimpleMessageException(UnknownDomain);
-class Project2HttpHeader : public cgicc::HTTPHeader {
- public:
- typedef std::map<std::string, const Glib::ustring> Headers;
- Project2HttpHeader(const std::string & s, const std::string & t) :
- cgicc::HTTPHeader("")
- {
- addHeader("Status", s);
- addHeader("Content-Type", t);
- }
- void addHeader(const std::string & name, const Glib::ustring & value) {
- headers.erase(name);
- headers.insert(Headers::value_type(name, value));
- }
- void render(std::ostream & out) const {
- BOOST_FOREACH(const Headers::value_type & h, headers) {
- out << h.first << ": " << h.second << std::endl;
- }
- BOOST_FOREACH(const cgicc::HTTPCookie & cookie, getCookies()) {
- out << cookie << std::endl;
- }
- out << std::endl;
- }
- private:
- Headers headers;
-};
-
static
int
xmlWrite(void * _out, const char * buf, int len)
@@ -64,20 +36,7 @@ CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) :
sessionID = c.getValue();
}
}
- try {
- if (_env->getRequestMethod() == "POST") {
- currentStage = new RequestStage(e->elems[0]);
- }
- else {
- currentStage = new PresentStage(e->elems.size() > 0 ? e->elems[0] : "index");
- }
- }
- catch (const XmlScriptParser::NotFound & nf) {
- currentStage = new NotFoundStage(_env, nf);
- }
- catch (const std::exception & ex) {
- currentStage = new ErrorStage(_env, ex);
- }
+ currentStage = new InitialStage(e);
}
CgiApplicationEngine::~CgiApplicationEngine()
@@ -114,25 +73,41 @@ void
CgiApplicationEngine::process() const
{
startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
- try {
- for (StagePtr nextStage; (nextStage = currentStage->run()); ) {
- currentStage = nextStage;
+ bool triedNotFound = false;
+ bool triedOnError = false;
+ StagePtr nextStage;
+ do {
+ try {
+ nextStage = currentStage->run();
}
- }
- catch (const XmlScriptParser::NotFound & nf) {
- currentStage = new NotFoundStage(_env, nf);
- }
- catch (const std::exception & ex) {
- currentStage = new ErrorStage(_env, ex);
- }
+ catch (const XmlScriptParser::NotFound & nf) {
+ if (_env->notFoundPresent.empty() || triedNotFound) {
+ nextStage = new DefaultNotFoundStage(_env, nf);
+ }
+ else {
+ triedNotFound = true;
+ nextStage = new CustomNotFoundStage(_env, nf);
+ }
+ }
+ catch (const std::exception & ex) {
+ if (_env->onErrorPresent.empty() || triedOnError) {
+ nextStage = new DefaultErrorStage(_env, ex);
+ }
+ else {
+ triedNotFound = true;
+ nextStage = new CustomErrorStage(_env, ex);
+ }
+ }
+ } while (nextStage && (currentStage = nextStage));
endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
- const Presenter * p = boost::dynamic_pointer_cast<const Presenter>(currentStage).get();
+ PresenterPtr p = boost::dynamic_pointer_cast<Presenter>(currentStage);
if (p) {
- addAppData(p);
+ addAppData(p.get());
}
}
-CgiApplicationEngine::Stage::Stage()
+CgiApplicationEngine::Stage::Stage(const CgiEnvironment * env) :
+ e(env)
{
}
@@ -140,59 +115,36 @@ CgiApplicationEngine::Stage::~Stage()
{
}
-CgiApplicationEngine::PresentStage::PresentStage(const std::string & id) :
- XmlProcessPresenter("present", id, false)
-{
-}
-
-CgiApplicationEngine::PresentStage::~PresentStage()
-{
-}
-
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::PresentStage::run()
-{
- BOOST_FOREACH(ParamCheckers::value_type pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- return new PresentStage(pc->present);
- }
- }
- execute();
- return NULL;
-}
-
CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::PresentStage::getHeader() const
+CgiApplicationEngine::Stage::getHeader() const
{
- Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
- header->addHeader("Cache-control", "no-cache");
- return HttpHeaderPtr(header);
+ return CgiApplicationEngine::HttpHeaderPtr();
}
CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::PresentStage::getDataDocument() const
+CgiApplicationEngine::Stage::getDataDocument() const
{
- return XmlProcessPresenter::getDataDocument();
+ return XmlDocPtr();
}
void
CgiApplicationEngine::addEnvData(const Presenter * p) const
{
// These were for debug... but why not pass them on?
- p->addField("servername", "project2", env()->getServerName());
- p->addField("scriptname", "project2", env()->getScriptName());
+ p->addField("servername", env()->getXmlPrefix(), env()->getServerName());
+ p->addField("scriptname", env()->getXmlPrefix(), env()->getScriptName());
// URL elements
- p->pushSub("uriElems", "project2");
+ p->pushSub("uriElems", env()->getXmlPrefix());
BOOST_FOREACH(std::string s, _env->elems) {
- p->addField("uriElem", "project2", s);
+ p->addField("uriElem", env()->getXmlPrefix(), s);
}
p->popSub();
// Parameters
- p->pushSub("params", "project2");
+ p->pushSub("params", env()->getXmlPrefix());
BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) {
- p->pushSub("param", "project2");
+ p->pushSub("param", env()->getXmlPrefix());
p->addAttr("name", fe.getName());
p->addAttr("value", fe.getValue());
p->popSub();
@@ -205,11 +157,11 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
{
// Sessions variables
if (!sessionID.is_nil()) {
- p->pushSub("session", "project2");
+ p->pushSub("session", env()->getXmlPrefix());
p->addField("id", sessionID.str());
Session::Values session(sessionsContainer->GetSession(sessionID)->GetValuesCopy());
BOOST_FOREACH(Session::Values::value_type sv, session) {
- p->pushSub("var", "project2");
+ p->pushSub("var", env()->getXmlPrefix());
p->addAttr("value", sv.second);
p->addAttr("name", sv.first);
p->popSub();
@@ -218,7 +170,7 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
}
// Timing info
- p->pushSub("timing", "project2");
+ p->pushSub("timing", env()->getXmlPrefix());
p->addAttr("start", startTime);
if (!endTime.is_not_a_date_time()) {
p->addAttr("end", endTime);
@@ -227,60 +179,6 @@ CgiApplicationEngine::addAppData(const Presenter * p) const
p->popSub();
}
-CgiApplicationEngine::RequestStage::RequestStage(const std::string & id)
-{
- XmlScriptParser request("request", id, false);
- xmlpp::Element * requestRoot = request.get_document()->get_root_node();
- present = requestRoot->get_attribute_value("present");
- rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true";
- localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";
-
- LoaderBase loader("http://project2.randomdan.homeip.net", true);
- loader.supportedStorers.insert(Storer::into(&parameterChecks));
- loader.supportedStorers.insert(Storer::into(&rowSets));
- loader.supportedStorers.insert(Storer::into(&tasks));
- loader.collectAll(this, requestRoot, true);
-}
-CgiApplicationEngine::RequestStage::~RequestStage()
-{
-}
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::RequestStage::run()
-{
- BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- return new PresentStage(pc->present);
- }
- }
- RequestHost::run();
- return present.empty() ? NULL : new PresentStage(present);
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::RequestStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("200 OK", "text/xml"));
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::RequestStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
-const Glib::ustring CgiApplicationEngine::RequestStage::resp("request");
-const Glib::ustring CgiApplicationEngine::RequestStage::style;
-const Glib::ustring &
-CgiApplicationEngine::RequestStage::getResponseRootNodeName() const
-{
- return resp;
-}
-const Glib::ustring &
-CgiApplicationEngine::RequestStage::getResponseStyle() const
-{
- return style;
-}
-
SessionPtr
CgiApplicationEngine::session() const
{
@@ -310,89 +208,4 @@ CgiApplicationEngine::loadEngineSection(const xmlpp::Element * e) const
domplat.push_back(DomainPlatforms::value_type(e->get_attribute_value("name"), e->get_attribute_value("platform")));
}
-CgiApplicationEngine::FailStage::FailStage(const CgiEnvironment * e) :
- env(e)
-{
-}
-
-CgiApplicationEngine::FailStage::~FailStage()
-{
-}
-
-const Glib::ustring &
-CgiApplicationEngine::FailStage::getResponseStyle() const
-{
- return env->errorTransformStyle;
-}
-
-CgiApplicationEngine::StagePtr
-CgiApplicationEngine::FailStage::run()
-{
- return NULL;
-}
-
-CgiApplicationEngine::NotFoundStage::NotFoundStage(const CgiEnvironment * e, const XmlScriptParser::NotFound & nf) :
- CgiApplicationEngine::FailStage(e)
-{
- initDoc();
- responseDoc->get_root_node()->add_child("resource")->set_child_text(nf.what());
-}
-
-CgiApplicationEngine::NotFoundStage::~NotFoundStage()
-{
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::NotFoundStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("404 Not found", env->errorContentType));
-}
-
-const Glib::ustring CgiApplicationEngine::NotFoundStage::resp("notfound");
-const Glib::ustring &
-CgiApplicationEngine::NotFoundStage::getResponseRootNodeName() const
-{
- return resp;
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::NotFoundStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
-CgiApplicationEngine::ErrorStage::ErrorStage(const CgiEnvironment * e, const std::exception & ex) :
- CgiApplicationEngine::FailStage(e)
-{
- initDoc();
- char * buf = __cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL);
- Logger()->messagef(LOG_ERR, "%s: Request errored: %s: %s", __FUNCTION__, buf, ex.what());
- responseDoc->get_root_node()->add_child("type")->set_child_text(buf);
- responseDoc->get_root_node()->add_child("what")->set_child_text(ex.what());
- free(buf);
-}
-
-CgiApplicationEngine::ErrorStage::~ErrorStage()
-{
-}
-
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::ErrorStage::getHeader() const
-{
- return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", env->errorContentType));
-}
-
-const Glib::ustring CgiApplicationEngine::ErrorStage::resp("error");
-const Glib::ustring &
-CgiApplicationEngine::ErrorStage::getResponseRootNodeName() const
-{
- return resp;
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::ErrorStage::getDataDocument() const
-{
- return XmlPresenter::getDataDocument();
-}
-
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index cfab7c4..de9b95a 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -47,19 +47,29 @@ class CgiApplicationEngine : public ApplicationEngine {
class Stage;
typedef boost::intrusive_ptr<Stage> StagePtr;
+ /// Base class for a stage iteration that should eventually produce a response for the client
class Stage : public virtual CommonObjects {
public:
- Stage();
+ Stage(const CgiEnvironment * e);
virtual ~Stage() = 0;
virtual StagePtr run() = 0;
- virtual XmlDocPtr getDataDocument() const = 0;
- virtual HttpHeaderPtr getHeader() const = 0;
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
+ protected:
+ const CgiEnvironment * e;
+ };
+
+ /// Stage implementation used to bootstrap the iteration process based on the CGI environment
+ class InitialStage : public Stage {
+ public:
+ InitialStage(const CgiEnvironment * e);
+ virtual StagePtr run();
};
+ /// Stage to process POST requests
class RequestStage : public Stage, public XmlPresenter, RequestHost {
public:
- RequestStage(const std::string & id);
- virtual ~RequestStage();
+ RequestStage(const CgiEnvironment *, const std::string & id);
virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
@@ -77,51 +87,73 @@ class CgiApplicationEngine : public ApplicationEngine {
static const Glib::ustring style;
};
- class PresentStage : public Stage, public XmlProcessPresenter {
+ /// Stage to process GET requests and follow up RequestStages
+ class PresentStage : public virtual Stage, public XmlProcessPresenter {
public:
- PresentStage(const std::string & id);
- virtual ~PresentStage();
+ PresentStage(const CgiEnvironment * e, const std::string & id);
+ PresentStage(const CgiEnvironment * e, const std::string & group, const std::string & id);
virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
};
- class FailStage : public Stage, public XmlPresenter {
+ /// The built-in fail-safe not found stage
+ class DefaultNotFoundStage : public virtual Stage, public XmlPresenter {
public:
- FailStage(const CgiEnvironment *);
- virtual ~FailStage();
+ DefaultNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
- virtual const Glib::ustring & getResponseStyle() const;
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
virtual StagePtr run();
+ virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
+ private:
+ static const Glib::ustring resp;
+ const CgiEnvironment * e;
+ const XmlScriptParser::NotFound nf;
+ };
- protected:
- const CgiEnvironment * env;
+ /// Custom not found handling stage
+ class CustomNotFoundStage : public DefaultNotFoundStage, public PresentStage {
+ public:
+ CustomNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
+ virtual StagePtr run();
+ virtual XmlDocPtr getDataDocument() const;
+ virtual HttpHeaderPtr getHeader() const;
+ virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
};
- class NotFoundStage : public FailStage {
+ /// The built-in fail-safe unhandled error stage
+ class DefaultErrorStage : public virtual Stage, public XmlPresenter {
public:
- NotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
- virtual ~NotFoundStage();
+ DefaultErrorStage(const CgiEnvironment *, const std::exception &);
+ ~DefaultErrorStage();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
+ virtual StagePtr run();
virtual const Glib::ustring & getResponseRootNodeName() const;
+ virtual const Glib::ustring & getResponseStyle() const;
private:
static const Glib::ustring resp;
+ const CgiEnvironment * e;
+ char * buf;
+ std::string what;
};
- class ErrorStage : public FailStage {
+ /// Custom unhandled error handling stage
+ class CustomErrorStage : public DefaultErrorStage, public PresentStage {
public:
- ErrorStage(const CgiEnvironment *, const std::exception &);
- virtual ~ErrorStage();
-
+ CustomErrorStage(const CgiEnvironment *, const std::exception &);
+ virtual StagePtr run();
virtual XmlDocPtr getDataDocument() const;
virtual HttpHeaderPtr getHeader() const;
virtual const Glib::ustring & getResponseRootNodeName() const;
- private:
- static const Glib::ustring resp;
+ virtual const Glib::ustring & getResponseStyle() const;
};
+
mutable StagePtr currentStage;
mutable UUID sessionID;
};
diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp
index 43f45f2..e8d5ba3 100644
--- a/project2/cgi/cgiEnvironment.cpp
+++ b/project2/cgi/cgiEnvironment.cpp
@@ -28,10 +28,22 @@ CgiEnvironment::addOptions(boost::program_options::positional_options_descriptio
{
boost::program_options::options_description cgi("Project2 CGI options");
cgi.add_options()
+ ("defaultpresent", boost::program_options::value(&defaultPresent)->default_value("index"),
+ "The present script to use when no other is specified")
+ ("presentroot", boost::program_options::value(&presentRoot)->default_value("present"),
+ "The folder in which to find presentation scripts")
+ ("requestroot", boost::program_options::value(&requestRoot)->default_value("request"),
+ "The folder in which to find request scripts")
+ ("errorpresentroot", boost::program_options::value(&errorPresentRoot)->default_value("error"),
+ "The folder in which to find presentation scripts for error handling")
("errorcontenttype", boost::program_options::value(&errorContentType)->default_value("text/xml"),
"The Content-Type to use in HTTP headers in event of an error")
("errortransformstyle", boost::program_options::value(&errorTransformStyle),
"The xml-stylesheet to specify in the data document in event of an error")
+ ("notfoundpresent", boost::program_options::value(&notFoundPresent),
+ "The present script to use when the requested script does not exist")
+ ("onerrorpresent", boost::program_options::value(&onErrorPresent),
+ "The present script to use when the requested script (or child) fails")
#ifndef NDEBUG
("dumpdatadoc", boost::program_options::value(&dumpdatadoc),
"Write a copy of the data document before sending it to the web server")
diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h
index c9b33fa..ce765bf 100644
--- a/project2/cgi/cgiEnvironment.h
+++ b/project2/cgi/cgiEnvironment.h
@@ -32,6 +32,12 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment {
#endif
Glib::ustring errorContentType;
Glib::ustring errorTransformStyle;
+ std::string defaultPresent;
+ std::string presentRoot;
+ std::string requestRoot;
+ std::string errorPresentRoot;
+ std::string notFoundPresent;
+ std::string onErrorPresent;
};
#endif
diff --git a/project2/cgi/cgiHttpHeader.cpp b/project2/cgi/cgiHttpHeader.cpp
new file mode 100644
index 0000000..37a48c9
--- /dev/null
+++ b/project2/cgi/cgiHttpHeader.cpp
@@ -0,0 +1,29 @@
+#include "cgiHttpHeader.h"
+#include <boost/foreach.hpp>
+
+Project2HttpHeader::Project2HttpHeader(const std::string & s, const std::string & t) :
+ cgicc::HTTPHeader("")
+{
+ addHeader("Status", s);
+ addHeader("Content-Type", t);
+}
+
+void
+Project2HttpHeader::addHeader(const std::string & name, const Glib::ustring & value)
+{
+ headers.erase(name);
+ headers.insert(Headers::value_type(name, value));
+}
+
+void
+Project2HttpHeader::render(std::ostream & out) const
+{
+ BOOST_FOREACH(const Headers::value_type & h, headers) {
+ out << h.first << ": " << h.second << std::endl;
+ }
+ BOOST_FOREACH(const cgicc::HTTPCookie & cookie, getCookies()) {
+ out << cookie << std::endl;
+ }
+ out << std::endl;
+}
+
diff --git a/project2/cgi/cgiHttpHeader.h b/project2/cgi/cgiHttpHeader.h
new file mode 100644
index 0000000..f84c707
--- /dev/null
+++ b/project2/cgi/cgiHttpHeader.h
@@ -0,0 +1,20 @@
+#ifndef HTTP_HEADER_H
+#define HTTP_HEADER_H
+
+#include <cgicc/HTTPHeader.h>
+#include <string>
+#include <map>
+#include <glibmm/ustring.h>
+
+class Project2HttpHeader : public cgicc::HTTPHeader {
+ public:
+ typedef std::map<std::string, const Glib::ustring> Headers;
+ Project2HttpHeader(const std::string & s, const std::string & t);
+ void addHeader(const std::string & name, const Glib::ustring & value);
+ void render(std::ostream & out) const;
+ private:
+ Headers headers;
+};
+
+#endif
+
diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp
new file mode 100644
index 0000000..a3fbc1f
--- /dev/null
+++ b/project2/cgi/cgiStageCustomError.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex) :
+ CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::DefaultErrorStage(env, ex),
+ CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->onErrorPresent)
+{
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::CustomErrorStage::getHeader() const
+{
+ return CgiApplicationEngine::DefaultErrorStage::getHeader();
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::CustomErrorStage::run()
+{
+ CgiApplicationEngine::DefaultErrorStage::run();
+ return CgiApplicationEngine::PresentStage::run();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomErrorStage::getResponseRootNodeName() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseRootNodeName();
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::CustomErrorStage::getDataDocument() const
+{
+ return CgiApplicationEngine::PresentStage::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomErrorStage::getResponseStyle() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseStyle();
+}
+
+
diff --git a/project2/cgi/cgiStageCustomNotFound.cpp b/project2/cgi/cgiStageCustomNotFound.cpp
new file mode 100644
index 0000000..a2d33dc
--- /dev/null
+++ b/project2/cgi/cgiStageCustomNotFound.cpp
@@ -0,0 +1,43 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
+ CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::DefaultNotFoundStage(env, notfound),
+ CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->notFoundPresent)
+{
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::CustomNotFoundStage::getHeader() const
+{
+ return CgiApplicationEngine::DefaultNotFoundStage::getHeader();
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::CustomNotFoundStage::run()
+{
+ CgiApplicationEngine::DefaultNotFoundStage::run();
+ return CgiApplicationEngine::PresentStage::run();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomNotFoundStage::getResponseRootNodeName() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseRootNodeName();
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::CustomNotFoundStage::getDataDocument() const
+{
+ return CgiApplicationEngine::PresentStage::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::CustomNotFoundStage::getResponseStyle() const
+{
+ return CgiApplicationEngine::PresentStage::getResponseStyle();
+}
+
diff --git a/project2/cgi/cgiStageDefaultError.cpp b/project2/cgi/cgiStageDefaultError.cpp
new file mode 100644
index 0000000..c881da1
--- /dev/null
+++ b/project2/cgi/cgiStageDefaultError.cpp
@@ -0,0 +1,52 @@
+#include "cgiAppEngine.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+#include "cgiEnvironment.h"
+#include <cxxabi.h>
+
+const Glib::ustring CgiApplicationEngine::DefaultErrorStage::resp("error");
+
+CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const CgiEnvironment * env, const std::exception & ex) :
+ CgiApplicationEngine::Stage(env),
+ buf(__cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL)),
+ what(ex.what())
+{
+}
+
+CgiApplicationEngine::DefaultErrorStage::~DefaultErrorStage()
+{
+ free(buf);
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::DefaultErrorStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", e->errorContentType));
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::DefaultErrorStage::run()
+{
+ addField("error-type", e->getXmlPrefix(), buf);
+ addField("error-what", e->getXmlPrefix(), what.c_str());
+ return NULL;
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultErrorStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::DefaultErrorStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultErrorStage::getResponseStyle() const
+{
+ return e->errorTransformStyle;
+}
+
diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp
new file mode 100644
index 0000000..f32ad1f
--- /dev/null
+++ b/project2/cgi/cgiStageDefaultNotFound.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../logger.h"
+
+CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
+ CgiApplicationEngine::Stage(env),
+ nf(notfound)
+{
+ Logger()->messagef(LOG_ERR, "%s: Resource not found: %s", __FUNCTION__, nf.what());
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::DefaultNotFoundStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("404 Not found", e->errorContentType));
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::DefaultNotFoundStage::run()
+{
+ addField("missing-resource", e->getXmlPrefix(), nf.what());
+ return NULL;
+}
+
+const Glib::ustring CgiApplicationEngine::DefaultNotFoundStage::resp("notfound");
+const Glib::ustring &
+CgiApplicationEngine::DefaultNotFoundStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::DefaultNotFoundStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring &
+CgiApplicationEngine::DefaultNotFoundStage::getResponseStyle() const
+{
+ return e->errorTransformStyle;
+}
+
diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp
new file mode 100644
index 0000000..a9315bc
--- /dev/null
+++ b/project2/cgi/cgiStageInitial.cpp
@@ -0,0 +1,19 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+
+CgiApplicationEngine::InitialStage::InitialStage(const CgiEnvironment * env) :
+ CgiApplicationEngine::Stage(env)
+{
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::InitialStage::run()
+{
+ if (e->getRequestMethod() == "POST") {
+ return new RequestStage(e, e->elems[0]);
+ }
+ else {
+ return new PresentStage(e, e->elems.empty() ? e->defaultPresent : e->elems[0]);
+ }
+}
+
diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp
new file mode 100644
index 0000000..9dcf124
--- /dev/null
+++ b/project2/cgi/cgiStagePresent.cpp
@@ -0,0 +1,44 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include <boost/foreach.hpp>
+
+CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & id) :
+ CgiApplicationEngine::Stage(e),
+ XmlProcessPresenter(e->presentRoot, id, false)
+{
+}
+
+CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & group, const std::string & id) :
+ CgiApplicationEngine::Stage(e),
+ XmlProcessPresenter(group, id, false)
+{
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::PresentStage::run()
+{
+ BOOST_FOREACH(ParamCheckers::value_type pc, parameterChecks.get<bySOOrder>()) {
+ if (!pc->performCheck()) {
+ return new PresentStage(e, pc->present);
+ }
+ }
+ execute();
+ return NULL;
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::PresentStage::getHeader() const
+{
+ Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
+ header->addHeader("Cache-control", "no-cache");
+ return HttpHeaderPtr(header);
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::PresentStage::getDataDocument() const
+{
+ return XmlProcessPresenter::getDataDocument();
+}
+
+
diff --git a/project2/cgi/cgiStageRequest.cpp b/project2/cgi/cgiStageRequest.cpp
new file mode 100644
index 0000000..6602527
--- /dev/null
+++ b/project2/cgi/cgiStageRequest.cpp
@@ -0,0 +1,60 @@
+#include "cgiAppEngine.h"
+#include "cgiEnvironment.h"
+#include "cgiHttpHeader.h"
+#include "../xmlObjectLoader.h"
+#include <boost/foreach.hpp>
+
+CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const std::string & id) :
+ CgiApplicationEngine::Stage(e)
+{
+ XmlScriptParser request(e->requestRoot, id, false);
+ xmlpp::Element * requestRoot = request.get_document()->get_root_node();
+ present = requestRoot->get_attribute_value("present");
+ rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true";
+ localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";
+
+ LoaderBase loader(ApplicationEngine::getCurrent()->env()->getXmlNamespace(), true);
+ loader.supportedStorers.insert(Storer::into(&parameterChecks));
+ loader.supportedStorers.insert(Storer::into(&rowSets));
+ loader.supportedStorers.insert(Storer::into(&tasks));
+ loader.collectAll(this, requestRoot, true);
+}
+
+CgiApplicationEngine::StagePtr
+CgiApplicationEngine::RequestStage::run()
+{
+ BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks.get<bySOOrder>()) {
+ if (!pc->performCheck()) {
+ return new PresentStage(e, pc->present);
+ }
+ }
+ RequestHost::run();
+ return present.empty() ? NULL : new PresentStage(e, present);
+}
+
+CgiApplicationEngine::HttpHeaderPtr
+CgiApplicationEngine::RequestStage::getHeader() const
+{
+ return HttpHeaderPtr(new Project2HttpHeader("200 OK", "text/xml"));
+}
+
+CgiApplicationEngine::XmlDocPtr
+CgiApplicationEngine::RequestStage::getDataDocument() const
+{
+ return XmlPresenter::getDataDocument();
+}
+
+const Glib::ustring CgiApplicationEngine::RequestStage::resp("request");
+const Glib::ustring CgiApplicationEngine::RequestStage::style;
+const Glib::ustring &
+CgiApplicationEngine::RequestStage::getResponseRootNodeName() const
+{
+ return resp;
+}
+const Glib::ustring &
+CgiApplicationEngine::RequestStage::getResponseStyle() const
+{
+ return style;
+}
+
+
diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp
index d501787..d1aa29e 100644
--- a/project2/cgi/p2webFCgi.cpp
+++ b/project2/cgi/p2webFCgi.cpp
@@ -1,7 +1,6 @@
#include "cgiCommon.h"
#include "FCgiIO.h"
#include "../xmlObjectLoader.h"
-#include "../logger.h"
time_t lastPeriodic = 0;
time_t periodicDelay = 600;