summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--TODO3
-rw-r--r--config.cpp21
-rw-r--r--config.h5
-rw-r--r--http.cpp54
-rw-r--r--http.h13
-rw-r--r--https.cpp57
-rw-r--r--https.h21
-rw-r--r--server.cpp56
-rw-r--r--server.h12
-rw-r--r--webserver.conf20
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("<xmlattr>");
@@ -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 <filesystem>
#include <string>
#include <unordered_map>
+#include <unordered_set>
#include <vector>
namespace fs = std::filesystem;
@@ -23,7 +24,7 @@ struct Path
struct Site
{
std::string name;
- std::string host;
+ std::unordered_set<std::string> hosts;
std::vector<Path> paths;
};
@@ -38,7 +39,7 @@ struct Socket
std::string address;
std::string port;
SocketProtocol protocol;
- std::vector<std::string> serve_sites; // if empty, serve all configured sites // TODO: implement
+ std::vector<std::string> 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<unsigned short>(std::atoi(config.Sockets()[0].port.data()));
- auto const doc_root = std::make_shared<std::string>(config.Sites()[0].paths[0].params.at("target"));
- auto const threads = std::max<int>(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<listener>(
- ioc,
- tcp::endpoint{address, port},
- doc_root)->run();
-
- // Run the I/O service on the requested number of threads
- std::vector<std::thread> 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<unsigned short>(std::atoi(m_socket.port.data()));
+ auto const doc_root = std::make_shared<std::string>(m_config.Sites()[0].paths[0].params.at("target"));
+
+ // Create and launch a listening port
+ std::make_shared<listener>(
+ 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 <boost/asio/dispatch.hpp>
+#include <boost/asio/strand.hpp>
+
#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<unsigned short>(std::atoi(config.Sockets()[0].port.data()));
- auto const doc_root = std::make_shared<std::string>(config.Sites()[0].paths[0].params.at("target"));
- auto const threads = std::max<int>(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<listener>(
- ioc,
- ctx,
- tcp::endpoint{address, port},
- doc_root)->run();
-
- // Run the I/O service on the requested number of threads
- std::vector<std::thread> 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<unsigned short>(std::atoi(m_socket.port.data()));
+ auto const doc_root = std::make_shared<std::string>(m_config.Sites()[0].paths[0].params.at("target"));
+
+ // Create and launch a listening port
+ std::make_shared<listener>(
+ 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 <boost/asio/dispatch.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/beast/ssl.hpp>
+#include <boost/asio/ssl.hpp>
+
#include "config.h"
+#include "server.h"
+
+namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
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 <boost/beast/core.hpp>
+#include <boost/beast/http.hpp>
+#include <boost/beast/version.hpp>
+#include <boost/beast/ssl.hpp>
+#include <boost/asio/dispatch.hpp>
+#include <boost/asio/strand.hpp>
+#include <boost/config.hpp>
+
+#include <thread>
+#include <vector>
+
#include "server.h"
#include "http.h"
#include "https.h"
+namespace beast = boost::beast; // from <boost/beast.hpp>
+namespace http = beast::http; // from <boost/beast/http.hpp>
+namespace net = boost::asio; // from <boost/asio.hpp>
+namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
+using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
+
+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<int>(1, config.Threads());
+
+ boost::asio::io_context ioc{threads};
+
+ std::vector<std::shared_ptr<Server>> servers;
+
+ const auto& sockets {config.Sockets()};
+ for (const auto& socket: sockets) {
+ if (socket.protocol == SocketProtocol::HTTP) {
+ servers.push_back(std::make_shared<HTTP::Server>(config, ioc, socket));
+ } else {
+ servers.push_back(std::make_shared<HTTPS::Server>(config, ioc, socket));
+ }
+ servers.back()->start();
+ }
+
+ // Run the I/O service on the requested number of threads
+ std::vector<std::thread> 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 @@
<site>
<name>antcom.de</name>
<host>lists.antcom.de</host>
+ <host>antcom.de</host>
+ <host>www.antcom.de</host>
<path requested="/" type="files">
<target>/home/ernie/homepage/test</target>
</path>
@@ -21,11 +23,15 @@
</path>
-->
</site>
- <!--
<site>
- <name>reichwein.it</name>
- <host>reichwein.it</host>
+ <name>marx</name>
+ <host>marx.antcom.de</host>
+ <path requested="/" type="files">
+ <target>/home/ernie/homepage/test1</target>
+ </path>
</site>
+ <!--
+ reichwein.it
danielareichwein.de
rolandreichwein.de
kneipenband.com
@@ -36,20 +42,18 @@
<address>127.0.0.1</address>
<port>8080</port>
<protocol>http</protocol>
- <certpath>/home/ernie/code/webserver/fullchain.pem</certpath>
- <keypath>/home/ernie/code/webserver/privkey.pem</keypath>
<!--
<site>antcom.de</site>
<site>reichwein.it</site>
-->
</socket>
- <!--
<socket>
<address>127.0.0.1</address>
- <port>443</port>
+ <port>8081</port>
<protocol>https</protocol>
+ <certpath>/home/ernie/code/webserver/fullchain.pem</certpath>
+ <keypath>/home/ernie/code/webserver/privkey.pem</keypath>
</socket>
- -->
</sockets>
</webserver>