diff options
-rw-r--r-- | project2/cgi/Jamfile.jam | 2 | ||||
-rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 2 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.cpp | 8 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.h | 1 | ||||
-rw-r--r-- | project2/cgi/cgiRequestID.cpp | 55 | ||||
-rw-r--r-- | project2/cgi/cgiSimpleRouter.cpp | 2 | ||||
-rw-r--r-- | project2/cgi/cgiUriParam.cpp (renamed from project2/common/variables/uri.cpp) | 12 | ||||
-rw-r--r-- | project2/common/environment.h | 2 | ||||
-rw-r--r-- | project2/common/exceptions.h | 1 | ||||
-rw-r--r-- | project2/common/presenterCache.cpp | 8 | ||||
-rw-r--r-- | project2/common/presenterCache.h | 3 | ||||
-rw-r--r-- | project2/console/consoleEnvironment.cpp | 17 | ||||
-rw-r--r-- | project2/console/consoleEnvironment.h | 4 | ||||
-rw-r--r-- | project2/files/Jamfile.jam | 2 | ||||
-rw-r--r-- | project2/files/presenterCache.cpp | 32 |
15 files changed, 91 insertions, 60 deletions
diff --git a/project2/cgi/Jamfile.jam b/project2/cgi/Jamfile.jam index 017dd11..63844b0 100644 --- a/project2/cgi/Jamfile.jam +++ b/project2/cgi/Jamfile.jam @@ -6,6 +6,7 @@ lib boost_filesystem : : <name>boost_filesystem ; lib cgicc : : <name>cgicc ; lib fcgi : : <name>fcgi ; lib fcgi++ : : <name>fcgi++ ; +lib gcrypt : : <name>gcrypt ; cpp-pch pch : pch.hpp : <include>../../libmisc @@ -25,6 +26,7 @@ lib p2web : <library>../common//p2common <library>boost_filesystem <library>../xml//p2xml + <library>gcrypt : : <library>..//p2parts <library>cgicc diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index f2c7f86..985789b 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -182,7 +182,7 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt p->finishRowSet(); } - if (!outputCachingActive && (!o || o->Parameters())) { + if (!o || o->Parameters()) { // Parameters p->addNewRowSet("params", env()->scriptNamespacePrefix); BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) { diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp index c106f67..6462f5c 100644 --- a/project2/cgi/cgiEnvironment.cpp +++ b/project2/cgi/cgiEnvironment.cpp @@ -140,6 +140,14 @@ CgiEnvironment::getParamUriCount() const return router->parameterCount(); } +void +CgiEnvironment::applyAllParameters(const boost::function<void (const std::string &, const std::string &)> & func) const +{ + BOOST_FOREACH(const auto & f, cgi->getElements()) { + func(f.getName(), f.getValue()); + } +} + Glib::ustring CgiEnvironment::getParamQuery(const std::string & p) const { diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h index 330cd97..176ca8d 100644 --- a/project2/cgi/cgiEnvironment.h +++ b/project2/cgi/cgiEnvironment.h @@ -38,6 +38,7 @@ class CgiEnvironment : public Environment { Glib::ustring getParamUri(VariableType idx) const; unsigned int getParamUriCount() const; Glib::ustring getParamQuery(const std::string & idx) const; + void applyAllParameters(const boost::function<void (const std::string &, const std::string &)> &) const; std::string getServerName() const; std::string getScriptName() const; std::string getRedirectURL() const; diff --git a/project2/cgi/cgiRequestID.cpp b/project2/cgi/cgiRequestID.cpp new file mode 100644 index 0000000..6f4d01e --- /dev/null +++ b/project2/cgi/cgiRequestID.cpp @@ -0,0 +1,55 @@ +#include <pch.hpp> +#include <variables.h> +#include <scriptLoader.h> +#include <scriptStorage.h> +#include <appEngine.h> +#include <gcrypt.h> +#include <scopeObject.h> +#include <iomanip> + +/// Variable implementation that returns a unique ID for a page request +class CgiRequestID : public VariableImplDyn { + public: + CgiRequestID(ScriptNodePtr e) : + VariableImplDyn(e) + { + } + + VariableType value() const + { + gcry_md_hd_t state; + gcry_md_open(&state, GCRY_MD_SHA1, 0); + ScopeObject gcryClose([&state] { gcry_md_close(state); }); + + auto _env = static_cast<const CgiEnvironment *>(ApplicationEngine::getCurrent()->env()); + gcryApplyString(state, _env->getRedirectURL()); + + _env->applyAllParameters([&state,this](const std::string & name, const std::string & value) { + gcryApplyString(state, name); + gcryApplyString(state, value); + }); + + return hash(state); + } + + private: + static void gcryApplyString(gcry_md_hd_t & state, const std::string & str) + { + gcry_md_write(state, str.data(), str.length()); + } + + static std::string hash(gcry_md_hd_t & state) + { + int hash_len = gcry_md_get_algo_dlen(GCRY_MD_SHA1); + unsigned char * hash = gcry_md_read(state, GCRY_MD_SHA1); + std::stringstream hashstr; + hashstr << std::hex << std::setfill('0'); + for (int i = 0; i < hash_len; i++) { + hashstr << std::setw(2) << static_cast<unsigned>(hash[i]); + } + return hashstr.str(); + } +}; +DECLARE_COMPONENT_LOADER("requestid", CgiRequestID, VariableLoader); + + diff --git a/project2/cgi/cgiSimpleRouter.cpp b/project2/cgi/cgiSimpleRouter.cpp index a28cf1d..2359c4e 100644 --- a/project2/cgi/cgiSimpleRouter.cpp +++ b/project2/cgi/cgiSimpleRouter.cpp @@ -2,6 +2,8 @@ #include "scriptLoader.h" #include "presenter.h" +SimpleNumericException(UriElementOutOfRange); + std::vector<std::string> makeVector(const boost::filesystem::path & y) { diff --git a/project2/common/variables/uri.cpp b/project2/cgi/cgiUriParam.cpp index c5e596f..04a2c36 100644 --- a/project2/common/variables/uri.cpp +++ b/project2/cgi/cgiUriParam.cpp @@ -1,8 +1,8 @@ #include <pch.hpp> -#include "../variables.h" -#include "../scriptLoader.h" -#include "../scriptStorage.h" -#include "../appEngine.h" +#include <variables.h> +#include <scriptLoader.h> +#include <scriptStorage.h> +#include <appEngine.h> /// Variable implementation to access URI path fragments class VariableUri : public VariableImplDyn { @@ -15,9 +15,9 @@ class VariableUri : public VariableImplDyn { VariableType value() const { try { - return ApplicationEngine::getCurrent()->env()->getParamUri(index()); + return static_cast<const CgiEnvironment *>(ApplicationEngine::getCurrent()->env())->getParamUri(index()); } - catch (UriElementOutOfRange) { + catch (...) { if (!defaultValue) { throw; } diff --git a/project2/common/environment.h b/project2/common/environment.h index 4daea74..af9f5dd 100644 --- a/project2/common/environment.h +++ b/project2/common/environment.h @@ -21,8 +21,6 @@ class Environment { static const Environment * getCurrent(); - virtual Glib::ustring getParamUri(VariableType idx) const = 0; - virtual unsigned int getParamUriCount() const = 0; virtual Glib::ustring getParamQuery(const std::string & idx) const = 0; virtual std::string getServerName() const = 0; diff --git a/project2/common/exceptions.h b/project2/common/exceptions.h index 6d3410d..38f0efa 100644 --- a/project2/common/exceptions.h +++ b/project2/common/exceptions.h @@ -62,7 +62,6 @@ class Name : public syscall_error { \ Name(int e) : syscall_error(e) { } \ } -SimpleNumericException(UriElementOutOfRange); SimpleMessageException(ParamNotFound); SimpleMessageException(NotSupported); SimpleMessageException(FileNotReadable); diff --git a/project2/common/presenterCache.cpp b/project2/common/presenterCache.cpp index d5897ad..6ca3661 100644 --- a/project2/common/presenterCache.cpp +++ b/project2/common/presenterCache.cpp @@ -9,14 +9,6 @@ PresenterCache::PresenterCache(ScriptNodePtr s) : } void -PresenterCache::applyKeys(const boost::function2<void, const std::string &, const VariableType &> & f) const -{ - BOOST_FOREACH(const IHaveParameters::Parameters::value_type & p, allParameters()) { - f(p.first, p.second); - } -} - -void PresenterCache::flushCache() { } diff --git a/project2/common/presenterCache.h b/project2/common/presenterCache.h index 15375da..799181b 100644 --- a/project2/common/presenterCache.h +++ b/project2/common/presenterCache.h @@ -13,9 +13,6 @@ class PresenterCache : public SourceObject, public virtual TransformSource, publ virtual std::ostream & writeCache(const std::string & ct, const std::string & encoding) = 0; virtual void flushCache(); const std::string encoding; - - protected: - void applyKeys(const boost::function2<void, const std::string &, const VariableType &> & f) const; }; typedef boost::intrusive_ptr<PresenterCache> PresenterCachePtr; diff --git a/project2/console/consoleEnvironment.cpp b/project2/console/consoleEnvironment.cpp index 69f17cd..09f4572 100644 --- a/project2/console/consoleEnvironment.cpp +++ b/project2/console/consoleEnvironment.cpp @@ -49,7 +49,6 @@ ConsoleEnvironment::ConsoleEnvironment(int c, char ** v) : ("console.syslogIdent", Options::value(&scriptname, scriptname), "Log to syslog with ident <arg>") ("console.platform", Options::value(&reqPlatform), "Platform")("p") ("console.queryParam", Options::value(&queryParams), "Query parameter")("q") - ("console.uriParam", Options::value(&uriParams), "URL paramater")("u") ; } @@ -63,22 +62,6 @@ ConsoleEnvironment::~ConsoleEnvironment() } Glib::ustring -ConsoleEnvironment::getParamUri(VariableType _idx) const -{ - int32_t idx = _idx; - if (idx < (int32_t)uriParams.size()) { - return uriParams[idx]; - } - throw UriElementOutOfRange(idx); -} - -unsigned int -ConsoleEnvironment::getParamUriCount() const -{ - return uriParams.size(); -} - -Glib::ustring ConsoleEnvironment::getParamQuery(const std::string & p) const { QueryParams::const_iterator i = std::find_if(queryParams.begin(), queryParams.end(), diff --git a/project2/console/consoleEnvironment.h b/project2/console/consoleEnvironment.h index 6ce2d75..fd54dd3 100644 --- a/project2/console/consoleEnvironment.h +++ b/project2/console/consoleEnvironment.h @@ -10,15 +10,12 @@ class ConsoleEnvironment : public Environment { public: typedef boost::tuple<Glib::ustring, Glib::ustring> ToDo; typedef std::vector<ToDo> ToDoList; - typedef std::vector<std::string> UriParams; typedef std::vector<std::pair<std::string, std::string> > QueryParams; ConsoleEnvironment(int argc, char ** argv); virtual ~ConsoleEnvironment(); - Glib::ustring getParamUri(VariableType idx) const; - unsigned int getParamUriCount() const; Glib::ustring getParamQuery(const std::string & idx) const; std::string getServerName() const; std::string getScriptName() const; @@ -36,7 +33,6 @@ class ConsoleEnvironment : public Environment { std::string scriptname; Glib::ustring reqPlatform; QueryParams queryParams; - UriParams uriParams; static ToDoList todolist; }; diff --git a/project2/files/Jamfile.jam b/project2/files/Jamfile.jam index b8ae31e..3b23db0 100644 --- a/project2/files/Jamfile.jam +++ b/project2/files/Jamfile.jam @@ -12,7 +12,7 @@ cpp-pch pch : pch.hpp : ; lib p2files : pch - [ glob *.cpp ] + [ glob-tree *.cpp ] : <include>../libmisc <library>glibmm diff --git a/project2/files/presenterCache.cpp b/project2/files/presenterCache.cpp index 6c21580..ee07fd2 100644 --- a/project2/files/presenterCache.cpp +++ b/project2/files/presenterCache.cpp @@ -15,6 +15,7 @@ #include <glibmm/convert.h> #include <sys/file.h> #include <gcrypt.h> +#include <iomanip> SimpleSysCallException(OpenCacheFile); SimpleSysCallException(StatCacheFile); @@ -70,12 +71,12 @@ class FilePresenterCache : public PresenterCache { { int hash_len = gcry_md_get_algo_dlen(GCRY_MD_SHA1); unsigned char * hash = gcry_md_read(state, GCRY_MD_SHA1); - std::string hashstr(hash_len * 2, '-'); - char * p = &hashstr[0]; - for (int i = 0; i < hash_len; i++, p += 2) { - snprintf(p, 3, "%02x", hash[i]); + std::stringstream hashstr; + hashstr << std::hex << std::setfill('0'); + for (int i = 0; i < hash_len; i++) { + hashstr << std::setw(2) << static_cast<unsigned>(hash[i]); } - return hashstr; + return hashstr.str(); } const int fd; private: @@ -85,7 +86,8 @@ class FilePresenterCache : public PresenterCache { typedef boost::shared_ptr<WriteCacheStrm> WriteCacheStrmPtr; FilePresenterCache(ScriptNodePtr s) : - PresenterCache(s) { + PresenterCache(s), + idProvider(VariableLoader::createNew(Provider, s)) { } ~FilePresenterCache() { @@ -186,12 +188,7 @@ class FilePresenterCache : public PresenterCache { Key getCacheKey() const { Key key; - unsigned int puc = Environment::getCurrent()->getParamUriCount(); - key.get<0>().reserve(puc); - for (unsigned int i = 0; i < puc; i += 1) { - key.get<0>().push_back(Environment::getCurrent()->getParamUri(i).raw()); - } - applyKeys(boost::bind(&appendParams, &key.get<1>(), _1, _2)); + key.get<0>().push_back(idProvider->value()); return key; } CacheFilePtr openCacheFile(const Key & key) const @@ -204,11 +201,7 @@ class FilePresenterCache : public PresenterCache { { boost::filesystem::path cache; cache = Store; - unsigned int puc = Environment::getCurrent()->getParamUriCount(); - for (unsigned int i = 0; i < puc; i += 1) { - cache /= Environment::getCurrent()->getParamUri(i).raw(); - } - applyKeys(boost::bind(&appendPath, &cache, _1, _2)); + cache /= idProvider->value(); boost::filesystem::create_directories(cache); cache /= FileName; return cache; @@ -227,16 +220,19 @@ class FilePresenterCache : public PresenterCache { static OpenCaches openCaches; mutable CacheFilePtr myCache; + Variable::VariableImplPtr idProvider; // Config static boost::filesystem::path Store; static std::string FileName; + static std::string Provider; static time_t CacheLife; friend class FilePresenterCacheLoader; }; FilePresenterCache::OpenCaches FilePresenterCache::openCaches; boost::filesystem::path FilePresenterCache::Store; std::string FilePresenterCache::FileName; +std::string FilePresenterCache::Provider; time_t FilePresenterCache::CacheLife; class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { @@ -251,6 +247,8 @@ class FilePresenterCacheLoader : public ElementLoader::For<FilePresenterCache> { "The filename to store the data in") ("pcache.file.life", Options::value(&FilePresenterCache::CacheLife, 3600), "The age of cache entries after which they are removed (seconds)") + ("pcache.file.idprovider", Options::value(&FilePresenterCache::Provider, "requestid"), + "The name of the component used to provide a unique request ID") ; } |