From 12972923e74e3dd174f3ce3e59c2db5ca9b400eb Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Fri, 3 Apr 2020 19:23:29 +0200 Subject: Configuration --- TODO | 3 -- config.cpp | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- config.h | 40 ++++++++++++++++++++++ webserver.conf | 13 +++++--- 4 files changed, 149 insertions(+), 9 deletions(-) diff --git a/TODO b/TODO index 4618a74..575d33b 100644 --- a/TODO +++ b/TODO @@ -1,6 +1,3 @@ Plugin: https://www.boost.org/doc/libs/1_72_0/doc/html/boost_dll/tutorial.html#boost_dll.tutorial.symbol_shadowing_problem__linux_ HTTP+HTTPS: https://www.boost.org/doc/libs/1_72_0/libs/beast/doc/html/beast/examples.html#beast.examples.servers -Config: https://www.boost.org/doc/libs/1_72_0/doc/html/property_tree/tutorial.html Certbot: https://certbot.eff.org/lets-encrypt/debianbuster-other - -Configfile configurable diff --git a/config.cpp b/config.cpp index edbe3c4..c71ce9e 100644 --- a/config.cpp +++ b/config.cpp @@ -3,7 +3,10 @@ #include #include +#include + namespace pt = boost::property_tree; +using namespace std::string_literals; void Config::readConfigfile(std::string filename) { @@ -13,15 +16,80 @@ void Config::readConfigfile(std::string filename) pt::ptree tree; - pt::read_xml(filename, tree); + pt::read_xml(filename, tree, pt::xml_parser::no_comments | pt::xml_parser::trim_whitespace); + // mandatory m_user = tree.get("webserver.user"); - m_group = tree.get("webserver.group1"); + m_group = tree.get("webserver.group"); + + // optional entries + auto elements = tree.get_child_optional("webserver"); + if (elements) { + for (const auto& element: *elements) { + if (element.first == "plugin-directory"s) { + m_plugin_directories.push_back(element.second.data()); + } else if (element.first == "sites"s) { + for (const auto& site: element.second) { + if (site.first != "site"s) + throw std::runtime_error(" expected in "); + Site site_struct; + for (const auto& x: site.second) { + if (x.first == "name"s) { + site_struct.name = x.second.data(); + } else if (x.first == "host"s) { + site_struct.host = x.second.data(); + } else if (x.first == "path"s) { + Path path; + auto attrs = x.second.get_child(""); + path.requested = attrs.get("requested"); + std::string type = attrs.get("type"); + if (type == "files") { + path.type = Files; + } else if (type == "plugin") { + path.type = Plugin; + } else + throw std::runtime_error("Unknown type: "s + type); + for (const auto& param: x.second) { + if (param.first.size() > 0 && param.first[0] != '<') // exclude meta-elements like + path.params[param.first.data()] = param.second.data(); + } + site_struct.paths.push_back(path); + } else + throw std::runtime_error("Unknown element: "s + x.first); + } + m_sites.push_back(site_struct); + } + } else if (element.first == "sockets"s) { + for (const auto& socket: element.second) { + if (socket.first != "socket"s) + throw std::runtime_error(" expected in "); + Socket socket_struct; + for (const auto& x: socket.second) { + if (x.first == "address"s) { + socket_struct.address = x.second.data(); + } else if (x.first == "port"s) { + socket_struct.port = x.second.data(); + } else if (x.first == "protocol"s) { + if (x.second.data() == "http"s) + socket_struct.protocol = HTTP; + else if (x.second.data() == "https"s) + socket_struct.protocol = HTTPS; + else + throw std::runtime_error("Unknown protocol: "s + x.second.data()); + } else + throw std::runtime_error("Unknown element: "s + x.first); + } + m_sockets.push_back(socket_struct); + } + } + } + } } Config::Config(const std::string& filename) { readConfigfile(filename); + dump(); } std::string Config::User() const @@ -33,3 +101,33 @@ std::string Config::Group() const { return m_group; } + +void Config::dump() const +{ + std::cout << "=== Configuration ===========================" << std::endl; + std::cout << "User: " << m_user << std::endl; + std::cout << "Group: " << m_user << std::endl; + + std::cout << "Plugin Directories:"; + for (const auto& dir: m_plugin_directories) + std::cout << " " << dir; + std::cout << std::endl; + + for (const auto& site: m_sites) { + std::cout << "Site: " << site.name << ": " << site.host << std::endl; + if (site.paths.size() == 0) + std::cout << " Warning: No paths configured." << std::endl; + for (const auto& path: site.paths) { + std::cout << " Path: " << path.requested << " -> " << ((path.type == Files) ? "files" : "plugin") << std::endl; + for (const auto& param: path.params) { + std::cout << " " << param.first << ": " << param.second << std::endl; + } + } + } + + for (const auto& socket: m_sockets) { + std::cout << "Socket: " << socket.address << ":" << socket.port << " (" << (socket.protocol == HTTP ? "HTTP" : "HTTPS") << ")" << std::endl; + } + std::cout << "=============================================" << std::endl; +} + diff --git a/config.h b/config.h index b1f17a3..e69b298 100644 --- a/config.h +++ b/config.h @@ -1,6 +1,41 @@ #pragma once #include +#include +#include + +enum PathType +{ + Files, // serve files + Plugin // delegate to plugin +}; + +struct Path +{ + std::string requested; // the requested path + PathType type; + std::unordered_map params; // what to serve, e.g. which filesystem path, or which plugin +}; + +struct Site +{ + std::string name; + std::string host; + std::vector paths; +}; + +enum SocketProtocol +{ + HTTP, + HTTPS +}; + +struct Socket +{ + std::string address; + std::string port; + SocketProtocol protocol; +}; class Config { @@ -10,6 +45,9 @@ class Config std::string m_user; std::string m_group; + std::vector m_plugin_directories; + std::vector m_sites; + std::vector m_sockets; public: Config(const std::string& filename); @@ -17,5 +55,7 @@ class Config // Data getters std::string User() const; std::string Group() const; + + void dump() const; }; diff --git a/webserver.conf b/webserver.conf index c3580c8..42bc383 100644 --- a/webserver.conf +++ b/webserver.conf @@ -1,14 +1,19 @@ - www-data + www-data www-data - /usr/lib/webserver/plugins + bf/usr/lib/webserver/plugins /usr/local/lib/webserver/plugins antcom.de antcom.de - /var/www/antcom.de - webbox + + /var/www/antcom.de + + + webbox + /var/lib/webbox +