From 364d82a99fd0296ad0df92396a68fb241b266bea Mon Sep 17 00:00:00 2001 From: Albert S Date: Sun, 29 Sep 2019 17:12:36 +0200 Subject: [PATCH] Begin removing several dependencies on Config object --- config.cpp | 45 +++++++++++----------- config.h | 76 +++++++++++++++++++++++++++----------- gateway/gatewayfactory.cpp | 13 ++++++- gateway/httpgateway.cpp | 18 ++------- gateway/httpgateway.h | 2 +- qswiki.cpp | 14 +++---- template.cpp | 24 +++++++----- template.h | 10 ++++- urlprovider.h | 4 +- 9 files changed, 127 insertions(+), 79 deletions(-) diff --git a/config.cpp b/config.cpp index 1f8980e..fdbb275 100644 --- a/config.cpp +++ b/config.cpp @@ -73,27 +73,27 @@ Config::Config(const std::map &map) this->wikiname = required("wikiname"); this->logfile = required("logfile"); this->templatepath = required("templatepath"); - this->linkallcats = required("linkallcats"); - this->linkallpages = required("linkallpages"); - this->linkcategory = required("linkcategory"); - this->linkdelete = required("linkdelete"); - this->linkedit = required("linkedit"); - this->linkhistory = required("linkhistory"); - this->linkindex = required("linkindex"); - this->linklogout = required("linklogout"); - this->linkpage = required("linkpage"); - this->linkrecent = required("linkrecent"); - this->linkrevision = required("linkrevision"); - this->linksettings = required("linksettings"); - this->linkshere = required("linkshere"); - this->loginurl = required("loginurl"); - this->linkrecentsort = required("linkrecentsort"); - this->linkhistorysort = required("linkhistorysort"); - this->actionurl = required("actionurl"); - this->settingsurl = required("settingsurl"); - this->deletionurl = required("deletionurl"); - this->adminregisterurl = required("adminregisterurl"); - this->userchangepwurl = required("userchangepwurl"); + this->urls.linkallcats = required("linkallcats"); + this->urls.linkallpages = required("linkallpages"); + this->urls.linkcategory = required("linkcategory"); + this->urls.linkdelete = required("linkdelete"); + this->urls.linkedit = required("linkedit"); + this->urls.linkhistory = required("linkhistory"); + this->urls.linkindex = required("linkindex"); + this->urls.linklogout = required("linklogout"); + this->urls.linkpage = required("linkpage"); + this->urls.linkrecent = required("linkrecent"); + this->urls.linkrevision = required("linkrevision"); + this->urls.linksettings = required("linksettings"); + this->urls.linkshere = required("linkshere"); + this->urls.loginurl = required("loginurl"); + this->urls.linkrecentsort = required("linkrecentsort"); + this->urls.linkhistorysort = required("linkhistorysort"); + this->urls.actionurl = required("actionurl"); + this->urls.settingsurl = required("settingsurl"); + this->urls.deletionurl = required("deletionurl"); + this->urls.adminregisterurl = required("adminregisterurl"); + this->urls.userchangepwurl = required("userchangepwurl"); this->connectionstring = required("connectionstring"); this->max_pagename_length = optional("max_pagename_length", 256); @@ -106,6 +106,9 @@ Config::Config(const std::map &map) this->templateprefix = "{qswiki:"; this->max_payload_length = optional("max_payload_length", 10 * 1024 * 1024); + + ConfigVariableResolver resolver{this->configmap}; + this->configVarResolver = resolver; } ConfigReader::ConfigReader(const std::string &file) diff --git a/config.h b/config.h index 4c4528b..f6d6023 100644 --- a/config.h +++ b/config.h @@ -6,25 +6,17 @@ #include #include "permissions.h" #include "utils.h" -class Config + +class WikiGeneralConfig { - private: - std::map configmap; - std::string required(const std::string &key); - - std::string optional(const std::string &key, std::string defaultvalue = ""); - int optional(const std::string &key, int defaulvalue); - uint64_t optional(const std::string &key, uint64_t defaultvalue); - - public: - Config(const std::map &map); - // TODO: these could be references!? std::string wikiname; - std::string wikipath; - std::string templatepath; - std::string templateprefix; - std::string logfile; std::string anon_username; + int max_pagename_length; + int query_limit; +}; + +struct ConfigUrls +{ std::string linkindex; std::string linkrecent; std::string linkallpages; @@ -46,6 +38,53 @@ class Config std::string linkhistorysort; std::string adminregisterurl; std::string userchangepwurl; +}; + +class ConfigVariableResolver +{ + private: + const std::map *configmap; + + public: + ConfigVariableResolver() + { + } + + ConfigVariableResolver(const std::map &configmap) + { + this->configmap = &configmap; + } + + std::string getConfig(const std::string &key) const + { + return utils::getKeyOrEmpty(*configmap, key); + } +}; + +class Config +{ + private: + std::map configmap; + std::string required(const std::string &key); + + std::string optional(const std::string &key, std::string defaultvalue = ""); + int optional(const std::string &key, int defaulvalue); + uint64_t optional(const std::string &key, uint64_t defaultvalue); + + public: + ConfigUrls urls; + ConfigVariableResolver configVarResolver; + + Config(const std::map &map); + + // TODO: these could be references!? + std::string wikiname; + std::string wikipath; + std::string templatepath; + std::string templateprefix; + std::string logfile; + std::string anon_username; + std::string connectionstring; int query_limit; @@ -56,11 +95,6 @@ class Config uint64_t max_payload_length; Permissions anon_permissions; - - std::string getConfig(const std::string &key) const - { - return utils::getKeyOrEmpty(configmap, key); - } }; class ConfigReader diff --git a/gateway/gatewayfactory.cpp b/gateway/gatewayfactory.cpp index 3a8630f..acb5872 100644 --- a/gateway/gatewayfactory.cpp +++ b/gateway/gatewayfactory.cpp @@ -24,5 +24,16 @@ SOFTWARE. std::unique_ptr createGateway(const Config &c) { - return std::make_unique(c); + std::string listenaddr = c.configVarResolver.getConfig("http.listenaddr"); + if(listenaddr.empty()) + { + throw new std::runtime_error("No http.listenaddr in config file"); + } + std::string listenport = c.configVarResolver.getConfig("http.listenport"); + if(listenport.empty()) + { + throw new std::runtime_error("No http.listenport in config file"); + } + + return std::make_unique(listenaddr, std::stoi(listenport), c.max_payload_length); } diff --git a/gateway/httpgateway.cpp b/gateway/httpgateway.cpp index bc0bbb0..1953286 100644 --- a/gateway/httpgateway.cpp +++ b/gateway/httpgateway.cpp @@ -20,21 +20,11 @@ SOFTWARE. */ #include "httpgateway.h" #include "../logger.h" -HttpGateway::HttpGateway(const Config &config) +HttpGateway::HttpGateway(std::string listenaddr, int port, uint64_t maxPayloadLength) { - this->listenaddr = config.getConfig("http.listenaddr"); - if(this->listenaddr.empty()) - { - throw new std::runtime_error("No http.listenaddr in config file"); - } - std::string listenport = config.getConfig("http.listenport"); - if(listenport.empty()) - { - throw new std::runtime_error("No http.listenport in config file"); - } - this->listenport = std::stoi(listenport); - - this->maxPayloadLength = config.max_payload_length; + this->listenaddr = listenaddr; + this->listenport = port; + this->maxPayloadLength = maxPayloadLength; } bool HttpGateway::keepReading() diff --git a/gateway/httpgateway.h b/gateway/httpgateway.h index 28a795a..af7efd2 100644 --- a/gateway/httpgateway.h +++ b/gateway/httpgateway.h @@ -19,7 +19,7 @@ class HttpGateway : public GatewayInterface uint64_t maxPayloadLength; public: - HttpGateway(const Config &config); + HttpGateway(std::string listenaddr, int port, uint64_t maxPayloadLength); bool keepReading() override; void work(RequestWorker &worker) override; }; diff --git a/qswiki.cpp b/qswiki.cpp index beefa6b..edc65ca 100644 --- a/qswiki.cpp +++ b/qswiki.cpp @@ -56,12 +56,12 @@ void setup_signal_handlers() } } -std::unique_ptr createCache(const Config &config) +std::unique_ptr createCache(const ConfigVariableResolver &resolver) { - std::string path = config.getConfig("cache_fs_dir"); + std::string path = resolver.getConfig("cache_fs_dir"); - return std::make_unique(config.getConfig("cache_fs_dir")); + return std::make_unique(path); } int main(int argc, char **argv) { @@ -97,7 +97,7 @@ int main(int argc, char **argv) // TODO: config.connectiontring only works as long as we only support sqlite of course if(!sandbox->enablePreWorker({ - config.getConfig("cache_fs_dir"), + config.configVarResolver.getConfig("cache_fs_dir"), config.templatepath, std::filesystem::path(config.logfile).parent_path(), std::filesystem::path(config.connectionstring).parent_path(), @@ -130,10 +130,10 @@ int main(int argc, char **argv) userdao->save(anon.value()); User::setAnon(anon.value()); - Template siteTemplate{config}; - UrlProvider urlprovider{config}; + Template siteTemplate{config.templateprefix, config.templatepath, config.urls, config.configVarResolver}; + UrlProvider urlprovider{config.urls}; - auto cache = createCache(config); + auto cache = createCache(config.configVarResolver); cache->clear(); RequestWorker requestWorker(*database, siteTemplate, urlprovider, *cache); diff --git a/template.cpp b/template.cpp index 9c6e202..351d1c2 100644 --- a/template.cpp +++ b/template.cpp @@ -23,22 +23,25 @@ SOFTWARE. #include "urlprovider.h" #include "htmllink.h" #include "logger.h" -Template::Template(const Config &config) +Template::Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls, + ConfigVariableResolver &configVarsResolver) { - this->config = &config; + this->templateprefix = templateprefix; + this->templatepath = templatepath; + this->configUrls = &configUrls; + this->configVarResolver = &configVarsResolver; } std::string Template::getPartPath(std::string_view partname) { // TODO: utils::concatPath? C++17 paths? - return this->config->templatepath + "/" + std::string(partname); + return this->templatepath + "/" + std::string(partname); } std::string Template::loadPartContent(std::string_view partname) { std::string partpath = getPartPath(partname); return utils::readCompleteFile(partpath); } - std::string Template::loadResolvedPart(std::string_view partname) { return resolveIncludes(loadPartContent(partname)); @@ -46,7 +49,7 @@ std::string Template::loadResolvedPart(std::string_view partname) std::string Template::resolveIncludes(std::string_view content) { - Varreplacer replacer(this->config->templateprefix); + Varreplacer replacer(this->templateprefix); replacer.addResolver("include", [&](std::string_view key) { return loadResolvedPart(key); }); return replacer.parse(content); } @@ -54,8 +57,9 @@ std::string Template::resolveIncludes(std::string_view content) TemplatePage Template::createPage(std::string name) { std::string content = loadResolvedPart(name); - Varreplacer replacer(this->config->templateprefix); - replacer.addResolver("config", [&](std::string_view key) { return this->config->getConfig(std::string(key)); }); + Varreplacer replacer(this->templateprefix); + replacer.addResolver("config", + [&](std::string_view key) { return this->configVarResolver->getConfig(std::string(key)); }); // TODO: Varreplacer is not recursive, but since includes might add new vars, it may not be this bad anyway. // return TemplatePage(replacer.parse(content)); @@ -96,12 +100,12 @@ std::string Template::renderSearch(const std::vector &results, } std::string Template::renderSearch(const std::vector &results) const { - UrlProvider urlprovider(*this->config); + UrlProvider urlprovider(*this->configUrls); return renderSearch(results, [&urlprovider](std::string s) { return urlprovider.page(s); }); } std::string Template::renderSearch(const std::vector &results) const { - UrlProvider urlprovider(*this->config); + UrlProvider urlprovider(*this->configUrls); HtmlLink link; char lastchar = 0; std::string result; @@ -124,7 +128,7 @@ std::string Template::renderSearch(const std::vector &results) con std::string Template::renderRevisionList(const std::vector &revisions, bool withpage) const { std::stringstream stream; - UrlProvider urlprovider(*this->config); + UrlProvider urlprovider(*this->configUrls); auto genwithoutpage = [&] { for(const Revision &revision : revisions) diff --git a/template.h b/template.h index 639cd7c..37e5ff2 100644 --- a/template.h +++ b/template.h @@ -11,7 +11,12 @@ class Template { private: - const Config *config; + ConfigVariableResolver *configVarResolver; + ConfigUrls *configUrls; + + std::string templateprefix; + std::string templatepath; + std::map pagesMap; std::string resolveIncludes(std::string_view content); @@ -21,7 +26,8 @@ class Template TemplatePage createPage(std::string name); public: - Template(const Config &config); + Template(std::string templateprefix, std::string templatepath, ConfigUrls &configUrls, + ConfigVariableResolver &configVarsResolver); /* TODO: returning this as a reference is by no means a risk free business, because between requests, different vars can be set conditionally, thus creating a mess diff --git a/urlprovider.h b/urlprovider.h index 744e89a..d9da79b 100644 --- a/urlprovider.h +++ b/urlprovider.h @@ -5,12 +5,12 @@ class UrlProvider { private: - const Config *config; + const ConfigUrls *config; std::string replaceOnlyPage(std::string templatepart, std::string page); public: - UrlProvider(const Config &config) + UrlProvider(const ConfigUrls &config) { this->config = &config; }