diff options
author | randomdan <randomdan@localhost> | 2011-12-08 16:46:11 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-12-08 16:46:11 +0000 |
commit | c9990b16272d9c9a55f1f7be1fdef5b625ad27aa (patch) | |
tree | 15b804e78d42233d736351569ec893280d1d7a5f /project2/cgi | |
parent | Send the expiry time to CouchDB when deleting old sessions (it's time seems o... (diff) | |
download | project2-c9990b16272d9c9a55f1f7be1fdef5b625ad27aa.tar.bz2 project2-c9990b16272d9c9a55f1f7be1fdef5b625ad27aa.tar.xz project2-c9990b16272d9c9a55f1f7be1fdef5b625ad27aa.zip |
Drop Boost::program_options in favour of our own, pluggable system which integrates application platforms properly
Diffstat (limited to 'project2/cgi')
-rw-r--r-- | project2/cgi/Jamfile.jam | 3 | ||||
-rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 26 | ||||
-rw-r--r-- | project2/cgi/cgiAppEngine.h | 5 | ||||
-rw-r--r-- | project2/cgi/cgiCommon.cpp | 2 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.cpp | 94 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.h | 18 | ||||
-rw-r--r-- | project2/cgi/cgiOutputOptions.cpp | 18 | ||||
-rw-r--r-- | project2/cgi/cgiOutputOptions.h | 7 | ||||
-rw-r--r-- | project2/cgi/cgiStageFail.cpp | 1 | ||||
-rw-r--r-- | project2/cgi/pch.hpp | 2 | ||||
-rw-r--r-- | project2/cgi/testCgi.cpp | 105 |
11 files changed, 151 insertions, 130 deletions
diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index 261e992..48225cb 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -2,7 +2,6 @@ alias libxmlpp : : : : <cflags>"`pkg-config --cflags libxml++-2.6`" <linkflags>"`pkg-config --libs libxml++-2.6`" ; lib boost_filesystem : : <name>boost_filesystem ; -lib boost_program_options : : <name>boost_program_options ; lib cgicc : : <name>cgicc ; lib fcgi : : <name>fcgi ; lib fcgi++ : : <name>fcgi++ ; @@ -12,7 +11,6 @@ cpp-pch pch : pch.hpp : <library>cgicc <library>libxmlpp <library>../common//p2common - <library>boost_program_options <library>boost_filesystem <library>../xml//p2xml ; @@ -24,7 +22,6 @@ lib p2web : <library>cgicc <library>libxmlpp <library>../common//p2common - <library>boost_program_options <library>boost_filesystem <library>../xml//p2xml : : diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 779b25a..7fd7c33 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -9,7 +9,6 @@ #include <boost/foreach.hpp> #include "ostreamWrapper.h" #include <boost/date_time/microsec_time_clock.hpp> -#include <glibmm/regex.h> const std::string SESSIONID = "sessionID"; typedef UUID SIDKey; @@ -27,7 +26,6 @@ getSessionID(const std::vector<cgicc::HTTPCookie> & cookies) { 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) @@ -200,27 +198,3 @@ CgiApplicationEngine::session() const return cursession; } -bool -CgiApplicationEngine::checkDomain(const DomainPlatforms::value_type & i) const -{ - Glib::RefPtr<Glib::Regex> reg = Glib::Regex::create(i.first, Glib::REGEX_CASELESS | Glib::REGEX_DOTALL); - return reg->match(_env->getServerName()); -} - -Glib::ustring -CgiApplicationEngine::resolveCurrentConfig() const -{ - DomainPlatforms::const_iterator i = std::find_if(domplat.begin(), domplat.end(), boost::bind(&CgiApplicationEngine::checkDomain, this, _1)); - if (i != domplat.end()) { - return i->second; - } - throw UnknownDomain(_env->getServerName()); -} - -void -CgiApplicationEngine::loadEngineSection(const xmlpp::Element * e) const -{ - domplat.push_back(DomainPlatforms::value_type(e->get_attribute_value("name"), e->get_attribute_value("platform"))); -} - - diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index e837b9d..25d3b93 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -36,7 +36,6 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink void process() const; const Environment * env() const; SessionPtr session() const; - virtual Glib::ustring resolveCurrentConfig() const; void addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr) const; void addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr) const; const CgiEnvironment * _env; @@ -44,10 +43,6 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink private: mutable boost::posix_time::ptime startTime; mutable boost::posix_time::ptime endTime; - typedef std::pair<Glib::ustring, Glib::ustring> DomainPlatform; - typedef std::list<DomainPlatform> DomainPlatforms; - mutable DomainPlatforms domplat; - bool checkDomain(const DomainPlatforms::value_type & i) const; void loadEngineSection(const xmlpp::Element *) const; SessionContainerPtr sessionsContainer; // Helpers diff --git a/project2/cgi/cgiCommon.cpp b/project2/cgi/cgiCommon.cpp index 579e3f4..3664e9f 100644 --- a/project2/cgi/cgiCommon.cpp +++ b/project2/cgi/cgiCommon.cpp @@ -34,7 +34,7 @@ doExceptionReporting(const E & e, std::ostream & IO) IO << "Kaboom!" << std::endl << std::endl << buf << std::endl - << e.what() << std::endl; + << "what '" << e.what() << "'" << std::endl; free(buf); } diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp index 541e7ae..ae7ad52 100644 --- a/project2/cgi/cgiEnvironment.cpp +++ b/project2/cgi/cgiEnvironment.cpp @@ -1,9 +1,11 @@ #include <pch.hpp> +#include <boost/version.hpp> #include "cgiEnvironment.h" #include "appEngine.h" #include "exceptions.h" #include <map> #include <cgicc/Cgicc.h> +#include <glibmm/regex.h> std::vector<std::string> makeVector(const boost::filesystem::path & y) @@ -22,53 +24,56 @@ makeVector(const boost::filesystem::path & y) } CgiEnvironment::CgiEnvironment(cgicc::Cgicc * c) : - Environment(0, NULL), cgicc::CgiEnvironment(c->getEnvironment()), elems(makeVector(boost::filesystem::path(getRedirectURL()))), - cgi(c) + cgi(c), + cgiOptions("Project2 CGI options"), + hpi(new HostnamePlatformIdentifier()) { -} - -CgiEnvironment::~CgiEnvironment() -{ -} - -boost::program_options::options_description -CgiEnvironment::addOptions(boost::program_options::positional_options_description &) -{ - boost::program_options::options_description cgi("Project2 CGI options"); - cgi.add_options() - ("defaultpresenter", boost::program_options::value(&defaultPresenter)->default_value("xml"), + cgiOptions + ("cgi.defaultPresenter", Options::value(&defaultPresenter, "xml"), "The default engine for formatting presentations") - ("defaultpresent", boost::program_options::value(&defaultPresent)->default_value("index"), + ("cgi.defaultPresent", Options::value(&defaultPresent, "index"), "The present script to use when no other is specified") - ("presentroot", boost::program_options::value(&presentRoot)->default_value("present"), + ("cgi.presentRoot", Options::value(&presentRoot, "present"), "The folder in which to find presentation scripts") - ("requestroot", boost::program_options::value(&requestRoot)->default_value("request"), + ("cgi.requestRoot", Options::value(&requestRoot, "request"), "The folder in which to find request scripts") - ("errorpresentroot", boost::program_options::value(&errorPresentRoot)->default_value("error"), + ("cgi.errorPresentRoot", Options::value(&errorPresentRoot, "error"), "The folder in which to find presentation scripts for error handling") - ("errorcontenttype", boost::program_options::value(&errorContentType)->default_value("text/xml"), + ("cgi.errorContentType", Options::value(&errorContentType, "text/xml"), "The Content-Type to use in HTTP headers in event of an error") - ("errortransformstyle", boost::program_options::value(&errorTransformStyle), + ("cgi.errorTransformStyle", Options::value(&errorTransformStyle), "The xml-stylesheet to specify in the data document in event of an error") - ("notfoundpresent", boost::program_options::value(¬FoundPresent), + ("cgi.notFoundPresent", Options::value(¬FoundPresent), "The present script to use when the requested script does not exist") - ("onerrorpresent", boost::program_options::value(&onErrorPresent), + ("cgi.onErrorPresent", Options::value(&onErrorPresent), "The present script to use when the requested script (or child) fails") - ("dumpdatadoc", boost::program_options::value(&dumpdatadoc), + ("cgi.dumpDataDoc", Options::value(&dumpdatadoc), "Write a copy of the data document before sending it to the web server") - ("sessionModule", boost::program_options::value(&sessionModule)->default_value("xml"), + ("cgi.sessionModule", Options::value(&sessionModule, "xml"), "The module with which to implement session management") + ("cgi.hostRegex", hpi, + "Regular expression used to define a hostname -> platform association") ; - return cgi; } -void -CgiEnvironment::postinit(const boost::program_options::options_description &, const boost::program_options::variables_map &) +const Options & +CgiEnvironment::engineOptions() const { + return cgiOptions; +} + +CgiEnvironment::~CgiEnvironment() +{ +} + +const Glib::ustring & +CgiEnvironment::platform() const { + return hpi->derivedPlatform(); } + Glib::ustring CgiEnvironment::getParamUri(unsigned int p) const { @@ -88,3 +93,38 @@ CgiEnvironment::getParamQuery(const std::string & p) const return (*cgi)(p); } +HostnamePlatformIdentifier::HostnamePlatformIdentifier() : + platform(NULL) +{ +} + +HostnamePlatformIdentifier::~HostnamePlatformIdentifier() +{ + reset(); +} + +const Glib::ustring & +HostnamePlatformIdentifier::derivedPlatform() const +{ + if (platform) { + return *platform; + } + throw NoSuchPlatform(Environment::getCurrent()->getServerName()); +} + +void +HostnamePlatformIdentifier::reset() const +{ + if (platform) { + delete platform; + } +} + +void +HostnamePlatformIdentifier::consume(const Glib::ustring & p, const Glib::ustring & r) const +{ + if (!platform && Glib::Regex::create(r, Glib::REGEX_CASELESS | Glib::REGEX_DOTALL)->match(Environment::getCurrent()->getServerName())) { + platform = new Glib::ustring(p); + } +} + diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h index fe99f5e..654f772 100644 --- a/project2/cgi/cgiEnvironment.h +++ b/project2/cgi/cgiEnvironment.h @@ -10,6 +10,17 @@ namespace cgicc { class Cgicc; } +class HostnamePlatformIdentifier : public Options::Target { + public: + HostnamePlatformIdentifier(); + virtual ~HostnamePlatformIdentifier(); + void reset() const; + void consume(const Glib::ustring &, const Glib::ustring &) const; + const Glib::ustring & derivedPlatform() const; + private: + mutable Glib::ustring * platform; +}; + class CgiEnvironment : public Environment, public cgicc::CgiEnvironment { public: CgiEnvironment(cgicc::Cgicc *); @@ -24,8 +35,11 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment { const cgicc::Cgicc * const cgi; private: - 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 &); + const Options & engineOptions() const; + const Glib::ustring & platform() const; + Options cgiOptions; + boost::intrusive_ptr<HostnamePlatformIdentifier> hpi; + public: std::string dumpdatadoc; Glib::ustring errorContentType; diff --git a/project2/cgi/cgiOutputOptions.cpp b/project2/cgi/cgiOutputOptions.cpp index eb07b25..add1671 100644 --- a/project2/cgi/cgiOutputOptions.cpp +++ b/project2/cgi/cgiOutputOptions.cpp @@ -20,13 +20,13 @@ OutputOptions::OutputOptions(const xmlpp::Element * p) : OutputOptionsLoader::OutputOptionsLoader() : opts("CGI default output options") { - opts.add_options() - ("cgi.output.core", po::value(&OutputOptions::core)->default_value(true), "Core messages") - ("cgi.output.session", po::value(&OutputOptions::core)->default_value(true), "Session values") - ("cgi.output.timing", po::value(&OutputOptions::core)->default_value(true), "Timing") - ("cgi.output.environment", po::value(&OutputOptions::core)->default_value(true), "Environment") - ("cgi.output.url", po::value(&OutputOptions::core)->default_value(true), "URL breakdown") - ("cgi.output.parameters", po::value(&OutputOptions::core)->default_value(true), "Parameters") + opts + ("cgi.output.core", Options::value(&OutputOptions::core, true), "Core messages") + ("cgi.output.session", Options::value(&OutputOptions::core, true), "Session values") + ("cgi.output.timing", Options::value(&OutputOptions::core, true), "Timing") + ("cgi.output.environment", Options::value(&OutputOptions::core, true), "Environment") + ("cgi.output.url", Options::value(&OutputOptions::core, true), "URL breakdown") + ("cgi.output.parameters", Options::value(&OutputOptions::core, true), "Parameters") ; } @@ -35,8 +35,8 @@ OutputOptionsLoader::createFrom(const xmlpp::Element * e) const { return new OutputOptions(e); } -po::options_description * -OutputOptionsLoader::options() +const Options * +OutputOptionsLoader::options() const { return &opts; } diff --git a/project2/cgi/cgiOutputOptions.h b/project2/cgi/cgiOutputOptions.h index 540764e..a1ff62d 100644 --- a/project2/cgi/cgiOutputOptions.h +++ b/project2/cgi/cgiOutputOptions.h @@ -2,7 +2,7 @@ #define OUTPUTOPTIONS_H #include "intrusivePtrBase.h" -#include <boost/program_options.hpp> +#include "options.h" #include "variables.h" namespace xmlpp { @@ -32,15 +32,14 @@ class OutputOptions : public IntrusivePtrBase { }; typedef boost::intrusive_ptr<OutputOptions> OutputOptionsPtr; -namespace po = boost::program_options; class OutputOptionsLoader : public ComponentLoader { public: OutputOptionsLoader(); OutputOptionsPtr createFrom(const xmlpp::Element * e) const; - po::options_description * options(); + const Options * options() const; private: - po::options_description opts; + Options opts; }; #endif diff --git a/project2/cgi/cgiStageFail.cpp b/project2/cgi/cgiStageFail.cpp index 97ac22a..87aba66 100644 --- a/project2/cgi/cgiStageFail.cpp +++ b/project2/cgi/cgiStageFail.cpp @@ -1,4 +1,5 @@ #include <pch.hpp> +#include <boost/lexical_cast.hpp> #include "cgiAppEngine.h" #include "cgiEnvironment.h" #include "cgiHttpHeader.h" diff --git a/project2/cgi/pch.hpp b/project2/cgi/pch.hpp index b3c7108..ff0b175 100644 --- a/project2/cgi/pch.hpp +++ b/project2/cgi/pch.hpp @@ -13,7 +13,7 @@ #include "xmlObjectLoader.h" #include <boost/bind.hpp> #include <boost/foreach.hpp> -#include <boost/program_options.hpp> +#include "options.h" #include <cgicc/CgiEnvironment.h> #include <cgicc/Cgicc.h> #include <cgicc/HTTPContentHeader.h> diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index 438e1b0..c2e8d4e 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -1,70 +1,71 @@ #include <iostream> -#include <boost/program_options.hpp> -#include <boost/filesystem/convenience.hpp> +#include <boost/bind.hpp> +#include <map> +#include "options.h" +#include "safeMapFind.h" #include "cgiCommon.h" +#include "../files/optionsSource.h" -namespace po = boost::program_options; - +#define TESTOPT(name, def, desc) \ + (name, Options::value(optStore.insert(OptStore::value_type(name, new std::string())).first->second, def), desc) class TestInput : public cgicc::CgiInput { public: - TestInput(int argc, char ** argv) + typedef std::string * StrPtr; + typedef std::map<std::string, StrPtr> OptStore; + OptStore optStore; + TestInput() : + opts("Project2 CGI test options") { - 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"), "") + opts + TESTOPT("SERVER_NAME", "localhost", "FQDN of web service") + TESTOPT("SERVER_SOFTWARE", "Apache", "Web server version string") + TESTOPT("GATEWAY_INTERFACE", "CGI/1.1", "Web server/script interface version") + TESTOPT("SERVER_PROTOCOL", "HTTP/1.1", "Web server/client interface version") + TESTOPT("SERVER_PORT", "80", "Server Port") + TESTOPT("REQUEST_METHOD", "GET", "Request method") + TESTOPT("PATH_INFO", "", "Path info") + TESTOPT("PATH_TRANSLATED", "", "Path translated") + TESTOPT("SCRIPT_NAME", "p2fcgi", "Script name") + TESTOPT("QUERY_STRING", "", "Query string") + TESTOPT("REMOTE_HOST", "", "Remote host") + TESTOPT("REMOTE_ADDR", "", "Remote address") + TESTOPT("AUTH_TYPE", "", "Authentication type") + TESTOPT("REMOTE_USER", "", "Remote user") + TESTOPT("REMOTE_IDENT", "", "Remote ident") + TESTOPT("CONTENT_TYPE", "", "Content type") + TESTOPT("CONTENT_LENGTH", "", "Content length") + TESTOPT("HTTP_ACCEPT", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accepted MIME types") + TESTOPT("HTTP_USER_AGENT", "Mozilla/5.0", "User agent") + TESTOPT("REDIRECT_REQUEST", "", "Redirect request") + TESTOPT("REDIRECT_URL", "", "Redirect URL") + TESTOPT("REDIRECT_STATUS", "", "Redirect status") + TESTOPT("HTTP_REFERER", "", "Referrer") + TESTOPT("HTTP_COOKIE", "", "Cookie") + TESTOPT("HTTPS", "No", "HTTPS?") ; - 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); - } + FileOptions fo(".testCgi.settings"); + opts.reset(); + fo.loadInto(boost::bind(&Options::consume, &opts, _1, _2, _3)); + } + + const Options * options() const { + return &opts; } - virtual std::string getenv(const char *varName) + + virtual std::string getenv(const char * varName) { - if (settings.count(varName)) { - return settings[varName].as<std::string>(); - } - return ""; + StrPtr def(new std::string()); + return *defaultMapFind(optStore, varName, def); } + private: - po::variables_map settings; + Options opts; }; int -main(int argc, char ** argv) +main(int, char **) { - TestInput ti(argc, argv); + TestInput ti; cgiServe(&ti, std::cout); } |