From 1fcaed7a34cce8e55bb071d503bb583f715e7d37 Mon Sep 17 00:00:00 2001 From: Roland Reichwein Date: Sat, 4 Apr 2020 19:24:16 +0200 Subject: Serve configured sockets --- TODO | 3 --- config.cpp | 21 +++++++++++++++++++-- config.h | 5 +++-- http.cpp | 54 ++++++++++++++++++++++++------------------------------ http.h | 13 ++++++++++++- https.cpp | 57 +++++++++++++++++++++++---------------------------------- https.h | 21 ++++++++++++++++++++- server.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- server.h | 12 ++++++++++++ webserver.conf | 20 ++++++++++++-------- 10 files changed, 179 insertions(+), 83 deletions(-) diff --git a/TODO b/TODO index 737d2f3..1d083ca 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,4 @@ -HTTP+HTTPS: https://www.boost.org/doc/libs/1_72_0/libs/beast/doc/html/beast/examples.html#beast.examples.servers Certbot: https://certbot.eff.org/lets-encrypt/debianbuster-other Webbox Debian 10 alternative hosts www, lists, ... - -Selective sites per Socket diff --git a/config.cpp b/config.cpp index 17376d0..c478265 100644 --- a/config.cpp +++ b/config.cpp @@ -40,7 +40,7 @@ void Config::readConfigfile(std::string filename) if (x.first == "name"s) { site_struct.name = x.second.data(); } else if (x.first == "host"s) { - site_struct.host = x.second.data(); + site_struct.hosts.insert(x.second.data()); } else if (x.first == "path"s) { Path path; auto attrs = x.second.get_child(""); @@ -91,6 +91,15 @@ void Config::readConfigfile(std::string filename) } } } + + // expand socket sites + for (auto& socket: m_sockets) { + if (socket.serve_sites.empty()) { + for (const auto& site: m_sites) { + socket.serve_sites.push_back(site.name); + } + } + } } Config::Config(const std::string& filename) @@ -143,7 +152,10 @@ void Config::dump() const std::cout << std::endl; for (const auto& site: m_sites) { - std::cout << "Site: " << site.name << ": " << site.host << std::endl; + std::cout << "Site: " << site.name << ":"; + for (const auto& host: site.hosts) + std::cout << " " << host; + std::cout << std::endl; if (site.paths.size() == 0) std::cout << " Warning: No paths configured." << std::endl; for (const auto& path: site.paths) { @@ -160,6 +172,11 @@ void Config::dump() const std::cout << " Key: " << socket.key_path.generic_string() << std::endl; std::cout << " Cert: " << socket.cert_path.generic_string() << std::endl; } + std::cout << " Serving:"; + for (const auto& site: socket.serve_sites) { + std::cout << " " << site; + } + std::cout << std::endl; } std::cout << "=============================================" << std::endl; } diff --git a/config.h b/config.h index 98a99c0..a8d6a03 100644 --- a/config.h +++ b/config.h @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace fs = std::filesystem; @@ -23,7 +24,7 @@ struct Path struct Site { std::string name; - std::string host; + std::unordered_set hosts; std::vector paths; }; @@ -38,7 +39,7 @@ struct Socket std::string address; std::string port; SocketProtocol protocol; - std::vector serve_sites; // if empty, serve all configured sites // TODO: implement + std::vector serve_sites; // if empty, automatically expand to all configured sites fs::path cert_path; fs::path key_path; }; diff --git a/http.cpp b/http.cpp index 82e1a39..aea4e07 100644 --- a/http.cpp +++ b/http.cpp @@ -153,6 +153,7 @@ handle_request( // Build the path to the requested file std::string path = path_cat(doc_root, req.target()); + std::cout << "DEBUG: " << req["host"] << std::endl; if(req.target().back() == '/') path.append("index.html"); @@ -446,35 +447,28 @@ private: namespace HTTP { -int server(Config& config) -{ - // TODO: Config - auto const address = net::ip::make_address(config.Sockets()[0].address); - auto const port = static_cast(std::atoi(config.Sockets()[0].port.data())); - auto const doc_root = std::make_shared(config.Sites()[0].paths[0].params.at("target")); - auto const threads = std::max(1, config.Threads()); - - // The io_context is required for all I/O - net::io_context ioc{threads}; - - // Create and launch a listening port - std::make_shared( - ioc, - tcp::endpoint{address, port}, - doc_root)->run(); - - // Run the I/O service on the requested number of threads - std::vector v; - v.reserve(threads - 1); - for(auto i = threads - 1; i > 0; --i) - v.emplace_back( - [&ioc] - { - ioc.run(); - }); - ioc.run(); - - return EXIT_SUCCESS; -} + Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socket): ::Server(config, ioc), m_socket(socket) + { + } + + Server::~Server() + { + } + + int Server::start() + { + // TODO: Config + auto const address = net::ip::make_address(m_socket.address); + auto const port = static_cast(std::atoi(m_socket.port.data())); + auto const doc_root = std::make_shared(m_config.Sites()[0].paths[0].params.at("target")); + + // Create and launch a listening port + std::make_shared( + m_ioc, + tcp::endpoint{address, port}, + doc_root)->run(); + + return EXIT_SUCCESS; + } } // namespace HTTP diff --git a/http.h b/http.h index 229d48e..d98170d 100644 --- a/http.h +++ b/http.h @@ -1,9 +1,20 @@ #pragma once +#include +#include + #include "config.h" +#include "server.h" namespace HTTP { -int server(Config& config); +class Server: public ::Server +{ + const Socket& m_socket; +public: + Server(Config& config, boost::asio::io_context& ioc, const Socket& socket); + virtual ~Server(); + int start() override; +}; } // namespace HTTP diff --git a/https.cpp b/https.cpp index 0c3b97b..b4e77f9 100644 --- a/https.cpp +++ b/https.cpp @@ -515,42 +515,31 @@ private: namespace HTTPS { -int server(Config& config) +Server::Server(Config& config, boost::asio::io_context& ioc, const Socket& socket): ::Server(config, ioc), m_socket(socket) { - // TODO: Config - auto const address = net::ip::make_address(config.Sockets()[0].address); - auto const port = static_cast(std::atoi(config.Sockets()[0].port.data())); - auto const doc_root = std::make_shared(config.Sites()[0].paths[0].params.at("target")); - auto const threads = std::max(1, config.Threads()); - - // The io_context is required for all I/O - net::io_context ioc{threads}; - - // The SSL context is required, and holds certificates - ssl::context ctx{ssl::context::tlsv13}; - - // This holds the self-signed certificate used by the server - load_server_certificate(ctx, config.Sockets()[0].cert_path, config.Sockets()[0].key_path); // TODO: config - - // Create and launch a listening port - std::make_shared( - ioc, - ctx, - tcp::endpoint{address, port}, - doc_root)->run(); - - // Run the I/O service on the requested number of threads - std::vector v; - v.reserve(threads - 1); - for(auto i = threads - 1; i > 0; --i) - v.emplace_back( - [&ioc] - { - ioc.run(); - }); - ioc.run(); + // This holds the self-signed certificate used by the server + load_server_certificate(m_ctx, m_socket.cert_path, m_socket.key_path); +} + +Server::~Server() +{ +} - return EXIT_SUCCESS; +int Server::start() +{ + // TODO: Config + auto const address = net::ip::make_address(m_socket.address); + auto const port = static_cast(std::atoi(m_socket.port.data())); + auto const doc_root = std::make_shared(m_config.Sites()[0].paths[0].params.at("target")); + + // Create and launch a listening port + std::make_shared( + m_ioc, + m_ctx, + tcp::endpoint{address, port}, + doc_root)->run(); + + return EXIT_SUCCESS; } } // namespace HTTPS diff --git a/https.h b/https.h index 3621f33..e137463 100644 --- a/https.h +++ b/https.h @@ -1,9 +1,28 @@ #pragma once +#include +#include +#include +#include + #include "config.h" +#include "server.h" + +namespace ssl = boost::asio::ssl; // from namespace HTTPS { -int server(Config& config); +class Server: public ::Server +{ + // The SSL context is required, and holds certificates + ssl::context m_ctx{ssl::context::tlsv13}; + const Socket& m_socket; + +public: + Server(Config& config, boost::asio::io_context& ioc, const Socket& socket); + virtual ~Server(); + + int start() override; +}; } diff --git a/server.cpp b/server.cpp index 2ad9bcd..bbe7223 100644 --- a/server.cpp +++ b/server.cpp @@ -1,10 +1,62 @@ +#include +#include +#include +#include +#include +#include +#include + +#include +#include + #include "server.h" #include "http.h" #include "https.h" +namespace beast = boost::beast; // from +namespace http = beast::http; // from +namespace net = boost::asio; // from +namespace ssl = boost::asio::ssl; // from +using tcp = boost::asio::ip::tcp; // from + +Server::Server(Config& config, boost::asio::io_context& ioc): m_config(config), m_ioc(ioc) +{ +} + +Server::~Server() +{ +} + int server(Config& config) { - //return HTTP::server(config); - return HTTPS::server(config); + auto const threads = std::max(1, config.Threads()); + + boost::asio::io_context ioc{threads}; + + std::vector> servers; + + const auto& sockets {config.Sockets()}; + for (const auto& socket: sockets) { + if (socket.protocol == SocketProtocol::HTTP) { + servers.push_back(std::make_shared(config, ioc, socket)); + } else { + servers.push_back(std::make_shared(config, ioc, socket)); + } + servers.back()->start(); + } + + // Run the I/O service on the requested number of threads + std::vector v; + v.reserve(threads - 1); + for(auto i = threads - 1; i > 0; --i) + v.emplace_back( + [&ioc] + { + ioc.run(); + }); + ioc.run(); + + return EXIT_SUCCESS; } + diff --git a/server.h b/server.h index 5ad21ff..0dcf3dd 100644 --- a/server.h +++ b/server.h @@ -6,4 +6,16 @@ using namespace std::string_literals; static const std::string VersionString{ "Webserver "s + std::string{VERSION} }; +class Server +{ +protected: + Config& m_config; + boost::asio::io_context& m_ioc; + +public: + Server(Config& config, boost::asio::io_context& ioc); + virtual ~Server(); + virtual int start() = 0; +}; + int server(Config& config); diff --git a/webserver.conf b/webserver.conf index 2036f67..46d4120 100644 --- a/webserver.conf +++ b/webserver.conf @@ -11,6 +11,8 @@ antcom.de lists.antcom.de + antcom.de + www.antcom.de /home/ernie/homepage/test @@ -21,11 +23,15 @@ --> - - -- cgit v1.2.3