summaryrefslogtreecommitdiff
path: root/project2/cgi
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-07-14 19:50:11 +0000
committerrandomdan <randomdan@localhost>2011-07-14 19:50:11 +0000
commitd2f60795927647c09acbeceb32efb8a29314c340 (patch)
tree5dc1f6f9b8331a17e67863c847ea63ca97f5d92c /project2/cgi
parentFix unused_result warning when compiled with optimization enabled (diff)
downloadproject2-d2f60795927647c09acbeceb32efb8a29314c340.tar.bz2
project2-d2f60795927647c09acbeceb32efb8a29314c340.tar.xz
project2-d2f60795927647c09acbeceb32efb8a29314c340.zip
All new dynamic transformations and processing and tidyup and stuff
Diffstat (limited to 'project2/cgi')
-rw-r--r--project2/cgi/cgiAppEngine.cpp99
-rw-r--r--project2/cgi/cgiAppEngine.h84
-rw-r--r--project2/cgi/cgiCommon.cpp4
-rw-r--r--project2/cgi/cgiEnvironment.cpp4
-rw-r--r--project2/cgi/cgiEnvironment.h3
-rw-r--r--project2/cgi/cgiStageCustomError.cpp25
-rw-r--r--project2/cgi/cgiStageCustomNotFound.cpp26
-rw-r--r--project2/cgi/cgiStageDefaultError.cpp35
-rw-r--r--project2/cgi/cgiStageDefaultNotFound.cpp34
-rw-r--r--project2/cgi/cgiStageInitial.cpp6
-rw-r--r--project2/cgi/cgiStagePresent.cpp43
-rw-r--r--project2/cgi/cgiStageRequest.cpp53
-rw-r--r--project2/cgi/testCgi.cpp70
13 files changed, 223 insertions, 263 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp
index 52e69cf..f4eb134 100644
--- a/project2/cgi/cgiAppEngine.cpp
+++ b/project2/cgi/cgiAppEngine.cpp
@@ -8,6 +8,7 @@
#include <boost/regex.hpp>
#include <boost/foreach.hpp>
#include "../sessionXml.h"
+#include "../ostreamWrapper.h"
#include <boost/date_time/microsec_time_clock.hpp>
const std::string SESSIONID = "sessionID";
@@ -18,29 +19,22 @@ SessionContainer * sessionsContainer = new SessionContainerXml();
SimpleMessageException(UnknownDomain);
-static
-int
-xmlWrite(void * _out, const char * buf, int len)
-{
- std::ostream * IO = static_cast<std::ostream*>(_out);
- IO->write(buf, len);
- return len;
-}
-
-CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e) :
+CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e, std::ostream & io) :
ApplicationEngine("web/host"),
- _env(e)
+ _env(e),
+ IO(io)
{
BOOST_FOREACH(const cgicc::HTTPCookie c, e->getCookieList()) {
if (c.getName() == SESSIONID) {
sessionID = c.getValue();
}
}
- currentStage = new InitialStage(e);
+ currentStage = NextStage(new InitialStage(e));
}
CgiApplicationEngine::~CgiApplicationEngine()
{
+ sessionsContainer->CleanUp();
}
const Environment *
@@ -49,25 +43,14 @@ CgiApplicationEngine::env() const
return _env;
}
-void
-CgiApplicationEngine::write(std::ostream & IO) const
-{
- HttpHeaderPtr header = currentStage->getHeader();
- if (!sessionID.is_nil()) {
- header->setCookie(cgicc::HTTPCookie(SESSIONID, sessionID.str(), "Session ID",
- _env->getServerName().substr(_env->getServerName().find(".")), 3600, "/", false));
- }
- header->render(IO);
- xmlOutputBufferPtr out = xmlOutputBufferCreateIO(
- xmlWrite, NULL, &IO, xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8));
- xmlSaveFileTo(out, currentStage->getDataDocument()->cobj(), "utf-8");
- sessionsContainer->CleanUp();
-#ifndef NDEBUG
- if (!_env->dumpdatadoc.empty()) {
- currentStage->getDataDocument()->write_to_file_formatted(_env->dumpdatadoc);
- }
-#endif
-}
+class TransformXmlToHttpStream : public TransformImpl<xmlpp::Document, ostreamWrapper> {
+ public:
+ void transform(const xmlpp::Document * doc, ostreamWrapper * o) const
+ {
+ const_cast<xmlpp::Document *>(doc)->write_to_stream_formatted(o->strm, "UTF-8");
+ }
+};
+DECLARE_TRANSFORM(TransformXmlToHttpStream);
void
CgiApplicationEngine::process() const
@@ -75,34 +58,56 @@ CgiApplicationEngine::process() const
startTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
bool triedNotFound = false;
bool triedOnError = false;
- StagePtr nextStage;
do {
try {
- nextStage = currentStage->run();
+ currentStage = currentStage.get<0>()->run();
+ }
+ catch (const CheckHost::CheckFailure & cf) {
+ currentStage = NextStage(new PresentStage(_env, cf.failedCheck->present));
}
catch (const XmlScriptParser::NotFound & nf) {
if (_env->notFoundPresent.empty() || triedNotFound) {
- nextStage = new DefaultNotFoundStage(_env, nf);
+ currentStage = NextStage(new DefaultNotFoundStage(_env, nf));
}
else {
triedNotFound = true;
- nextStage = new CustomNotFoundStage(_env, nf);
+ currentStage = NextStage(new CustomNotFoundStage(_env, nf));
}
}
catch (const std::exception & ex) {
if (_env->onErrorPresent.empty() || triedOnError) {
- nextStage = new DefaultErrorStage(_env, ex);
+ currentStage = NextStage(new DefaultErrorStage(_env, ex));
}
else {
triedNotFound = true;
- nextStage = new CustomErrorStage(_env, ex);
+ currentStage = NextStage(new CustomErrorStage(_env, ex));
}
}
- } while (nextStage && (currentStage = nextStage));
+ } while (currentStage.get<0>());
endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
- PresenterPtr p = boost::dynamic_pointer_cast<Presenter>(currentStage);
- if (p) {
- addAppData(p.get());
+ ResponseStagePtr rs = currentStage.get<1>();
+ if (currentStage.get<3>()) {
+ addAppData(currentStage.get<3>().get());
+ 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(".")), 3600, "/", false));
+ }
+ header->render(IO);
+ if (currentStage.get<2>()) {
+ TransformSourcePtr ts = currentStage.get<2>();
+ std::fstream * ddd = NULL;
+ if (!_env->dumpdatadoc.empty()) {
+ ddd = new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out);
+ ts->addTarget(new ostreamWrapper(*ddd));
+ }
+ ts->addTarget(new ostreamWrapper(IO));
+ ts->doTransforms();
+ if (ddd) {
+ delete ddd;
+ }
}
}
@@ -115,18 +120,6 @@ CgiApplicationEngine::Stage::~Stage()
{
}
-CgiApplicationEngine::HttpHeaderPtr
-CgiApplicationEngine::Stage::getHeader() const
-{
- return CgiApplicationEngine::HttpHeaderPtr();
-}
-
-CgiApplicationEngine::XmlDocPtr
-CgiApplicationEngine::Stage::getDataDocument() const
-{
- return XmlDocPtr();
-}
-
void
CgiApplicationEngine::addEnvData(const Presenter * p) const
{
diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h
index 78f796f..e2ad1a2 100644
--- a/project2/cgi/cgiAppEngine.h
+++ b/project2/cgi/cgiAppEngine.h
@@ -4,11 +4,14 @@
#include "../appEngine.h"
#include "../task.h"
#include "../paramChecker.h"
-#include "../xmlPresenter.h"
#include "../commonObjects.h"
#include "../uuid.h"
-#include "../requestHost.h"
+#include "../taskHost.h"
+#include "../viewHost.h"
+#include "../transform.h"
+#include "../xmlPresenter.h"
#include <boost/intrusive_ptr.hpp>
+#include <boost/tuple/tuple.hpp>
class CgiEnvironment;
class Session;
@@ -19,16 +22,15 @@ namespace xmlpp {
class Document;
}
-class CgiApplicationEngine : public ApplicationEngine {
+class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink {
public:
typedef boost::shared_ptr<xmlpp::Document> XmlDocPtr;
typedef boost::shared_ptr<cgicc::HTTPHeader> HttpHeaderPtr;
- CgiApplicationEngine(const CgiEnvironment *);
+ CgiApplicationEngine(const CgiEnvironment *, std::ostream &);
virtual ~CgiApplicationEngine();
void process() const;
- void write(std::ostream &) const;
const Environment * env() const;
SessionPtr session() const;
virtual Glib::ustring resolveCurrentConfig() const;
@@ -45,115 +47,103 @@ class CgiApplicationEngine : public ApplicationEngine {
bool checkDomain(const DomainPlatforms::value_type & i) const;
void loadEngineSection(const xmlpp::Element *) const;
+ public:
class Stage;
+ class ResponseStage;
typedef boost::intrusive_ptr<Stage> StagePtr;
+ typedef boost::intrusive_ptr<ResponseStage> ResponseStagePtr;
+ typedef boost::tuple<StagePtr, ResponseStagePtr, TransformSourcePtr, PresenterPtr> NextStage;
/// Base class for a stage iteration that should eventually produce a response for the client
- class Stage : public virtual CommonObjects {
+ class Stage : public virtual IntrusivePtrBase {
public:
Stage(const CgiEnvironment * e);
virtual ~Stage() = 0;
- virtual StagePtr run() = 0;
- virtual XmlDocPtr getDataDocument() const;
- virtual HttpHeaderPtr getHeader() const;
+ virtual NextStage run() = 0;
protected:
const CgiEnvironment * e;
};
+ /// Base class for a stage that can be a response to the client
+ class ResponseStage : public Stage {
+ public:
+ ResponseStage(const CgiEnvironment * e);
+ virtual HttpHeaderPtr getHeader() const = 0;
+ };
+
/// 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();
+ virtual NextStage run();
};
/// Stage to process POST requests
- class RequestStage : public Stage, public XmlPresenter, RequestHost {
+ class RequestStage : public ResponseStage, TaskHost {
public:
RequestStage(const CgiEnvironment *, const std::string & id);
- virtual StagePtr run();
- virtual XmlDocPtr getDataDocument() const;
+ virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
- virtual const Glib::ustring & getResponseRootNodeName() const;
- virtual const Glib::ustring & getResponseStyle() const;
-
protected:
std::string present;
- typedef Storage<ParamChecker>::Objects ParamCheckers;
- ParamCheckers parameterChecks;
-
- private:
- static const Glib::ustring resp;
- static const Glib::ustring style;
};
/// Stage to process GET requests and follow up RequestStages
- class PresentStage : public virtual Stage, public XmlProcessPresenter {
+ class PresentStage : public virtual ResponseStage, ViewHost {
public:
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 NextStage run();
virtual HttpHeaderPtr getHeader() const;
};
/// The built-in fail-safe not found stage
- class DefaultNotFoundStage : public virtual Stage, public XmlPresenter {
+ class DefaultNotFoundStage : public virtual ResponseStage {
public:
DefaultNotFoundStage(const CgiEnvironment *, const XmlScriptParser::NotFound &);
- virtual XmlDocPtr getDataDocument() const;
+ virtual NextStage run();
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 XmlScriptParser::NotFound nf;
+ XmlPresenterPtr pres;
};
/// 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;
+ CustomNotFoundStage(const CgiEnvironment *, const ::XmlScriptParser::NotFound &);
+ virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
- virtual const Glib::ustring & getResponseRootNodeName() const;
- virtual const Glib::ustring & getResponseStyle() const;
};
/// The built-in fail-safe unhandled error stage
- class DefaultErrorStage : public virtual Stage, public XmlPresenter {
+ class DefaultErrorStage : public virtual ResponseStage {
public:
DefaultErrorStage(const CgiEnvironment *, const std::exception &);
~DefaultErrorStage();
- virtual XmlDocPtr getDataDocument() const;
+ virtual NextStage run();
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;
char * buf;
std::string what;
+ XmlPresenterPtr pres;
};
/// Custom unhandled error handling stage
class CustomErrorStage : public DefaultErrorStage, public PresentStage {
public:
CustomErrorStage(const CgiEnvironment *, const std::exception &);
- virtual StagePtr run();
- virtual XmlDocPtr getDataDocument() const;
+ virtual NextStage run();
virtual HttpHeaderPtr getHeader() const;
- virtual const Glib::ustring & getResponseRootNodeName() const;
- virtual const Glib::ustring & getResponseStyle() const;
};
- mutable StagePtr currentStage;
+ private:
+ mutable NextStage currentStage;
mutable UUID sessionID;
+ mutable std::ostream & IO;
};
#endif
diff --git a/project2/cgi/cgiCommon.cpp b/project2/cgi/cgiCommon.cpp
index fa40d2b..b8a2b93 100644
--- a/project2/cgi/cgiCommon.cpp
+++ b/project2/cgi/cgiCommon.cpp
@@ -44,12 +44,10 @@ cgiServe(cgicc::CgiInput * i, std::ostream & IO)
CgiEnvironment env(&cgi);
env.init();
try {
- CgiApplicationEngine app(&env);
+ CgiApplicationEngine app(&env, IO);
Logger()->messagef(LOG_DEBUG, "%s: Processing request", __FUNCTION__);
app.process();
- Logger()->messagef(LOG_DEBUG, "%s: Sending request result", __FUNCTION__);
- app.write(IO);
Logger()->messagef(LOG_DEBUG, "%s: Completed request", __FUNCTION__);
}
catch (const std::exception & e) {
diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp
index e8d5ba3..2bc3b02 100644
--- a/project2/cgi/cgiEnvironment.cpp
+++ b/project2/cgi/cgiEnvironment.cpp
@@ -28,6 +28,8 @@ CgiEnvironment::addOptions(boost::program_options::positional_options_descriptio
{
boost::program_options::options_description cgi("Project2 CGI options");
cgi.add_options()
+ ("defaultpresenter", boost::program_options::value(&defaultPresenter)->default_value("xml"),
+ "The default engine for formatting presentations")
("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"),
@@ -44,10 +46,8 @@ CgiEnvironment::addOptions(boost::program_options::positional_options_descriptio
"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")
-#endif
;
return cgi;
}
diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h
index ce765bf..abfe78e 100644
--- a/project2/cgi/cgiEnvironment.h
+++ b/project2/cgi/cgiEnvironment.h
@@ -27,9 +27,7 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment {
boost::program_options::options_description addOptions(boost::program_options::positional_options_description &);
void postinit(const boost::program_options::options_description &, const boost::program_options::variables_map &);
public:
-#ifndef NDEBUG
std::string dumpdatadoc;
-#endif
Glib::ustring errorContentType;
Glib::ustring errorTransformStyle;
std::string defaultPresent;
@@ -38,6 +36,7 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment {
std::string errorPresentRoot;
std::string notFoundPresent;
std::string onErrorPresent;
+ std::string defaultPresenter;
};
#endif
diff --git a/project2/cgi/cgiStageCustomError.cpp b/project2/cgi/cgiStageCustomError.cpp
index a3fbc1f..fb2f0de 100644
--- a/project2/cgi/cgiStageCustomError.cpp
+++ b/project2/cgi/cgiStageCustomError.cpp
@@ -4,7 +4,9 @@
#include "../logger.h"
CgiApplicationEngine::CustomErrorStage::CustomErrorStage(const CgiEnvironment * env, const std::exception & ex) :
- CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::ResponseStage(env),
+ ::XmlScriptParser(env->errorPresentRoot, env->onErrorPresent, false),
+ ::CheckHost(env->errorPresentRoot, env->onErrorPresent),
CgiApplicationEngine::DefaultErrorStage(env, ex),
CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->onErrorPresent)
{
@@ -16,29 +18,10 @@ CgiApplicationEngine::CustomErrorStage::getHeader() const
return CgiApplicationEngine::DefaultErrorStage::getHeader();
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
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
index a2d33dc..7c08a9f 100644
--- a/project2/cgi/cgiStageCustomNotFound.cpp
+++ b/project2/cgi/cgiStageCustomNotFound.cpp
@@ -3,8 +3,10 @@
#include "cgiHttpHeader.h"
#include "../logger.h"
-CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
- CgiApplicationEngine::Stage(env),
+CgiApplicationEngine::CustomNotFoundStage::CustomNotFoundStage(const CgiEnvironment * env, const ::XmlScriptParser::NotFound & notfound) :
+ CgiApplicationEngine::ResponseStage(env),
+ ::XmlScriptParser(env->errorPresentRoot, env->notFoundPresent, false),
+ ::CheckHost(env->errorPresentRoot, env->notFoundPresent),
CgiApplicationEngine::DefaultNotFoundStage(env, notfound),
CgiApplicationEngine::PresentStage(env, env->errorPresentRoot, env->notFoundPresent)
{
@@ -16,28 +18,10 @@ CgiApplicationEngine::CustomNotFoundStage::getHeader() const
return CgiApplicationEngine::DefaultNotFoundStage::getHeader();
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
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
index c881da1..767a634 100644
--- a/project2/cgi/cgiStageDefaultError.cpp
+++ b/project2/cgi/cgiStageDefaultError.cpp
@@ -4,12 +4,13 @@
#include "cgiEnvironment.h"
#include <cxxabi.h>
-const Glib::ustring CgiApplicationEngine::DefaultErrorStage::resp("error");
+static const Glib::ustring DefaultErrorStageResp("error");
CgiApplicationEngine::DefaultErrorStage::DefaultErrorStage(const CgiEnvironment * env, const std::exception & ex) :
- CgiApplicationEngine::Stage(env),
+ CgiApplicationEngine::ResponseStage(env),
buf(__cxxabiv1::__cxa_demangle(typeid(ex).name(), NULL, NULL, NULL)),
- what(ex.what())
+ what(ex.what()),
+ pres(new XmlPresenter(DefaultErrorStageResp, e->errorTransformStyle, e->errorContentType))
{
}
@@ -21,32 +22,14 @@ CgiApplicationEngine::DefaultErrorStage::~DefaultErrorStage()
CgiApplicationEngine::HttpHeaderPtr
CgiApplicationEngine::DefaultErrorStage::getHeader() const
{
- return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", e->errorContentType));
+ return HttpHeaderPtr(new Project2HttpHeader("500 Internal Server Error", pres->contentType));
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
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;
+ pres->addField("error-type", e->getXmlPrefix(), buf);
+ pres->addField("error-what", e->getXmlPrefix(), what.c_str());
+ return NextStage(NULL, this, pres.get(), pres.get());
}
diff --git a/project2/cgi/cgiStageDefaultNotFound.cpp b/project2/cgi/cgiStageDefaultNotFound.cpp
index f32ad1f..2e7acb1 100644
--- a/project2/cgi/cgiStageDefaultNotFound.cpp
+++ b/project2/cgi/cgiStageDefaultNotFound.cpp
@@ -3,9 +3,12 @@
#include "cgiHttpHeader.h"
#include "../logger.h"
+static const Glib::ustring DefaultNotFoundStageResp("notfound");
+
CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnvironment * env, const XmlScriptParser::NotFound & notfound) :
- CgiApplicationEngine::Stage(env),
- nf(notfound)
+ CgiApplicationEngine::ResponseStage(env),
+ nf(notfound),
+ pres(new XmlPresenter(DefaultNotFoundStageResp, e->errorTransformStyle, e->errorContentType))
{
Logger()->messagef(LOG_ERR, "%s: Resource not found: %s", __FUNCTION__, nf.what());
}
@@ -13,32 +16,13 @@ CgiApplicationEngine::DefaultNotFoundStage::DefaultNotFoundStage(const CgiEnviro
CgiApplicationEngine::HttpHeaderPtr
CgiApplicationEngine::DefaultNotFoundStage::getHeader() const
{
- return HttpHeaderPtr(new Project2HttpHeader("404 Not found", e->errorContentType));
+ return HttpHeaderPtr(new Project2HttpHeader("404 Not found", pres->contentType));
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
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;
+ pres->addField("missing-resource", e->getXmlPrefix(), nf.what());
+ return NextStage(NULL, this, pres.get(), pres.get());
}
diff --git a/project2/cgi/cgiStageInitial.cpp b/project2/cgi/cgiStageInitial.cpp
index d302971..1db8f8f 100644
--- a/project2/cgi/cgiStageInitial.cpp
+++ b/project2/cgi/cgiStageInitial.cpp
@@ -9,17 +9,17 @@ CgiApplicationEngine::InitialStage::InitialStage(const CgiEnvironment * env) :
{
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
CgiApplicationEngine::InitialStage::run()
{
if (e->getRequestMethod() == "POST") {
if (e->elems.empty()) {
throw EmptyRequestURL();
}
- return new RequestStage(e, e->elems[0]);
+ return NextStage(new RequestStage(e, e->elems[0]));
}
else {
- return new PresentStage(e, e->elems.empty() ? e->defaultPresent : e->elems[0]);
+ return NextStage(new PresentStage(e, e->elems.empty() ? e->defaultPresent : e->elems[0]));
}
}
diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp
index 47db567..aaa1092 100644
--- a/project2/cgi/cgiStagePresent.cpp
+++ b/project2/cgi/cgiStagePresent.cpp
@@ -2,44 +2,45 @@
#include "cgiEnvironment.h"
#include "cgiHttpHeader.h"
#include <boost/foreach.hpp>
+#include <boost/bind.hpp>
CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & id) :
- CgiApplicationEngine::Stage(e),
- XmlProcessPresenter(e->presentRoot, id, false)
+ CgiApplicationEngine::ResponseStage(e),
+ XmlScriptParser(e->presentRoot, id, false),
+ CheckHost(e->presentRoot, id),
+ ViewHost(e->presentRoot, id)
{
+ parseDocument();
}
CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, const std::string & group, const std::string & id) :
- CgiApplicationEngine::Stage(e),
- XmlProcessPresenter(group, id, false)
+ CgiApplicationEngine::ResponseStage(e),
+ XmlScriptParser(group, id, false),
+ CheckHost(group, id),
+ ViewHost(group, id)
{
+ parseDocument();
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
CgiApplicationEngine::PresentStage::run()
{
- BOOST_FOREACH(ParamCheckers::value_type pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message());
- return new PresentStage(e, pc->present);
- }
- }
- execute();
- return NULL;
+ runChecks();
+ executeViews(boost::bind(&PresenterLoader::createFrom, LoaderBase::getLoader<PresenterLoader, NotSupported>(e->defaultPresenter), _1));
+ return NextStage(NULL, this, boost::dynamic_pointer_cast<TransformSource>(headPresenter()), headPresenter());
+}
+
+CgiApplicationEngine::ResponseStage::ResponseStage(const CgiEnvironment * e) :
+ CgiApplicationEngine::Stage(e)
+{
}
CgiApplicationEngine::HttpHeaderPtr
CgiApplicationEngine::PresentStage::getHeader() const
{
- Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
+ ContentPresenter * cp = boost::dynamic_pointer_cast<ContentPresenter>(headPresenter()).get();
+ Project2HttpHeader * header = new Project2HttpHeader("200 OK", cp ? cp->contentType : "text/plain");
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
index 22cb2e8..94f3b49 100644
--- a/project2/cgi/cgiStageRequest.cpp
+++ b/project2/cgi/cgiStageRequest.cpp
@@ -5,57 +5,32 @@
#include <boost/foreach.hpp>
CgiApplicationEngine::RequestStage::RequestStage(const CgiEnvironment * e, const std::string & id) :
- CgiApplicationEngine::Stage(e)
+ XmlScriptParser(e->requestRoot, id, false),
+ ::CheckHost(e->requestRoot, id),
+ CgiApplicationEngine::ResponseStage(e),
+ ::TaskHost(e->requestRoot, id)
{
- XmlScriptParser request(e->requestRoot, id, false);
- xmlpp::Element * requestRoot = request.get_document()->get_root_node();
+ xmlpp::Element * requestRoot = 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(true);
- loader.supportedStorers.insert(Storer::into(&parameterChecks));
- loader.supportedStorers.insert(Storer::into(&rowSets));
- loader.supportedStorers.insert(new NOEErrorStorer(&normTasks, &errorTasks));
- loader.collectAll(this, requestRoot, true);
+ parseDocument();
}
-CgiApplicationEngine::StagePtr
+CgiApplicationEngine::NextStage
CgiApplicationEngine::RequestStage::run()
{
- BOOST_FOREACH(const ParamCheckers::value_type & pc, parameterChecks.get<bySOOrder>()) {
- if (!pc->performCheck()) {
- ApplicationEngine::getCurrent()->logMessage(false, pc->group(), pc->message());
- return new PresentStage(e, pc->present);
- }
- }
- RequestHost::run();
- return present.empty() ? NULL : new PresentStage(e, present);
+ runChecks();
+ executeTasks();
+ return NextStage(present.empty() ? NULL : new PresentStage(e, present), this);
}
+const std::string contentType = "text/plain";
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;
+ Project2HttpHeader * header = new Project2HttpHeader("200 OK", contentType);
+ header->addHeader("Cache-control", "no-cache");
+ return HttpHeaderPtr(header);
}
-const Glib::ustring &
-CgiApplicationEngine::RequestStage::getResponseStyle() const
-{
- return style;
-}
-
diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp
new file mode 100644
index 0000000..438e1b0
--- /dev/null
+++ b/project2/cgi/testCgi.cpp
@@ -0,0 +1,70 @@
+#include <iostream>
+#include <boost/program_options.hpp>
+#include <boost/filesystem/convenience.hpp>
+#include "cgiCommon.h"
+
+namespace po = boost::program_options;
+
+class TestInput : public cgicc::CgiInput {
+ public:
+ TestInput(int argc, char ** argv)
+ {
+ po::options_description test("Project2 CGI test options");
+ test.add_options()
+ ("help,h", "Print usage and exit")
+ ("SERVER_NAME", "FQDN of web service")
+ ("SERVER_SOFTWARE", po::value<std::string>()->default_value("Apache"), "")
+ ("GATEWAY_INTERFACE", po::value<std::string>()->default_value("CGI/1.1"), "")
+ ("SERVER_PROTOCOL", po::value<std::string>()->default_value("HTTP/1.1"), "")
+ ("SERVER_PORT", po::value<std::string>()->default_value("80"), "")
+ ("REQUEST_METHOD", po::value<std::string>()->default_value("GET"), "")
+ ("PATH_INFO", "")
+ ("PATH_TRANSLATED", "")
+ ("SCRIPT_NAME", po::value<std::string>()->default_value("p2fcgi"), "")
+ ("QUERY_STRING", "")
+ ("REMOTE_HOST", "")
+ ("REMOTE_ADDR", "")
+ ("AUTH_TYPE", "")
+ ("REMOTE_USER", "")
+ ("REMOTE_IDENT", "")
+ ("CONTENT_TYPE", "")
+ ("CONTENT_LENGTH", "")
+ ("HTTP_ACCEPT", po::value<std::string>()->default_value("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), "")
+ ("HTTP_USER_AGENT", po::value<std::string>()->default_value("Mozilla/5.0"), "")
+ ("REDIRECT_REQUEST", "")
+ ("REDIRECT_URL", "")
+ ("REDIRECT_STATUS", "")
+ ("HTTP_REFERER", "")
+ ("HTTP_COOKIE", "")
+ ("HTTPS", po::value<std::string>()->default_value("No"), "")
+ ;
+ po::parsed_options parsed = po::command_line_parser(argc, argv).options(test).allow_unregistered().run();
+ po::store(parsed, settings);
+ if (boost::filesystem::exists("testCgi.settings")) {
+ std::ifstream f("testCgi.settings");
+ po::store(po::parse_config_file(f, test, true), settings);
+ }
+ po::notify(settings);
+ if (settings.count("help")) {
+ std::cout << test;
+ exit(1);
+ }
+ }
+ virtual std::string getenv(const char *varName)
+ {
+ if (settings.count(varName)) {
+ return settings[varName].as<std::string>();
+ }
+ return "";
+ }
+ private:
+ po::variables_map settings;
+};
+
+int
+main(int argc, char ** argv)
+{
+ TestInput ti(argc, argv);
+ cgiServe(&ti, std::cout);
+}
+