From eaf0311ca69dc43c31ed2a290c97ba67efd32c83 Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 10 Jul 2013 23:00:44 +0000 Subject: Central various bits of the CGI start up process Move the command line arguments option source into a new cli library Extend testCgi with newly available features --- project2/cgi/Jamfile.jam | 1 + project2/cgi/cgiAppEngine.cpp | 21 ++++---- project2/cgi/cgiAppEngine.h | 6 +-- project2/cgi/p2webCgi.cpp | 6 +-- project2/cgi/p2webFCgi.cpp | 6 +-- project2/cgi/testCgi.cpp | 60 ++++++++++++----------- project2/cli/Jamfile.jam | 16 +++++++ project2/cli/claOptions.cpp | 87 +++++++++++++++++++++++++++++++++ project2/cli/claOptions.h | 21 ++++++++ project2/console/Jamfile.jam | 1 + project2/console/claOptions.cpp | 90 ----------------------------------- project2/console/claOptions.h | 19 -------- project2/console/consoleAppEngine.cpp | 15 ++++++ project2/console/consoleAppEngine.h | 3 +- project2/console/p2consoleMain.cpp | 2 +- 15 files changed, 193 insertions(+), 161 deletions(-) create mode 100644 project2/cli/Jamfile.jam create mode 100644 project2/cli/claOptions.cpp create mode 100644 project2/cli/claOptions.h delete mode 100644 project2/console/claOptions.cpp delete mode 100644 project2/console/claOptions.h diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index 8da2f11..5b8e5a5 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -55,5 +55,6 @@ exe testCgi : testCgi.cpp : p2cgicommon + ../cli//p2cli ../../libmisc ; diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 8adfb35..bd25172 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -1,4 +1,5 @@ #include +#include "optionsSource.h" #include "cgiAppEngine.h" #include "cgiResult.h" #include @@ -122,7 +123,7 @@ finalTransformSource(TransformSourcePtr ts) } void -CgiApplicationEngine::processRun(std::ostream & IO, CgiRequestContext * crc) const +CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const { bool sessionEmpty = crc->getSession()->Empty(); crc->startTime = boost::date_time::microsec_clock::universal_time(); @@ -308,11 +309,15 @@ doExceptionReporting(const E & e, std::ostream & IO) } void -CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const +CgiApplicationEngine::process(std::ostream & IO, cgicc::CgiInput * cgii, const CgiEnvInput & cgienv) const { try { - Logger()->messagef(LOG_DEBUG, "%s: Processing request", __FUNCTION__); - processRun(IO, crc); + boost::function sn = boost::bind(&CgiEnvInput::getenv, &cgienv, "SERVER_NAME"); + OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, sn)); + CgiRequestContext crc(cgii, cgienv); + Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); + Logger()->messagebf(LOG_DEBUG, "%s: Processing request (%s)", __FUNCTION__, crc.getRedirectURL()); + process(IO, &crc); Logger()->messagef(LOG_DEBUG, "%s: Completed request", __FUNCTION__); } catch (const std::exception & e) { @@ -333,13 +338,13 @@ CgiApplicationEngine::process(std::ostream & IO, CgiRequestContext * crc) const } const Glib::ustring & -CgiApplicationEngine::derivedPlatform(CgiRequestContext * crc) +CgiApplicationEngine::derivedPlatform(const boost::function & vhostName) { - auto pi = std::find_if(platHosts.begin(), platHosts.end(), [crc](const PlatformHostname & r) -> bool { - return r.second->match(crc->getServerName()); + auto pi = std::find_if(platHosts.begin(), platHosts.end(), [vhostName](const PlatformHostname & r) -> bool { + return r.second->match(vhostName()); }); if (pi == platHosts.end()) { - throw NoSuchPlatform(crc->getServerName()); + throw NoSuchPlatform(vhostName()); } return pi->first; } diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 476378a..1bc282f 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -32,11 +32,11 @@ class CgiApplicationEngine { CgiApplicationEngine(); virtual ~CgiApplicationEngine(); - void process(std::ostream & IO, CgiRequestContext *) const; - static const Glib::ustring & derivedPlatform(CgiRequestContext *); + void process(std::ostream & IO, cgicc::CgiInput * cgii, const CgiEnvInput & cgienv) const; + static const Glib::ustring & derivedPlatform(const boost::function & vhostName); private: - void processRun(std::ostream & IO, CgiRequestContext *) const; + void process(std::ostream & IO, CgiRequestContext *) const; void addAppData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext *, bool) const; void addEnvData(const MultiRowSetPresenter * p, OutputOptionsPtr o, CgiRequestContext *, bool) const; diff --git a/project2/cgi/p2webCgi.cpp b/project2/cgi/p2webCgi.cpp index a8b47e8..a4e2328 100644 --- a/project2/cgi/p2webCgi.cpp +++ b/project2/cgi/p2webCgi.cpp @@ -1,5 +1,4 @@ #include "cgiAppEngine.h" -#include "optionsSource.h" #include class GetEnv : public CgiEnvInput { @@ -18,10 +17,7 @@ main(void) Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); CgiApplicationEngine app; GetEnv ge; - CgiRequestContext crc(NULL, ge); - OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, &crc)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); - app.process(std::cout, &crc); + app.process(std::cout, NULL, ge); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); diff --git a/project2/cgi/p2webFCgi.cpp b/project2/cgi/p2webFCgi.cpp index 4bc9b2d..0551bf0 100644 --- a/project2/cgi/p2webFCgi.cpp +++ b/project2/cgi/p2webFCgi.cpp @@ -1,6 +1,5 @@ #include "FCgiIO.h" #include "cgiAppEngine.h" -#include "optionsSource.h" #include time_t lastPeriodic = 0; @@ -45,10 +44,7 @@ main(void) while (FCGX_Accept_r(&request) == 0) { alarm(0); cgicc::FCgiIO IO(request); - CgiRequestContext crc(&IO, IO); - OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, &crc)); - Plugable::onAllComponents(boost::bind(&ComponentLoader::onBefore, _1)); - app.process(IO, &crc); + app.process(IO, &IO, IO); FCGX_Finish_r(&request); Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); if (time(NULL) > lastPeriodic + periodicDelay) { diff --git a/project2/cgi/testCgi.cpp b/project2/cgi/testCgi.cpp index 6fa8d42..d923d3c 100644 --- a/project2/cgi/testCgi.cpp +++ b/project2/cgi/testCgi.cpp @@ -4,6 +4,7 @@ #include "options.h" #include "safeMapFind.h" #include "../files/optionsSource.h" +#include "../cli/claOptions.h" #include "cgiRequestContext.h" #include "cgiAppEngine.h" @@ -23,23 +24,11 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { typedef boost::shared_ptr StrPtr; typedef std::map OptStore; - TestInput(int argc, char ** argv) : - crc(NULL, *this) + TestInput(int argc, char ** argv) { - auto cp = boost::bind(&CgiApplicationEngine::derivedPlatform, &crc); - OptionsSource::loadSources(cp); - FileOptions fo(".testCgi.settings"); - fo.loadInto(TestConfigConsumer(), cp); - if (argc > 1) { - const char * qm = strchr(argv[1], '?'); - if (qm) { - optStore()["REDIRECT_URL"] = StrPtr(new std::string(argv[1], qm - argv[1])); - optStore()["QUERY_STRING"] = StrPtr(new std::string(qm + 1)); - } - else { - optStore()["REDIRECT_URL"] = StrPtr(new std::string(argv[1])); - } - } + Plugable::newLoader("_1", new FileOptions(".testCgi.settings")); + Plugable::newLoader("_2", new CommandLineArguments(argc, argv, + [](const char * url) { urls.push_back(url); })); } std::string getenv(const std::string & varName) const @@ -54,30 +43,44 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { } void run() { + Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); CgiApplicationEngine app; - if (urlListFile.empty()) { - for (int run = 0; run < runCount; run += 1) { - app.process(std::cout, &crc); + boost::function sn = boost::bind(&CgiEnvInput::getenv, this, "SERVER_NAME"); + OptionsSource::loadSources(boost::bind(&CgiApplicationEngine::derivedPlatform, sn)); + + if (!urlListFile.empty()) { + std::ifstream urlFile(urlListFile); + while (!urlFile.eof()) { + std::string url; + urlFile >> url; + urls.push_back(url); } } - else { - for (int run = 0; run < runCount; run += 1) { - std::ifstream urls(urlListFile); - while (!urls.eof()) { - std::string url; - urls >> url; + + while (runCount-- > 0) { + BOOST_FOREACH(const auto & url, urls) { + int qm = url.find('?'); + if (qm != -1) { + optStore()["REDIRECT_URL"] = StrPtr(new std::string(url.substr(0, qm))); + optStore()["QUERY_STRING"] = StrPtr(new std::string(url.substr(qm + 1))); + } + else { optStore()["REDIRECT_URL"] = StrPtr(new std::string(url)); - app.process(std::cout, &crc); + optStore()["QUERY_STRING"] = StrPtr(new std::string()); } + app.process(std::cout, this, *this); + Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); } + Plugable::onAllComponents(boost::bind(&ComponentLoader::onPeriodic, _1)); } + Plugable::onAllComponents(boost::bind(&ComponentLoader::onIdle, _1)); } INITOPTIONS; private: - CgiRequestContext crc; static int runCount; static std::string urlListFile; + static std::vector urls; static OptStore & optStore() { static OptStore _optStore; @@ -86,6 +89,7 @@ class TestInput : public cgicc::CgiInput, public CgiEnvInput { }; int TestInput::runCount; std::string TestInput::urlListFile; +std::vector TestInput::urls; DECLARE_OPTIONS(TestInput, "Project2 CGI test options") TESTOPT("SERVER_NAME", "localhost", "FQDN of web service") @@ -97,7 +101,6 @@ 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") @@ -108,7 +111,6 @@ 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") diff --git a/project2/cli/Jamfile.jam b/project2/cli/Jamfile.jam new file mode 100644 index 0000000..28487aa --- /dev/null +++ b/project2/cli/Jamfile.jam @@ -0,0 +1,16 @@ +alias glibmm : : : : + "`pkg-config --cflags glibmm-2.4`" + "`pkg-config --libs glibmm-2.4`" + ; + +lib p2cli : + [ glob *.cpp ] + : + . + ../../libmisc + glibmm + ../common//p2common + : : + . + ; + diff --git a/project2/cli/claOptions.cpp b/project2/cli/claOptions.cpp new file mode 100644 index 0000000..b1e1250 --- /dev/null +++ b/project2/cli/claOptions.cpp @@ -0,0 +1,87 @@ +#include +#include +#include +#include "../common/optionsSource.h" +#include "../common/exceptions.h" +#include "claOptions.h" + +SimpleMessageException(ArgumentRequired); +SimpleMessageException(UnknownOption); + +CommandLineArguments::CommandLineArguments(int c, const char * const * v, const Others & o) : + argc(c), + argv(v), + others(o), + loadedAt(0) +{ +} + +void +CommandLineArguments::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const { + bool moreopts = true; + + for (int x = 1; x < argc; x += 1) { + if (moreopts && strcmp(argv[x], "--") == 0) { + moreopts = false; + } + else if (moreopts && strncmp(argv[x], "--", 2) == 0) { + Glib::ustring plat, name(argv[x] + 2); + Glib::ustring::size_type sl = name.find('/'); + if (sl != (Glib::ustring::size_type)-1) { + plat = name.substr(sl + 1); + name = name.substr(0, sl); + } + const Options::Option * o = consume.get(name); + if (!o) { + throw UnknownOption(name); + } + if (o->paramRequired()) { + x += 1; + if (x >= argc) { + throw ArgumentRequired(name); + } + consume(name, plat, argv[x], platform); + } + else { + consume(name, plat, name, platform); + } + } + else if (moreopts && *(argv[x]) == '-') { + const char * n = argv[x] + 1; + while (*n) { + Glib::ustring name(1, *n++); + const Options::Option * o = consume.get(name); + if (!o) { + throw UnknownOption(name); + } + if (o->paramRequired()) { + if (!*n) { + x += 1; + if (x >= argc) { + throw ArgumentRequired(name); + } + consume(name, Glib::ustring(), argv[x], platform); + } + else { + consume(name, Glib::ustring(), n, platform); + n += 1; + } + } + else { + consume(name, Glib::ustring(), name, platform); + } + } + } + else { + others(argv[x]); + } + } + time(&loadedAt); +} + +bool +CommandLineArguments::needReload() const +{ + return !loadedAt; +} + diff --git a/project2/cli/claOptions.h b/project2/cli/claOptions.h new file mode 100644 index 0000000..c669004 --- /dev/null +++ b/project2/cli/claOptions.h @@ -0,0 +1,21 @@ +#ifndef CLAOPTIONS_H +#define CLAOPTIONS_H + +#include "../common/optionsSource.h" + +class CommandLineArguments : public OptionsSource { + public: + typedef boost::function Others; + CommandLineArguments(int c, const char * const * v, const Others &); + void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; + bool needReload() const; + + private: + const int argc; + const char * const * argv; + const Others others; + mutable time_t loadedAt; +}; + +#endif + diff --git a/project2/console/Jamfile.jam b/project2/console/Jamfile.jam index fc5d50b..260de3e 100644 --- a/project2/console/Jamfile.jam +++ b/project2/console/Jamfile.jam @@ -14,6 +14,7 @@ exe p2console : . ..//p2parts ../common//p2common + ../cli//p2cli ../../libmisc ; diff --git a/project2/console/claOptions.cpp b/project2/console/claOptions.cpp deleted file mode 100644 index ee28bf6..0000000 --- a/project2/console/claOptions.cpp +++ /dev/null @@ -1,90 +0,0 @@ -#include -#include -#include -#include "../common/optionsSource.h" -#include "../common/exceptions.h" -#include "claOptions.h" -#include "consoleAppEngine.h" - -StaticMessageException(InvalidScriptName, "Script name should be group/name"); -SimpleMessageException(ArgumentRequired); -SimpleMessageException(UnknownOption); - -CommandLineArguments::CommandLineArguments(int c, const char * const * v) : - argc(c), - argv(v), - loadedAt(0) -{ -} - -void -CommandLineArguments::loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const { - bool moreopts = true; - - for (int x = 1; x < argc; x += 1) { - if (moreopts && strcmp(argv[x], "--") == 0) { - moreopts = false; - } - else if (moreopts && strncmp(argv[x], "--", 2) == 0) { - Glib::ustring name(argv[x] + 2); - const Options::Option * o = consume.get(name); - if (!o) { - throw UnknownOption(name); - } - if (o->paramRequired()) { - x += 1; - if (x >= argc) { - throw ArgumentRequired(name); - } - consume(name, platform(), argv[x], platform); - } - else { - consume(name, platform(), name, platform); - } - } - else if (moreopts && *(argv[x]) == '-') { - const char * n = argv[x] + 1; - while (*n) { - Glib::ustring name(1, *n++); - const Options::Option * o = consume.get(name); - if (!o) { - throw UnknownOption(name); - } - if (o->paramRequired()) { - if (!*n) { - x += 1; - if (x >= argc) { - throw ArgumentRequired(name); - } - consume(name, platform(), argv[x], platform); - } - else { - consume(name, platform(), n, platform); - n += 1; - } - } - else { - consume(name, platform(), name, platform); - } - } - } - else { - const char * sl = strchr(argv[x], '/'); - if (sl) { - ConsoleApplicationEngine::todolist.push_back(ConsoleApplicationEngine::ToDo(std::string(argv[x], sl), sl + 1)); - sl++; - } - else { - throw InvalidScriptName(); - } - } - } - time(&loadedAt); -} - -bool -CommandLineArguments::needReload() const -{ - return !loadedAt; -} - diff --git a/project2/console/claOptions.h b/project2/console/claOptions.h deleted file mode 100644 index ea3fb01..0000000 --- a/project2/console/claOptions.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CLAOPTIONS_H -#define CLAOPTIONS_H - -#include "../common/optionsSource.h" - -class CommandLineArguments : public OptionsSource { - public: - CommandLineArguments(int c, const char * const * v); - void loadInto(const ConfigConsumer & consume, const Options::CurrentPlatform & platform) const; - bool needReload() const; - - private: - const int argc; - const char * const * argv; - mutable time_t loadedAt; -}; - -#endif - diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index 332d7b8..592b006 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -13,6 +13,7 @@ #include #include +StaticMessageException(InvalidScriptName, "Script name should be group/name"); SimpleMessageException(UnknownPlatformAlias); class ShowHelpTrigger : public Options::Target { @@ -135,3 +136,17 @@ ConsoleApplicationEngine::process() Plugable::onAllComponents(boost::bind(&ComponentLoader::onIteration, _1)); } } + +void +ConsoleApplicationEngine::appendScript(const char * arg) +{ + const char * sl = strchr(arg, '/'); + if (sl) { + todolist.push_back(ConsoleApplicationEngine::ToDo(std::string(arg, sl), sl + 1)); + sl++; + } + else { + throw InvalidScriptName(); + } +} + diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index b75d9b1..f4017e4 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -18,6 +18,8 @@ class ConsoleApplicationEngine : public ExecContext { VariableType getParameter(const VariableType&) const; SessionPtr getSession() const; + static void appendScript(const char * arg); + INITOPTIONS; private: @@ -28,7 +30,6 @@ class ConsoleApplicationEngine : public ExecContext { typedef std::map ConsolePlatforms; typedef std::map Parameters; - friend class CommandLineArguments; mutable ConsolePlatforms conplat; SessionPtr runtime; MultiRowSetPresenterPtr presenter; diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp index 3c0f473..6b9a2ea 100644 --- a/project2/console/p2consoleMain.cpp +++ b/project2/console/p2consoleMain.cpp @@ -6,7 +6,7 @@ int main(int argc, char ** argv) { - Plugable::newLoader("", new CommandLineArguments(argc, argv)); + Plugable::newLoader("", new CommandLineArguments(argc, argv, &ConsoleApplicationEngine::appendScript)); Plugable::onAllComponents(boost::bind(&ComponentLoader::onBegin, _1)); OptionsSource::loadSources([] { return ConsoleApplicationEngine::reqPlatform;} ); -- cgit v1.2.3