diff options
Diffstat (limited to 'tests/webserverprocess.cpp')
-rw-r--r-- | tests/webserverprocess.cpp | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/tests/webserverprocess.cpp b/tests/webserverprocess.cpp new file mode 100644 index 0000000..c91275b --- /dev/null +++ b/tests/webserverprocess.cpp @@ -0,0 +1,221 @@ +#include "webserverprocess.h" + +#include <boost/test/data/dataset.hpp> +#include <boost/test/data/monomorphic.hpp> +#include <boost/test/data/test_case.hpp> + +#include <boost/algorithm/string.hpp> +#include <boost/beast/core.hpp> +#include <boost/beast/http.hpp> +#include <boost/beast/websocket.hpp> +#include <boost/beast/websocket/ssl.hpp> +#include <boost/beast/ssl.hpp> +#include <boost/beast/version.hpp> +#include <boost/asio/buffer.hpp> +#include <boost/asio/buffers_iterator.hpp> +#include <boost/asio/connect.hpp> +#include <boost/asio/ip/tcp.hpp> +#include <boost/asio/ssl/error.hpp> +#include <boost/asio/ssl/stream.hpp> +#include <boost/property_tree/ptree.hpp> +#include <boost/property_tree/xml_parser.hpp> + +#include <fmt/core.h> + +#include <chrono> +#include <exception> +#include <filesystem> +#include <iostream> +#include <memory> +#include <mutex> +#include <sstream> +#include <stdexcept> +#include <string> +#include <thread> + +#include <ext/stdio_filebuf.h> +#include <signal.h> +#include <sys/wait.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> + +#include <libreichwein/file.h> +#include <libreichwein/process.h> + +#include "webserver.h" +#include "helper.h" + +using namespace std::string_literals; +namespace fs = std::filesystem; +namespace pt = boost::property_tree; +using namespace boost::unit_test; +using namespace Reichwein; + +void WebserverProcess::init(const std::string& config) +{ + m_config = config; + File::setFile(testConfigFilename, config); + + // test self signed certificate + File::setFile(testCertFilename, R"(-----BEGIN CERTIFICATE----- +MIIC4zCCAcugAwIBAgIUeS9y+EsFWxf+foEx6SJ/R56rmX8wDQYJKoZIhvcNAQEL +BQAwADAgFw0yMzAxMDYxNzIwNTFaGA8yMDUwMDUyNDE3MjA1MVowADCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALiZSICAcXng9j7zAb873U4TpuzvRVfh +xS3gEhxqNPs6+ZQ43nAxDSdafzfGxpTkElTt/REj4oEOLw+QWI/jfbe4gDRDzf6V +ij0fVuzp02JtJSS+dNrLv17NufBydOyD8oDrPehVrPlrZQhhkYMvLHAim+wikT2O +s0es2R+avixxAZvx5EYgHba9T7R/pC/lA4BI3lEbVKjDA83hZvjPH1YdK+RYQS2g +Jygdhe8qOSswXIwFAF3MMBpwRD3mz+vAJZP3lpBGsn+asO6Xd/5cjC8msgomS8Ji +c9DMMNlrE1WU73wVG9n0OJcke2XEtzARVKJLlBPsug4oxDev6O4GakkCAwEAAaNT +MFEwHQYDVR0OBBYEFE4i7Gtyn30qpIkH6f0/wuFA45pjMB8GA1UdIwQYMBaAFE4i +7Gtyn30qpIkH6f0/wuFA45pjMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEL +BQADggEBAIlGv4b2yLmTOrXOPNst2y3J+GiRvuMKoAfDt5KLxUhbCmPgJzGDWn0l +60xXBX/t2uo3dQa9yAIW64RqhEQX7uja/7B3PmJZlgF7+owvT8OZA4+UN1lLUvY4 +V7mUzuKuqo5jcX8EmZnHrJ4TGZ0dXbT1hAUgqIjnDChjWyvs4B9zZL5FTisPUic7 +MU+FcpKJ5M6iJ150d9hzLiwmJyPLkW5Grq0Jh22njUQwWW2vIMn4cA3CyS64+oi2 +DNnDgde3mYxXL8Oki7CbeCTpmUXcBHmQtWOvKZPCsOzMF4moTLC4DdElvOpwKCAK +ABd6rubkarwvDV7wEo1eSuAHPZ/KhGo= +-----END CERTIFICATE----- +)"); + File::setFile(testKeyFilename, R"(-----BEGIN PRIVATE KEY----- +MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC4mUiAgHF54PY+ +8wG/O91OE6bs70VX4cUt4BIcajT7OvmUON5wMQ0nWn83xsaU5BJU7f0RI+KBDi8P +kFiP4323uIA0Q83+lYo9H1bs6dNibSUkvnTay79ezbnwcnTsg/KA6z3oVaz5a2UI +YZGDLyxwIpvsIpE9jrNHrNkfmr4scQGb8eRGIB22vU+0f6Qv5QOASN5RG1SowwPN +4Wb4zx9WHSvkWEEtoCcoHYXvKjkrMFyMBQBdzDAacEQ95s/rwCWT95aQRrJ/mrDu +l3f+XIwvJrIKJkvCYnPQzDDZaxNVlO98FRvZ9DiXJHtlxLcwEVSiS5QT7LoOKMQ3 +r+juBmpJAgMBAAECggEACjs5suCbmYAb2d2VZlRitdP+Q6HX37D0YTBrBI7o6JdK +U7oqrwBy/JBGHpDqewBgmTs3FGr/H/zJpDTRickXs9X6qhrreQ2wA6b/5gHoPMt0 +nHKfbqyOCuq/YGmxnBXMnDNdoynTfGAE0af5vRIBZiYu6vG4B9fHzURR5O/qVDNn +WqJ+2Y8AAf4mJDCBEvJz2RaZwSq788i/d8oTSeCk93TDF+GHhUq6ymkORACj76ws +8ohfoNQIG1VhdcTK2GOQjqctEFUm54t9N1nxD6VavMu5DlSSVsPTDbYuE5U4cy3T +ThDtoYJgwz5KRflklwl3xoDJVx3B5wMUaqviRp6l0QKBgQC6MPG+EV2drsHwG0Wg +gnP4uCSuFAfWBlHAQyZv5PMQBNfM8YjyMyL+O7cggGNJSOZr/X30EqoBe+LXrL3X +Gtix8F1Ed0fbAarAgxIwq8MktzmastDq4XS+zwYPZ7UTbmbqvT3VYPga4Sh90fyY +nPJpqZvhvGzQX22yeHS7vTSQOQKBgQD9z36EIYMuLl0HJK6gfjGHsy/Rx7bw1TmP +aHmuF8Ra7rpDSOym0ImKWTOLEoLlQUsMz/FuVLCGP/ACjMFKsqh3Zy/0hVJOMDMR +Z+ODT28Hcz4AMcTYDvcTYd70HhhZL+/eFCVk8Nk164saMuhifAkOgvwfaYs0m3ue +S9jxlZKKkQKBgHgBzf6k8MMOfaAF4/XVv2wDPFkbPgW74vtaDK84UVX02ScWUx9Q +yHA3Cwye09/LZgEazREA6qS0NfyvMVkwy5S9CVB01VKam3UjxhiqzMegdTd5o+CQ +WpAVnaFWRcb1dM4+FVmv+5pPn6qhKv8uwaxLDtcLfNM9ftX2f77176g5AoGADWtQ +DBpdfi6TWpJU7UVexwbxS00c3gTYAz4J2OuGxSwECxSq9nLmIrtunza+VvKpziac +ZDH0F1UAEpJwkct6Xr3E6k+2N04TFSOCAupLO4CbUZVQDABWjd7J0+xXaze+neZA +x+J4CYLHmv4ADVzzeaHxRJPm+UQTOB5YfQVkdxECgYBv3QuUMiBGKWgeheP4nAFU +SVgqGBQwAtqb5DR1YVJ4LFPt+jyrQMby6mqSlzENYcidSP3Ogn22CvST+bAjbf6D +D/ae1zeOHBls00ILHANv1Z/hXcEkiKnZdeP6O43xBfCS+Lps5daXgUbC0kw2R09S +VZTqPHmb+db0rFA3XlAg2A== +-----END PRIVATE KEY----- +)"); + start(); +} + +WebserverProcess::WebserverProcess(const std::string& config): m_pid{} +{ + init(config); +} + +WebserverProcess::WebserverProcess(): m_pid{} +{ + std::string config{R"CONFIG(<webserver> + <user>www-data</user> + <group>www-data</group> + <threads>10</threads> + <statisticspath>stats.db</statisticspath> + <plugin-directory>../plugins</plugin-directory> + <sites> + <site> + <name>localhost</name> + <host>ip6-localhost</host> + <host>localhost</host> + <host>127.0.0.1</host> + <host>[::1]</host> + <path requested="/"> + <plugin>static-files</plugin> + <target>.</target> + </path> + <certpath>testchain.pem</certpath> + <keypath>testkey.pem</keypath> + </site> + </sites> + <sockets> + <socket> + <address>127.0.0.1</address> + <port>8080</port> + <protocol>http</protocol> + <site>localhost</site> + </socket> + <socket> + <address>::1</address> + <port>8080</port> + <protocol>http</protocol> + <site>localhost</site> + </socket> + <socket> + <address>127.0.0.1</address> + <port>8081</port> + <protocol>https</protocol> + <site>localhost</site> + </socket> + <socket> + <address>::1</address> + <port>8081</port> + <protocol>https</protocol> + <site>localhost</site> + </socket> + </sockets> +</webserver> +)CONFIG"}; + init(config); +} + +WebserverProcess::~WebserverProcess() +{ + stop(); + fs::remove(testConfigFilename); + fs::remove(testCertFilename); + fs::remove(testKeyFilename); +} + +void WebserverProcess::start() +{ + if (m_pid != 0) + throw std::runtime_error("Process already running, so it can't be started"); + + m_pid = fork(); + if (m_pid < 0) + throw std::runtime_error("Fork unsuccessful."); + + if (m_pid == 0) { // child process branch + char* argv[] = {(char*)"webserver", (char*)"-c", (char*)"./webserver.conf"}; + webserver(sizeof(argv) / sizeof(char*), argv); + exit(0); + } + + // wait for server to start up + if (int port{port_from_config(m_config)}; port >= 0) + wait_for_pid_listening_on(m_pid, port); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); +} + +void WebserverProcess::stop() +{ + if (m_pid == 0) + throw std::runtime_error("Process not running, so it can't be stopped"); + + if (kill(m_pid, SIGTERM) != 0) + throw std::runtime_error("Unable to kill process"); + + if (int result = waitpid(m_pid, NULL, 0); result != m_pid) + throw std::runtime_error("waitpid returned "s + std::to_string(result)); + + m_pid = 0; +} + +bool WebserverProcess::is_running() +{ + if (m_pid == 0) + return false; + + return Reichwein::Process::is_running(m_pid); +} + |