diff options
| -rw-r--r-- | config.cpp | 12 | ||||
| -rw-r--r-- | config.h | 13 | ||||
| -rw-r--r-- | https.cpp | 4 | ||||
| -rw-r--r-- | tests/test-auth.cpp | 12 | ||||
| -rw-r--r-- | tests/test-config.cpp | 230 | ||||
| -rw-r--r-- | webserver.cpp | 3 | 
6 files changed, 257 insertions, 17 deletions
| @@ -9,6 +9,7 @@  #include <exception>  #include <iostream> +namespace fs = std::filesystem;  namespace pt = boost::property_tree;  using namespace std::string_literals; @@ -26,15 +27,16 @@ namespace {  } // anonymous namespace -void Config::readConfigfile(std::string filename) +void Config::readConfigfile(const std::filesystem::path& filename)  { - if (filename == "") { -  filename = default_filename; + fs::path used_filename{filename}; + if (used_filename.empty()) { +  used_filename = default_filename;   }   pt::ptree tree; - pt::read_xml(filename, tree, pt::xml_parser::no_comments | pt::xml_parser::trim_whitespace); + pt::read_xml(used_filename, tree, pt::xml_parser::no_comments | pt::xml_parser::trim_whitespace);   // mandatory   m_user = tree.get<std::string>("webserver.user"); @@ -203,7 +205,7 @@ void Config::create_look_up_table()   }  } -Config::Config(const std::string& filename) +Config::Config(const std::filesystem::path& filename)  {   readConfigfile(filename);   dump(); @@ -6,8 +6,7 @@  #include <unordered_set>  #include <vector> -namespace fs = std::filesystem; - +// URL path, not FS  struct Path  {   std::string requested; // the requested path @@ -21,8 +20,8 @@ struct Site   // std::string name; is the index in the m_sites map   std::unordered_set<std::string> hosts;   std::vector<Path> paths; - fs::path cert_path; - fs::path key_path; + std::filesystem::path cert_path; + std::filesystem::path key_path;  };  enum class SocketProtocol @@ -43,9 +42,9 @@ struct Socket  class Config  { - const std::string default_filename{"/etc/webserver.conf"}; + const std::filesystem::path default_filename{"/etc/webserver.conf"}; - void readConfigfile(std::string filename); + void readConfigfile(const std::filesystem::path& filename);   void expand_socket_sites();   void validate();   void create_look_up_table(); @@ -58,7 +57,7 @@ class Config   std::vector<Socket> m_sockets;   public: -  Config(const std::string& filename); +  Config(const std::filesystem::path& filename);    // Data getters    std::string User() const; @@ -27,6 +27,7 @@  #include <algorithm>  #include <cstddef>  #include <cstdlib> +#include <filesystem>  #include <functional>  #include <iostream>  #include <memory> @@ -35,6 +36,7 @@  #include <thread>  #include <vector> +namespace fs = std::filesystem;  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> @@ -468,7 +470,7 @@ private:  /*  Load a signed certificate into the ssl context, and configure      the context for use with a server.  */ -void load_server_certificate(boost::asio::ssl::context& ctx, fs::path cert_path, fs::path key_path) +void load_server_certificate(boost::asio::ssl::context& ctx, const fs::path& cert_path, const fs::path& key_path)  {      /*          The certificate was generated from CMD.EXE on Windows 10 using: diff --git a/tests/test-auth.cpp b/tests/test-auth.cpp index 8397b35..37bc02f 100644 --- a/tests/test-auth.cpp +++ b/tests/test-auth.cpp @@ -18,7 +18,16 @@ class AuthFixture  public:   AuthFixture(){}   ~AuthFixture(){} - void setup(){} + void setup() + { +  int filedes[2]; +  if (pipe(filedes) == -1) +   throw std::runtime_error("Pipe error"); +  if (close(2) == -1) +   throw std::runtime_error("Can't close stderr"); +  if (dup(filedes[1]) == -1) +   throw std::runtime_error("Replace stdout w/ pipe input"); + }   void teardown(){}  }; @@ -36,6 +45,7 @@ BOOST_FIXTURE_TEST_CASE(validate, AuthFixture)  {   BOOST_CHECK(Auth::validate("t5MMkLQXzYkdw", "abc")); + BOOST_CHECK(!Auth::validate("", ""));   BOOST_CHECK(!Auth::validate("abc", "abc"));   BOOST_CHECK(!Auth::validate("t5MNkLQXzYkdw", "abc"));  } diff --git a/tests/test-config.cpp b/tests/test-config.cpp index ddba9c9..ddae1c8 100644 --- a/tests/test-config.cpp +++ b/tests/test-config.cpp @@ -6,23 +6,249 @@  #include <boost/property_tree/ptree.hpp>  #include <boost/property_tree/xml_parser.hpp> +#include <filesystem>  #include <sstream>  #include <string>  #include "config.h" +#include "libreichwein/file.h" +  using namespace std::string_literals; +namespace fs = std::filesystem; + +const fs::path testConfigFilename{"test-webserver.conf"};  class ConfigFixture  {  public:   ConfigFixture(){}   ~ConfigFixture(){} - void setup(){} - void teardown(){} + void setup() + { +  int filedes[2]; +  if (pipe(filedes) == -1) +   throw std::runtime_error("Pipe error"); +  if (close(1) == -1) +   throw std::runtime_error("Can't close stdout"); +  if (dup(filedes[1]) == -1) +   throw std::runtime_error("Replace stdout w/ pipe input"); + } + void teardown() + { +  std::error_code ec; +  fs::remove(testConfigFilename); + }  };  BOOST_FIXTURE_TEST_CASE(config, ConfigFixture)  { + Reichwein::File::setFile(testConfigFilename, R"CONFIG( +<webserver> + <user>user1</user> + <group>www-data</group> + <threads>10</threads> + <!-- + <plugin-directory>/usr/lib/webserver/plugins</plugin-directory> + <plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory> + --> + <plugin-directory>plugins</plugin-directory> + <sites> +  <site> +   <name>antcom.de</name> +   <host>lists.antcom.de</host> +   <host>antcom.de</host> +   <host>www.antcom.de</host> +   <host>ip6-localhost</host> +   <host>127.0.0.1</host> +   <host>[::1]</host> +   <host>reichwein.mooo.com</host> +   <host>[2001:a61:410:c001:5e51:4fff:fea2:ec7f]</address> + +   <path requested="/"> +    <plugin>static-files</plugin> +    <target>/home/ernie/homepage/test</target> +   </path> + +   <path requested="/webbox1"> +    <plugin>webbox</plugin> +    <target>/home/ernie/testbox</target> +    <WEBBOX_NAME>Testbox1</WEBBOX_NAME> +    <WEBBOX_READONLY>0</WEBBOX_READONLY> +    <WEBBOX_STATIC_HTML>/home/ernie/code/webserver/plugins/webbox/html</WEBBOX_STATIC_HTML> +    <auth login="abc" password="p3p0Jka3YM5Fk"/> +   </path> +   <path requested="/webbox2"> +    <plugin>webbox</plugin> +    <target>/home/ernie/testbox</target> +    <WEBBOX_NAME>Testbox1</WEBBOX_NAME> +    <WEBBOX_READONLY>1</WEBBOX_READONLY> +    <WEBBOX_STATIC_HTML>/home/ernie/code/webserver/plugins/webbox/html</WEBBOX_STATIC_HTML> +   </path> +   <path requested="/blog"> +    <plugin>weblog</plugin> +    <target>/home/ernie/testblog</target> +    <WEBLOG_NAME>Roland Reichweins Blog</WEBLOG_NAME> +    <WEBLOG_KEYWORDS>Roland Reichwein, Blog</WEBLOG_KEYWORDS> +   </path> +   <path requested="/stats"> +    <plugin>statistics</plugin> +    <target></target> +   </path> +   <path requested="/cgi-bin"> +    <plugin>cgi</plugin> +    <target>/home/ernie/code/webserver/cgi-bin</target> +    <auth login="abc" password="p3p0Jka3YM5Fk"/> +   </path> +   <path requested="/fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9000</target> +   </path> +   <path requested="/unix"> +    <plugin>fcgi</plugin> +    <target>/home/ernie/code/webserver/fastcgi/socket</target> +   </path> +   <path requested="/php"> +    <plugin>fcgi</plugin> +    <target>/run/php/php-fpm.sock</target> +   </path> + +   <path requested="/cgi-bin/admin/echo.fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9001</target> +   </path> +   <path requested="/cgi-bin/admin/admin.fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9002</target> +   </path> +   <path requested="/cgi-bin/shop.fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9003</target> +   </path> +   <path requested="/webshop"> +    <plugin>static-files</plugin> +    <target>/home/ernie/code/webshop/html</target> +   </path> + +   <path requested="/downtube"> +    <plugin>static-files</plugin> +    <target>/home/ernie/code/downtube/html</target> +   </path> +   <path requested="/downtube/downtube.fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9004</target> +   </path> + +   <path requested="/whiteboard"> +    <plugin>static-files</plugin> +    <target>/home/ernie/code/whiteboard/html</target> +   </path> +   <path requested="/whiteboard/whiteboard.fcgi"> +    <plugin>fcgi</plugin> +    <target>127.0.0.1:9014</target> +   </path> + +   <path requested="/redirect1"> +    <plugin>redirect</plugin> +    <target>https://www.antcom.de/</target> +    <STATUS_CODE>301</STATUS_CODE> +    <MESSAGE>Redirecting to antcom.de ...</MESSAGE> +   </path> +   <certpath>/home/ernie/code/webserver/fullchain.pem</certpath> +   <keypath>/home/ernie/code/webserver/privkey.pem</keypath> +  </site> +  <site> +   <name>marx</name> +   <host>marx.antcom.de</host> +   <host>marx1.antcom.de</host> +   <host>localhost</host> +   <path requested="/"> +    <plugin>static-files</plugin> +    <target>/home/ernie/homepage/test1</target> +   </path> +   <path requested="/cgi-bin"> +    <plugin>cgi</plugin> +    <target>/home/ernie/code/webserver/cgi-bin</target> +   </path> +   <path requested="/cgit"> +    <plugin>cgi</plugin> +    <target>/usr/lib/cgit/cgit.cgi</target> +   </path> +   <path requested="/cgit-css"> +    <plugin>static-files</plugin> +    <target>/usr/share/cgit</target> +   </path> +   <certpath>/home/ernie/code/webserver/cert.pem</certpath> +   <keypath>/home/ernie/code/webserver/key.pem</keypath> +  </site> + </sites> + <sockets> +  <socket> +   <address>127.0.0.1</address> +   <port>8080</port> +   <protocol>http</protocol> +    +   <site>antcom.de</site> +   <site>marx</site> + +  </socket> +  <socket> +   <address>2001:a61:410:c001:5e51:4fff:fea2:ec7f</address> +   <port>80</port> +   <protocol>http</protocol> +   <site>antcom.de</site> +  </socket> +  <socket> +   <address>::1</address> +   <port>8080</port> +   <protocol>http</protocol> +   <!-- +   <site>antcom.de</site> +   <site>reichwein.it</site> +   --> +  </socket> +  <socket> +   <address>127.0.0.1</address> +   <port>8081</port> +   <protocol>https</protocol> +  </socket> +  <socket> +   <address>::1</address> +   <port>8081</port> +   <protocol>https</protocol> +  </socket> +  <socket> +   <address>127.0.0.1</address> +   <port>443</port> +   <protocol>https</protocol> +  </socket> + </sockets> +</webserver> + +)CONFIG"); + + Config config{testConfigFilename}; + + BOOST_CHECK_EQUAL(config.User(), "user1"); + BOOST_CHECK_EQUAL(config.Group(), "www-data"); + BOOST_CHECK_EQUAL(config.Threads(), 10); + + auto pd{config.PluginDirectories()}; + BOOST_CHECK_EQUAL(pd.size(), 1); + BOOST_CHECK_EQUAL(pd[0], "plugins"); +  + auto sites{config.Sites()}; + BOOST_CHECK_EQUAL(sites.size(), 2); +  + auto sockets{config.Sockets()}; + BOOST_CHECK_EQUAL(sockets.size(), 4); // 2 privileged ports skipped + + const Path& p {config.GetPath(sockets[0], "antcom.de", "/webbox1/path1/abc.txt")}; + BOOST_CHECK_EQUAL(p.requested, "/webbox1"); + + BOOST_CHECK_EQUAL(config.PluginIsConfigured("webbox"), true); + BOOST_CHECK_EQUAL(config.PluginIsConfigured("webmux"), false); + + (void)config.dump();  } diff --git a/webserver.cpp b/webserver.cpp index 4591fc9..bfa3b8c 100644 --- a/webserver.cpp +++ b/webserver.cpp @@ -3,6 +3,7 @@  #include "server.h"  #include "plugin.h" +#include <filesystem>  #include <exception>  #include <iostream>  #include <string> @@ -29,7 +30,7 @@ int webserver(int argc, char* argv[])   try {    //initlocale(); // TODO: breaks plugins -  std::string config_filename; +  std::filesystem::path config_filename;    if (!(argc == 1 || argc == 3)) {     usage(); | 
