summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--config.cpp102
-rw-r--r--config.h40
-rw-r--r--webserver.conf13
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 <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
+#include <iostream>
+
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<std::string>("webserver.user");
- m_group = tree.get<std::string>("webserver.group1");
+ m_group = tree.get<std::string>("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("<site> expected in <sites>");
+ 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("<xmlattr>");
+ path.requested = attrs.get<std::string>("requested");
+ std::string type = attrs.get<std::string>("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 <xmlattr>
+ 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("<socket> expected in <sockets>");
+ 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 <string>
+#include <unordered_map>
+#include <vector>
+
+enum PathType
+{
+ Files, // serve files
+ Plugin // delegate to plugin
+};
+
+struct Path
+{
+ std::string requested; // the requested path
+ PathType type;
+ std::unordered_map<std::string, std::string> params; // what to serve, e.g. which filesystem path, or which plugin
+};
+
+struct Site
+{
+ std::string name;
+ std::string host;
+ std::vector<Path> 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<std::string> m_plugin_directories;
+ std::vector<Site> m_sites;
+ std::vector<Socket> 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 @@
<webserver>
- <user>www-data<user>
+ <user>www-data</user>
<group>www-data</group>
- <plugin-directory>/usr/lib/webserver/plugins</plugin-directory>
+ <plugin-directory><a c="d">b<e>f</e></a>/usr/lib/webserver/plugins</plugin-directory>
<plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory>
<sites>
<site>
<name>antcom.de</name>
<host>antcom.de</host>
- <path requested="/" type="files">/var/www/antcom.de</path>
- <path requested="/webbox" type="plugin">webbox</path>
+ <path requested="/" type="files">
+ <target>/var/www/antcom.de</target>
+ </path>
+ <path requested="/webbox" type="plugin">
+ <plugin>webbox</plugin>
+ <target>/var/lib/webbox</target>
+ </path>
</site>
<!--
<site>