Begin removing several dependencies on Config object

This commit is contained in:
Albert S. 2019-09-29 17:12:36 +02:00
parent 327c0793d1
commit 364d82a99f
9 changed files with 127 additions and 79 deletions

View File

@ -73,27 +73,27 @@ Config::Config(const std::map<std::string, std::string> &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<std::string, std::string> &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)

View File

@ -6,25 +6,17 @@
#include <map>
#include "permissions.h"
#include "utils.h"
class Config
class WikiGeneralConfig
{
private:
std::map<std::string, std::string> 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<std::string, std::string> &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<std::string, std::string> *configmap;
public:
ConfigVariableResolver()
{
}
ConfigVariableResolver(const std::map<std::string, std::string> &configmap)
{
this->configmap = &configmap;
}
std::string getConfig(const std::string &key) const
{
return utils::getKeyOrEmpty(*configmap, key);
}
};
class Config
{
private:
std::map<std::string, std::string> 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<std::string, std::string> &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

View File

@ -24,5 +24,16 @@ SOFTWARE.
std::unique_ptr<GatewayInterface> createGateway(const Config &c)
{
return std::make_unique<HttpGateway>(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<HttpGateway>(listenaddr, std::stoi(listenport), c.max_payload_length);
}

View File

@ -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()

View File

@ -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;
};

View File

@ -56,12 +56,12 @@ void setup_signal_handlers()
}
}
std::unique_ptr<ICache> createCache(const Config &config)
std::unique_ptr<ICache> createCache(const ConfigVariableResolver &resolver)
{
std::string path = config.getConfig("cache_fs_dir");
std::string path = resolver.getConfig("cache_fs_dir");
return std::make_unique<FsCache>(config.getConfig("cache_fs_dir"));
return std::make_unique<FsCache>(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);

View File

@ -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<std::string> &results,
}
std::string Template::renderSearch(const std::vector<std::string> &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<SearchResult> &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<SearchResult> &results) con
std::string Template::renderRevisionList(const std::vector<Revision> &revisions, bool withpage) const
{
std::stringstream stream;
UrlProvider urlprovider(*this->config);
UrlProvider urlprovider(*this->configUrls);
auto genwithoutpage = [&] {
for(const Revision &revision : revisions)

View File

@ -11,7 +11,12 @@
class Template
{
private:
const Config *config;
ConfigVariableResolver *configVarResolver;
ConfigUrls *configUrls;
std::string templateprefix;
std::string templatepath;
std::map<std::string, TemplatePage> 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

View File

@ -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;
}