summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--config.cpp11
-rw-r--r--config.h3
-rw-r--r--debian/webserver.conf1
-rw-r--r--server.cpp2
-rw-r--r--statistics.cpp13
-rw-r--r--statistics.h4
-rw-r--r--tests/test-config.cpp1
-rw-r--r--tests/test-statistics.cpp69
-rw-r--r--tests/test-webserver.cpp1
-rw-r--r--webserver.conf1
10 files changed, 98 insertions, 8 deletions
diff --git a/config.cpp b/config.cpp
index 342d973..2b37f91 100644
--- a/config.cpp
+++ b/config.cpp
@@ -45,6 +45,8 @@ void Config::readConfigfile(const std::filesystem::path& filename)
m_threads = tree.get<int>("webserver.threads");
+ m_statistics_path = tree.get<std::string>("webserver.statisticspath", "/var/lib/webserver/stats.db");
+
// optional entries
auto elements = tree.get_child_optional("webserver");
if (elements) {
@@ -226,6 +228,11 @@ int Config::Threads() const
return m_threads;
}
+fs::path Config::statistics_path() const
+{
+ return m_statistics_path;
+}
+
const std::vector<std::string>& Config::PluginDirectories() const
{
return m_plugin_directories;
@@ -245,10 +252,12 @@ 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 << "Group: " << m_group << std::endl;
std::cout << "Threads: " << m_threads << std::endl;
+ std::cout << "Statistics Path: " << statistics_path() << std::endl;
+
std::cout << "Plugin Directories:";
for (const auto& dir: m_plugin_directories)
std::cout << " " << dir;
diff --git a/config.h b/config.h
index d0e78ba..42a979e 100644
--- a/config.h
+++ b/config.h
@@ -52,6 +52,7 @@ class Config
std::string m_user;
std::string m_group;
int m_threads;
+ std::filesystem::path m_statistics_path;
std::vector<std::string> m_plugin_directories;
std::unordered_map<std::string, Site> m_sites;
std::vector<Socket> m_sockets;
@@ -65,6 +66,8 @@ class Config
int Threads() const;
+ std::filesystem::path statistics_path() const;
+
const std::vector<std::string>& PluginDirectories() const;
const std::unordered_map<std::string, Site>& Sites() const;
const std::vector<Socket>& Sockets() const;
diff --git a/debian/webserver.conf b/debian/webserver.conf
index f40e793..4a9e3af 100644
--- a/debian/webserver.conf
+++ b/debian/webserver.conf
@@ -1,6 +1,7 @@
<webserver>
<user>www-data</user>
<group>www-data</group>
+ <statisticspath>/var/lib/webserver/stats.db</statisticspath>
<threads>10</threads>
<plugin-directory>/usr/lib/webserver/plugins</plugin-directory>
<sites>
diff --git a/server.cpp b/server.cpp
index 51e80ba..5d9d7ea 100644
--- a/server.cpp
+++ b/server.cpp
@@ -59,7 +59,7 @@ Server::~Server()
int run_server(Config& config, plugins_container_type& plugins)
{
- Statistics stats;
+ Statistics stats(config.statistics_path());
auto const threads = std::max<int>(1, config.Threads());
diff --git a/statistics.cpp b/statistics.cpp
index 1d67bfd..fb7148b 100644
--- a/statistics.cpp
+++ b/statistics.cpp
@@ -8,14 +8,14 @@ namespace fs = std::filesystem;
using namespace std::string_literals;
namespace {
- const fs::path statsfilepath{ "/var/lib/webserver/stats.db" };
+ const fs::path default_statsfilepath{ "stats.db" };
} // anonymous namespace
void Statistics::load()
{
std::lock_guard<std::mutex> lock(mMutex);
std::cout << "Loading statistics..." << std::endl;
- std::ifstream file{statsfilepath, std::ios::in | std::ios::binary};
+ std::ifstream file{mPath, std::ios::in | std::ios::binary};
if (file.is_open()) {
Reichwein::Serialization::IArchive archive{file};
@@ -32,7 +32,7 @@ void Statistics::save()
if (mChanged) {
std::lock_guard<std::mutex> lock(mMutex);
std::cout << "Saving statistics..." << std::endl;
- std::ofstream file{statsfilepath, std::ios::out | std::ios::binary | std::ios::trunc};
+ std::ofstream file{mPath, std::ios::out | std::ios::binary | std::ios::trunc};
if (file.is_open()) {
Reichwein::Serialization::OArchive archive{file};
@@ -45,7 +45,12 @@ void Statistics::save()
}
}
-Statistics::Statistics()
+Statistics::Statistics(): mPath{default_statsfilepath}
+{
+ load();
+}
+
+Statistics::Statistics(const fs::path& path): mPath{path.empty() ? default_statsfilepath : path}
{
load();
}
diff --git a/statistics.h b/statistics.h
index a8b4854..f2ebcd3 100644
--- a/statistics.h
+++ b/statistics.h
@@ -1,5 +1,7 @@
#pragma once
+#include "config.h"
+
#include "libreichwein/archive.h"
#include <cstdint>
@@ -63,12 +65,14 @@ private:
bool mChanged{};
std::deque<Bin> mBins;
std::mutex mMutex;
+ std::filesystem::path mPath;
void load();
void limit();
public:
Statistics();
+ Statistics(const std::filesystem::path& path);
~Statistics();
void count(size_t bytes_in, size_t bytes_out, bool error, bool ipv6, bool https);
diff --git a/tests/test-config.cpp b/tests/test-config.cpp
index c16c519..fe482f8 100644
--- a/tests/test-config.cpp
+++ b/tests/test-config.cpp
@@ -41,6 +41,7 @@ BOOST_FIXTURE_TEST_CASE(config, ConfigFixture)
<user>user1</user>
<group>www-data</group>
<threads>10</threads>
+ <statisticspath>stats.db</statisticspath>
<!--
<plugin-directory>/usr/lib/webserver/plugins</plugin-directory>
<plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory>
diff --git a/tests/test-statistics.cpp b/tests/test-statistics.cpp
index 9ed7d06..fbc8cfb 100644
--- a/tests/test-statistics.cpp
+++ b/tests/test-statistics.cpp
@@ -6,23 +6,88 @@
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
+#include <filesystem>
#include <sstream>
#include <string>
#include "statistics.h"
+#include "config.h"
+
using namespace std::string_literals;
+namespace fs = std::filesystem;
class StatisticsFixture
{
public:
StatisticsFixture(){}
~StatisticsFixture(){}
- void setup(){}
- void teardown(){}
+ void setup()
+ {
+ std::error_code ec;
+ fs::remove("stats.db", ec);
+ }
+ void teardown()
+ {
+ std::error_code ec;
+ fs::remove("stats.db", ec);
+ }
};
BOOST_FIXTURE_TEST_CASE(statistics, StatisticsFixture)
{
+ {
+ Statistics stats;
+
+ BOOST_CHECK_EQUAL(stats.getValues(), "");
+
+ stats.count(10, 1000, false, true, true);
+
+ auto v{stats.getValues()};
+ BOOST_CHECK_GT(v.size(), 0);
+
+ auto pos{v.find(",")};
+ BOOST_CHECK(pos != std::string::npos);
+ BOOST_CHECK_GT(pos, 0);
+
+ std::string v2{v.substr(pos)};
+
+ BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n");
+
+ stats.save();
+
+ BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n");
+ }
+
+ {
+ Statistics stats("stats.db");
+ auto v{stats.getValues()};
+ BOOST_CHECK_GT(v.size(), 0);
+
+ auto pos{v.find(",")};
+ BOOST_CHECK(pos != std::string::npos);
+ BOOST_CHECK_GT(pos, 0);
+
+ std::string v2{v.substr(pos)};
+
+ BOOST_CHECK_EQUAL(v2, ",1,0,10,1000,1,0,10,1000,1,0,10,1000\n");
+
+ stats.count(10, 1000, false, true, true);
+ BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",2,0,20,2000,2,0,20,2000,2,0,20,2000\n");
+ stats.count(10, 1000, true, true, true);
+ BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",3,1,30,3000,3,1,30,3000,3,1,30,3000\n");
+ stats.count(10, 1000, false, false, false);
+ BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",4,1,40,4000,3,1,30,3000,3,1,30,3000\n");
+ stats.count(10, 1000, false, true, false);
+ BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",5,1,50,5000,4,1,40,4000,3,1,30,3000\n");
+ stats.count(10, 1000, false, false, true);
+ BOOST_CHECK_EQUAL(stats.getValues().substr(pos), ",6,1,60,6000,4,1,40,4000,4,1,40,4000\n");
+ }
+}
+
+BOOST_FIXTURE_TEST_CASE(statistics_non_existing, StatisticsFixture)
+{
+ Statistics stats("nonexistingpath/stats.db");
+ BOOST_CHECK_EQUAL(stats.getValues(), "");
}
diff --git a/tests/test-webserver.cpp b/tests/test-webserver.cpp
index 53aa9cc..ef3b15f 100644
--- a/tests/test-webserver.cpp
+++ b/tests/test-webserver.cpp
@@ -65,6 +65,7 @@ public:
<user>www-data</user>
<group>www-data</group>
<threads>10</threads>
+ <statisticspath>stats.db</sttaisticspath>
<plugin-directory>../plugins</plugin-directory>
<sites>
<site>
diff --git a/webserver.conf b/webserver.conf
index e1c7902..53b48ce 100644
--- a/webserver.conf
+++ b/webserver.conf
@@ -2,6 +2,7 @@
<user>www-data</user>
<group>www-data</group>
<threads>10</threads>
+ <statisticspath>stats.db</statisticspath>
<!--
<plugin-directory>/usr/lib/webserver/plugins</plugin-directory>
<plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory>