summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--config.cpp11
-rw-r--r--config.h7
-rw-r--r--plugin.cpp35
-rw-r--r--plugins/static-files/Makefile130
-rw-r--r--plugins/static-files/static-files.cpp26
-rw-r--r--plugins/static-files/static-files.h15
-rw-r--r--plugins/webbox/Makefile130
-rw-r--r--plugins/webbox/webbox.cpp26
-rw-r--r--plugins/webbox/webbox.h15
-rw-r--r--plugins/weblog/Makefile130
-rw-r--r--plugins/weblog/weblog.cpp26
-rw-r--r--plugins/weblog/weblog.h15
-rw-r--r--webserver.conf2
14 files changed, 557 insertions, 15 deletions
diff --git a/Makefile b/Makefile
index 06385de..234ddaf 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
DISTROS=debian10
VERSION=$(shell dpkg-parsechangelog --show-field Version)
PROJECTNAME=webserver
+PLUGINS=static-files webbox # weblog cgi fcgi
CXX=clang++-10
@@ -77,6 +78,7 @@ TESTSRC=\
SRC=$(PROGSRC) webserver.cpp
all: $(PROJECTNAME) test-$(PROJECTNAME)
+ for i in $(PLUGINS) ; do make -C plugins/$$i ; done
./test-$(PROJECTNAME)
./webserver -c webserver.conf
@@ -127,7 +129,9 @@ debs: $(DISTROS)
clean:
-rm -f test-$(PROJECTNAME) $(PROJECTNAME)
+ -rm -f plugins/*.so
-find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
+ for i in $(PLUGINS) ; do make -C plugins/$$i clean ; done
zip: clean
-rm -f ../$(PROJECTNAME).zip
diff --git a/config.cpp b/config.cpp
index baf611b..0d1eb34 100644
--- a/config.cpp
+++ b/config.cpp
@@ -215,3 +215,14 @@ std::string Config::DocRoot(const Socket& socket, const std::string& requested_h
return result;
}
+bool Config::PluginIsConfigured(const std::string& name) const
+{
+ for (const auto& site: m_sites) {
+ for (const auto& path: site.paths) {
+ if (path.params.find("plugin") != path.params.end())
+ return true;
+ }
+ }
+ return false;
+}
+
diff --git a/config.h b/config.h
index 801b5fa..72ce9b1 100644
--- a/config.h
+++ b/config.h
@@ -70,9 +70,16 @@ class Config
const std::vector<Site>& Sites() const;
const std::vector<Socket>& Sockets() const;
+ //
+ // secondary calculation functions
+ //
+
/// param[in] requested_host e.g. www.domain.com:8080 or www.domain.com
std::string DocRoot(const Socket& socket, const std::string& requested_host, const std::string& requested_path) const;
+ // return true iff plugin "name" is mentioned in config
+ bool PluginIsConfigured(const std::string& name) const;
+
void dump() const;
};
diff --git a/plugin.cpp b/plugin.cpp
index c0a01fc..1da89cd 100644
--- a/plugin.cpp
+++ b/plugin.cpp
@@ -20,24 +20,31 @@ void PluginLoader::load_plugins()
for (const auto& dir: plugin_directories) {
for (auto& path: fs::recursive_directory_iterator(dir)) {
- if (path.is_regular_file()) {
+ if (path.is_regular_file() && path.path().extension() == ".so"s) {
dll::fs::path lib_path{path.path()};
try {
- boost::shared_ptr<webserver_plugin_interface> plugin = dll::import<webserver_plugin_interface>(lib_path, "webserver_plugin", dll::load_mode::append_decorations);
- if (plugin) {
- if (plugin->version() != webserver_plugin_interface::interface_version)
- throw std::runtime_error("Bad interface version for "s + path.path().generic_string() + ": "s + std::to_string(plugin->version()) + " vs. "s + std::to_string(webserver_plugin_interface::interface_version));
-
- if (m_plugins.contains(plugin->name()))
- throw std::runtime_error("Plugin already exists: "s + plugin->name());
-
- m_plugins.emplace(plugin->name(), plugin);
-
- std::cout << "Found plugin: " << plugin->name() << std::endl;
- } else
- std::cout << "Can't load plugin from " << path.path().generic_string() << std::endl;
+ boost::shared_ptr<webserver_plugin_interface> plugin = dll::import<webserver_plugin_interface>(lib_path, "webserver_plugin", dll::load_mode::append_decorations);
+ if (plugin) {
+ if (plugin->version() != webserver_plugin_interface::interface_version)
+ throw std::runtime_error("Bad interface version for "s + path.path().generic_string() + ": "s + std::to_string(plugin->version()) + " vs. "s + std::to_string(webserver_plugin_interface::interface_version));
+
+ std::string name{plugin->name()};
+ if (m_plugins.contains(name))
+ throw std::runtime_error("Plugin already exists: "s + name);
+
+ std::cout << "Found plugin: " << name << " (" << path.path().string() << "), ";
+ if (m_config.PluginIsConfigured(name)) {
+ std::cout << "loading.";
+ m_plugins.emplace(plugin->name(), plugin);
+ } else {
+ std::cout << "ignored (not configured).";
+ }
+ std::cout << std::endl;
+
+ } else
+ std::cout << "Can't load plugin from " << path.path().generic_string() << std::endl;
} catch (const std::exception& ex) {
std::cout << "Can't load plugin from " << path.path().generic_string() << ": " << ex.what() << std::endl;
}
diff --git a/plugins/static-files/Makefile b/plugins/static-files/Makefile
new file mode 100644
index 0000000..e0905a1
--- /dev/null
+++ b/plugins/static-files/Makefile
@@ -0,0 +1,130 @@
+DISTROS=debian10
+VERSION=$(shell dpkg-parsechangelog --show-field Version)
+PROJECTNAME=static-files
+
+CXX=clang++-10
+
+ifeq ($(shell which $(CXX)),)
+CXX=clang++
+endif
+
+ifeq ($(shell which $(CXX)),)
+CXX=g++-9
+endif
+
+ifeq ($(CXXFLAGS),)
+#CXXFLAGS=-O2 -DNDEBUG
+CXXFLAGS=-O0 -g -D_DEBUG
+endif
+# -fprofile-instr-generate -fcoverage-mapping
+# gcc:--coverage
+
+CXXFLAGS+= -Wall -I.
+
+CXXFLAGS+= -pthread -fvisibility=hidden -fPIC
+ifeq ($(CXX),clang++-10)
+CXXFLAGS+=-std=c++20 #-stdlib=libc++
+else
+CXXFLAGS+=-std=c++2a
+endif
+
+CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
+
+LIBS=\
+-lboost_context \
+-lboost_coroutine \
+-lboost_program_options \
+-lboost_system \
+-lboost_thread \
+-lboost_filesystem \
+-lboost_regex \
+-lpthread \
+-lssl -lcrypto \
+-ldl
+
+ifeq ($(CXX),clang++-10)
+LIBS+= \
+-fuse-ld=lld-10 \
+-lstdc++
+#-lc++ \
+#-lc++abi
+#-lc++fs
+#-lstdc++fs
+else
+LIBS+= \
+-lstdc++
+#-lstdc++fs
+endif
+
+PROGSRC=\
+ static-files.cpp
+
+TESTSRC=\
+ test-webserver.cpp \
+ googlemock/src/gmock-all.cpp \
+ googletest/src/gtest-all.cpp \
+ $(PROGSRC)
+
+SRC=$(PROGSRC)
+
+all: $(PROJECTNAME).so
+
+# testsuite ----------------------------------------------
+test-$(PROJECTNAME): $(TESTSRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+
+$(PROJECTNAME).so: $(SRC:.cpp=.o)
+ $(CXX) -shared $(CXXFLAGS) $^ $(LIBS) -o $@
+
+dep: $(TESTSRC:.cpp=.d)
+
+%.d: %.cpp
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -c $<
+
+%.o: %.cpp %.d
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+googletest/src/%.o: googletest/src/%.cc
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+# dependencies
+
+ADD_DEP=Makefile
+
+install:
+ mkdir -p $(DESTDIR)/usr/bin
+ cp webserver $(DESTDIR)/usr/bin
+
+ mkdir -p $(DESTDIR)/usr/lib/webserver/plugins
+ mkdir -p $(DESTDIR)/usr/local/lib/webserver/plugins
+
+ mkdir -p $(DESTDIR)/etc
+ cp webserver.conf $(DESTDIR)/etc/webserver.conf
+
+# misc ---------------------------------------------------
+deb:
+ # build binary deb package
+ dpkg-buildpackage -us -uc -rfakeroot
+
+deb-src:
+ dpkg-source -b .
+
+$(DISTROS): deb-src
+ sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../webserver_$(VERSION).dsc ; \
+
+debs: $(DISTROS)
+
+clean:
+ -rm -f test-$(PROJECTNAME) $(PROJECTNAME)
+ -find . -name '*.o' -o -name '*.so' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
+
+zip: clean
+ -rm -f ../$(PROJECTNAME).zip
+ zip -r ../$(PROJECTNAME).zip *
+ ls -l ../$(PROJECTNAME).zip
+
+
+
+.PHONY: clean all zip install deb deb-src debs all $(DISTROS)
+
+-include $(wildcard $(SRC:.cpp=.d))
diff --git a/plugins/static-files/static-files.cpp b/plugins/static-files/static-files.cpp
new file mode 100644
index 0000000..287c975
--- /dev/null
+++ b/plugins/static-files/static-files.cpp
@@ -0,0 +1,26 @@
+#include "static-files.h"
+
+#include <iostream>
+
+using namespace std::string_literals;
+
+std::string static_files_plugin::name()
+{
+ return "static-files";
+}
+
+static_files_plugin::static_files_plugin()
+{
+ //std::cout << "Plugin constructor" << std::endl;
+}
+
+static_files_plugin::~static_files_plugin()
+{
+ //std::cout << "Plugin destructor" << std::endl;
+}
+
+std::string static_files_plugin::generate_page(std::string path)
+{
+ return "Static Files "s + path;
+}
+
diff --git a/plugins/static-files/static-files.h b/plugins/static-files/static-files.h
new file mode 100644
index 0000000..7ea5500
--- /dev/null
+++ b/plugins/static-files/static-files.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "../../plugin_interface.h"
+
+class static_files_plugin: public webserver_plugin_interface
+{
+public:
+ static_files_plugin();
+ ~static_files_plugin();
+ std::string name();
+ std::string generate_page(std::string path);
+};
+
+extern "C" BOOST_SYMBOL_EXPORT static_files_plugin webserver_plugin;
+static_files_plugin webserver_plugin;
diff --git a/plugins/webbox/Makefile b/plugins/webbox/Makefile
new file mode 100644
index 0000000..666aede
--- /dev/null
+++ b/plugins/webbox/Makefile
@@ -0,0 +1,130 @@
+DISTROS=debian10
+VERSION=$(shell dpkg-parsechangelog --show-field Version)
+PROJECTNAME=webbox
+
+CXX=clang++-10
+
+ifeq ($(shell which $(CXX)),)
+CXX=clang++
+endif
+
+ifeq ($(shell which $(CXX)),)
+CXX=g++-9
+endif
+
+ifeq ($(CXXFLAGS),)
+#CXXFLAGS=-O2 -DNDEBUG
+CXXFLAGS=-O0 -g -D_DEBUG
+endif
+# -fprofile-instr-generate -fcoverage-mapping
+# gcc:--coverage
+
+CXXFLAGS+= -Wall -I.
+
+CXXFLAGS+= -pthread -fvisibility=hidden -fPIC
+ifeq ($(CXX),clang++-10)
+CXXFLAGS+=-std=c++20 #-stdlib=libc++
+else
+CXXFLAGS+=-std=c++2a
+endif
+
+CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
+
+LIBS=\
+-lboost_context \
+-lboost_coroutine \
+-lboost_program_options \
+-lboost_system \
+-lboost_thread \
+-lboost_filesystem \
+-lboost_regex \
+-lpthread \
+-lssl -lcrypto \
+-ldl
+
+ifeq ($(CXX),clang++-10)
+LIBS+= \
+-fuse-ld=lld-10 \
+-lstdc++
+#-lc++ \
+#-lc++abi
+#-lc++fs
+#-lstdc++fs
+else
+LIBS+= \
+-lstdc++
+#-lstdc++fs
+endif
+
+PROGSRC=\
+ webbox.cpp
+
+TESTSRC=\
+ test-webserver.cpp \
+ googlemock/src/gmock-all.cpp \
+ googletest/src/gtest-all.cpp \
+ $(PROGSRC)
+
+SRC=$(PROGSRC)
+
+all: $(PROJECTNAME).so
+
+# testsuite ----------------------------------------------
+test-$(PROJECTNAME): $(TESTSRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+
+$(PROJECTNAME).so: $(SRC:.cpp=.o)
+ $(CXX) -shared $(CXXFLAGS) $^ $(LIBS) -o $@
+
+dep: $(TESTSRC:.cpp=.d)
+
+%.d: %.cpp
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -c $<
+
+%.o: %.cpp %.d
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+googletest/src/%.o: googletest/src/%.cc
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+# dependencies
+
+ADD_DEP=Makefile
+
+install:
+ mkdir -p $(DESTDIR)/usr/bin
+ cp webserver $(DESTDIR)/usr/bin
+
+ mkdir -p $(DESTDIR)/usr/lib/webserver/plugins
+ mkdir -p $(DESTDIR)/usr/local/lib/webserver/plugins
+
+ mkdir -p $(DESTDIR)/etc
+ cp webserver.conf $(DESTDIR)/etc/webserver.conf
+
+# misc ---------------------------------------------------
+deb:
+ # build binary deb package
+ dpkg-buildpackage -us -uc -rfakeroot
+
+deb-src:
+ dpkg-source -b .
+
+$(DISTROS): deb-src
+ sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../webserver_$(VERSION).dsc ; \
+
+debs: $(DISTROS)
+
+clean:
+ -rm -f test-$(PROJECTNAME) $(PROJECTNAME)
+ -find . -name '*.o' -o -name '*.so' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
+
+zip: clean
+ -rm -f ../$(PROJECTNAME).zip
+ zip -r ../$(PROJECTNAME).zip *
+ ls -l ../$(PROJECTNAME).zip
+
+
+
+.PHONY: clean all zip install deb deb-src debs all $(DISTROS)
+
+-include $(wildcard $(SRC:.cpp=.d))
diff --git a/plugins/webbox/webbox.cpp b/plugins/webbox/webbox.cpp
new file mode 100644
index 0000000..7fe9fa7
--- /dev/null
+++ b/plugins/webbox/webbox.cpp
@@ -0,0 +1,26 @@
+#include "webbox.h"
+
+#include <iostream>
+
+using namespace std::string_literals;
+
+std::string webbox_plugin::name()
+{
+ return "webbox";
+}
+
+webbox_plugin::webbox_plugin()
+{
+ //std::cout << "Plugin constructor" << std::endl;
+}
+
+webbox_plugin::~webbox_plugin()
+{
+ //std::cout << "Plugin destructor" << std::endl;
+}
+
+std::string webbox_plugin::generate_page(std::string path)
+{
+ return "Webbox "s + path;
+}
+
diff --git a/plugins/webbox/webbox.h b/plugins/webbox/webbox.h
new file mode 100644
index 0000000..037a725
--- /dev/null
+++ b/plugins/webbox/webbox.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "../../plugin_interface.h"
+
+class webbox_plugin: public webserver_plugin_interface
+{
+public:
+ webbox_plugin();
+ ~webbox_plugin();
+ std::string name();
+ std::string generate_page(std::string path);
+};
+
+extern "C" BOOST_SYMBOL_EXPORT webbox_plugin webserver_plugin;
+webbox_plugin webserver_plugin;
diff --git a/plugins/weblog/Makefile b/plugins/weblog/Makefile
new file mode 100644
index 0000000..27b68fc
--- /dev/null
+++ b/plugins/weblog/Makefile
@@ -0,0 +1,130 @@
+DISTROS=debian10
+VERSION=$(shell dpkg-parsechangelog --show-field Version)
+PROJECTNAME=weblog
+
+CXX=clang++-10
+
+ifeq ($(shell which $(CXX)),)
+CXX=clang++
+endif
+
+ifeq ($(shell which $(CXX)),)
+CXX=g++-9
+endif
+
+ifeq ($(CXXFLAGS),)
+#CXXFLAGS=-O2 -DNDEBUG
+CXXFLAGS=-O0 -g -D_DEBUG
+endif
+# -fprofile-instr-generate -fcoverage-mapping
+# gcc:--coverage
+
+CXXFLAGS+= -Wall -I.
+
+CXXFLAGS+= -pthread -fvisibility=hidden -fPIC
+ifeq ($(CXX),clang++-10)
+CXXFLAGS+=-std=c++20 #-stdlib=libc++
+else
+CXXFLAGS+=-std=c++2a
+endif
+
+CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
+
+LIBS=\
+-lboost_context \
+-lboost_coroutine \
+-lboost_program_options \
+-lboost_system \
+-lboost_thread \
+-lboost_filesystem \
+-lboost_regex \
+-lpthread \
+-lssl -lcrypto \
+-ldl
+
+ifeq ($(CXX),clang++-10)
+LIBS+= \
+-fuse-ld=lld-10 \
+-lstdc++
+#-lc++ \
+#-lc++abi
+#-lc++fs
+#-lstdc++fs
+else
+LIBS+= \
+-lstdc++
+#-lstdc++fs
+endif
+
+PROGSRC=\
+ weblog.cpp
+
+TESTSRC=\
+ test-webserver.cpp \
+ googlemock/src/gmock-all.cpp \
+ googletest/src/gtest-all.cpp \
+ $(PROGSRC)
+
+SRC=$(PROGSRC)
+
+all: $(PROJECTNAME).so
+
+# testsuite ----------------------------------------------
+test-$(PROJECTNAME): $(TESTSRC:.cpp=.o)
+ $(CXX) $(CXXFLAGS) $^ $(LIBS) -o $@
+
+$(PROJECTNAME).so: $(SRC:.cpp=.o)
+ $(CXX) -shared $(CXXFLAGS) $^ $(LIBS) -o $@
+
+dep: $(TESTSRC:.cpp=.d)
+
+%.d: %.cpp
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -MM -MP -MF $@ -c $<
+
+%.o: %.cpp %.d
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+googletest/src/%.o: googletest/src/%.cc
+ $(CXX) $(CXXFLAGS) $(CXXTESTFLAGS) -c $< -o $@
+
+# dependencies
+
+ADD_DEP=Makefile
+
+install:
+ mkdir -p $(DESTDIR)/usr/bin
+ cp webserver $(DESTDIR)/usr/bin
+
+ mkdir -p $(DESTDIR)/usr/lib/webserver/plugins
+ mkdir -p $(DESTDIR)/usr/local/lib/webserver/plugins
+
+ mkdir -p $(DESTDIR)/etc
+ cp webserver.conf $(DESTDIR)/etc/webserver.conf
+
+# misc ---------------------------------------------------
+deb:
+ # build binary deb package
+ dpkg-buildpackage -us -uc -rfakeroot
+
+deb-src:
+ dpkg-source -b .
+
+$(DISTROS): deb-src
+ sudo pbuilder build --basetgz /var/cache/pbuilder/$@.tgz --buildresult result/$@ ../webserver_$(VERSION).dsc ; \
+
+debs: $(DISTROS)
+
+clean:
+ -rm -f test-$(PROJECTNAME) $(PROJECTNAME)
+ -find . -name '*.o' -o -name '*.d' -o -name '*.gcno' -o -name '*.gcda' | xargs rm -f
+
+zip: clean
+ -rm -f ../$(PROJECTNAME).zip
+ zip -r ../$(PROJECTNAME).zip *
+ ls -l ../$(PROJECTNAME).zip
+
+
+
+.PHONY: clean all zip install deb deb-src debs all $(DISTROS)
+
+-include $(wildcard $(SRC:.cpp=.d))
diff --git a/plugins/weblog/weblog.cpp b/plugins/weblog/weblog.cpp
new file mode 100644
index 0000000..ef90a53
--- /dev/null
+++ b/plugins/weblog/weblog.cpp
@@ -0,0 +1,26 @@
+#include "weblog.h"
+
+#include <iostream>
+
+using namespace std::string_literals;
+
+std::string weblog_plugin::name()
+{
+ return "weblog";
+}
+
+weblog_plugin::weblog_plugin()
+{
+ //std::cout << "Plugin constructor" << std::endl;
+}
+
+weblog_plugin::~weblog_plugin()
+{
+ //std::cout << "Plugin destructor" << std::endl;
+}
+
+std::string weblog_plugin::generate_page(std::string path)
+{
+ return "Blog "s + path;
+}
+
diff --git a/plugins/weblog/weblog.h b/plugins/weblog/weblog.h
new file mode 100644
index 0000000..5433e1c
--- /dev/null
+++ b/plugins/weblog/weblog.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include "../plugin_interface.h"
+
+class weblog_plugin: public webserver_plugin_interface
+{
+public:
+ weblog_plugin();
+ ~weblog_plugin();
+ std::string name();
+ std::string generate_page(std::string path);
+};
+
+extern "C" BOOST_SYMBOL_EXPORT weblog_plugin webserver_plugin;
+weblog_plugin webserver_plugin;
diff --git a/webserver.conf b/webserver.conf
index c41e7b2..7749739 100644
--- a/webserver.conf
+++ b/webserver.conf
@@ -6,7 +6,7 @@
<plugin-directory><a c="d">b<e>f</e></a>/usr/lib/webserver/plugins</plugin-directory>
<plugin-directory>/usr/local/lib/webserver/plugins</plugin-directory>
-->
- <plugin-directory>plugins-examples</plugin-directory>
+ <plugin-directory>plugins</plugin-directory>
<sites>
<site>
<name>antcom.de</name>