summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--debian/control2
-rw-r--r--http.cpp119
-rw-r--r--https.cpp145
-rw-r--r--https.h13
-rw-r--r--plugin.cpp15
-rw-r--r--plugins/static-files/Makefile4
-rw-r--r--server.cpp12
8 files changed, 292 insertions, 24 deletions
diff --git a/Makefile b/Makefile
index 4de0904..d167ab4 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ CXXFLAGS+= -pthread
ifeq ($(CXX),clang++-10)
CXXFLAGS+=-std=c++20 #-stdlib=libc++
else
-CXXFLAGS+=-std=c++2a
+CXXFLAGS+=-std=c++17
endif
CXXTESTFLAGS=-Igoogletest/include -Igooglemock/include/ -Igoogletest -Igooglemock
@@ -53,8 +53,8 @@ LIBS+= \
#-lstdc++fs
else
LIBS+= \
--lstdc++
-#-lstdc++fs
+-lstdc++ \
+-lstdc++fs
endif
PROGSRC=\
diff --git a/debian/control b/debian/control
index 3d5d617..4c0d558 100644
--- a/debian/control
+++ b/debian/control
@@ -2,7 +2,7 @@ Source: webserver
Section: web
Priority: extra
Maintainer: Roland Reichwein <mail@reichwein.it>
-Build-Depends: debhelper (>= 9), libssl-dev, libssl-dev, libboost-all-dev | libboost1.71-all-dev, clang
+Build-Depends: debhelper (>= 9), libssl-dev, libboost-all-dev | libboost1.71-all-dev, clang
Standards-Version: 4.1.3
Homepage: http://www.reichwein.it/webserver/
diff --git a/http.cpp b/http.cpp
index 9a5b554..cb95b0f 100644
--- a/http.cpp
+++ b/http.cpp
@@ -1,13 +1,23 @@
#include "http.h"
+#include <boost/beast/version.hpp>
+
+// Support both boost in Debian unstable (BOOST_LATEST) and in stable (boost 1.67)
+#if BOOST_VERSION >= 107100
+#define BOOST_LATEST
+#endif
+
#include "server.h"
#include "response.h"
#include <boost/beast/version.hpp>
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
-#include <boost/beast/version.hpp>
#include <boost/asio/dispatch.hpp>
+#ifndef BOOST_LATEST
+#include <boost/asio/bind_executor.hpp>
+#include <boost/asio/ip/tcp.hpp>
+#endif
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
#include <algorithm>
@@ -38,7 +48,12 @@ fail(beast::error_code ec, char const* what)
// Handles an HTTP server connection
class session : public std::enable_shared_from_this<session>
{
+#ifdef BOOST_LATEST
beast::tcp_stream stream_;
+#else
+ tcp::socket socket_;
+ boost::asio::strand<boost::asio::io_context::executor_type> strand_;
+#endif
beast::flat_buffer buffer_;
Server& m_server;
request_type req_;
@@ -51,6 +66,7 @@ class session : public std::enable_shared_from_this<session>
res_ = sp;
// Write the response
+#ifdef BOOST_LATEST
http::async_write(
stream_,
*sp,
@@ -58,14 +74,36 @@ class session : public std::enable_shared_from_this<session>
&session::on_write,
shared_from_this(),
sp->need_eof()));
+#else
+ http::async_write(
+ socket_,
+ *sp,
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_write,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2,
+ sp->need_eof())));
+#endif
}
public:
// Take ownership of the stream
session(
+#ifdef BOOST_LATEST
tcp::socket&& socket,
+#else
+ tcp::socket socket,
+#endif
Server& server)
+#ifdef BOOST_LATEST
: stream_(std::move(socket))
+#else
+ : socket_(std::move(socket))
+ , strand_(socket_.get_executor())
+#endif
, m_server(server)
{
}
@@ -75,13 +113,15 @@ public:
run()
{
// We need to be executing within a strand to perform async operations
- // on the I/O objects in this session. Although not strictly necessary
- // for single-threaded contexts, this example code is written to be
- // thread-safe by default.
+ // on the I/O objects in this session.
+#ifdef BOOST_LATEST
net::dispatch(stream_.get_executor(),
beast::bind_front_handler(
&session::do_read,
shared_from_this()));
+#else
+ do_read();
+#endif
}
void
@@ -91,6 +131,7 @@ public:
// otherwise the operation behavior is undefined.
req_ = {};
+#ifdef BOOST_LATEST
// Set the timeout.
stream_.expires_after(std::chrono::seconds(30));
@@ -99,12 +140,29 @@ public:
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
+#else
+
+ http::async_read(socket_, buffer_, req_,
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_read,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2)));
+#endif
}
void
on_read(
+#ifdef BOOST_LATEST
beast::error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred
+#else
+ boost::system::error_code ec,
+ std::size_t bytes_transferred
+#endif
+ )
{
boost::ignore_unused(bytes_transferred);
@@ -121,9 +179,16 @@ public:
void
on_write(
+#ifdef BOOST_LATEST
bool close,
beast::error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred
+#else
+ boost::system::error_code ec,
+ std::size_t bytes_transferred,
+ bool close
+#endif
+ )
{
boost::ignore_unused(bytes_transferred);
@@ -149,8 +214,11 @@ public:
{
// Send a TCP shutdown
beast::error_code ec;
+#ifdef BOOST_LATEST
stream_.socket().shutdown(tcp::socket::shutdown_send, ec);
-
+#else
+ socket_.shutdown(tcp::socket::shutdown_send, ec);
+#endif
// At this point the connection is closed gracefully
}
};
@@ -160,8 +228,13 @@ public:
// Accepts incoming connections and launches the sessions
class listener : public std::enable_shared_from_this<listener>
{
+#ifdef BOOST_LATEST
net::io_context& ioc_;
+#endif
tcp::acceptor acceptor_;
+#ifndef BOOST_LATEST
+ tcp::socket socket_;
+#endif
Server& m_server;
public:
@@ -169,11 +242,20 @@ public:
net::io_context& ioc,
tcp::endpoint endpoint,
Server& server)
+#ifdef BOOST_LATEST
: ioc_(ioc)
, acceptor_(net::make_strand(ioc))
+#else
+ : acceptor_(ioc)
+ , socket_(ioc)
+#endif
, m_server(server)
{
+#ifdef BOOST_VERSION
beast::error_code ec;
+#else
+ boost::system::error_code ec;
+#endif
// Open the acceptor
acceptor_.open(endpoint.protocol(), ec);
@@ -213,7 +295,11 @@ public:
void
run()
{
- do_accept();
+#ifndef BOOST_LATEST
+ if (!acceptor_.is_open())
+ return;
+#endif
+ do_accept();
}
private:
@@ -221,15 +307,28 @@ private:
do_accept()
{
// The new connection gets its own strand
+#ifdef BOOST_LATEST
acceptor_.async_accept(
net::make_strand(ioc_),
beast::bind_front_handler(
&listener::on_accept,
shared_from_this()));
+#else
+ acceptor_.async_accept(
+ socket_,
+ std::bind(
+ &listener::on_accept,
+ shared_from_this(),
+ std::placeholders::_1));
+#endif
}
void
+#ifdef BOOST_LATEST
on_accept(beast::error_code ec, tcp::socket socket)
+#else
+ on_accept(boost::system::error_code ec)
+#endif
{
if(ec)
{
@@ -239,7 +338,11 @@ private:
{
// Create the session and run it
std::make_shared<session>(
+#ifdef BOOST_LATEST
std::move(socket),
+#else
+ std::move(socket_),
+#endif
m_server)->run();
}
diff --git a/https.cpp b/https.cpp
index 60f37e7..facc533 100644
--- a/https.cpp
+++ b/https.cpp
@@ -10,10 +10,15 @@
#include <boost/asio/buffer.hpp>
#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/ssl/context.hpp>
+#ifdef BOOST_LATEST
+#include <boost/beast/ssl.hpp>
+#else
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl/stream.hpp>
+#include <boost/asio/bind_executor.hpp>
+#endif
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>
@@ -39,8 +44,15 @@ namespace {
// Report a failure
void
-fail(beast::error_code ec, char const* what)
+fail(
+#ifdef BOOST_LATEST
+ beast::error_code ec,
+#else
+ boost::system::error_code ec,
+#endif
+ char const* what)
{
+#ifdef BOOST_LATEST
// ssl::error::stream_truncated, also known as an SSL "short read",
// indicates the peer closed the connection without performing the
// required closing handshake (for example, Google does this to
@@ -60,6 +72,7 @@ fail(beast::error_code ec, char const* what)
if(ec == net::ssl::error::stream_truncated)
return;
+#endif
std::cerr << what << ": " << ec.message() << "\n";
}
@@ -67,7 +80,13 @@ fail(beast::error_code ec, char const* what)
// Handles an HTTP server connection
class session : public std::enable_shared_from_this<session>
{
+#ifdef BOOST_LATEST
beast::ssl_stream<beast::tcp_stream> stream_;
+#else
+ tcp::socket socket_;
+ ssl::stream<tcp::socket&> stream_;
+ boost::asio::strand<boost::asio::io_context::executor_type> strand_;
+#endif
beast::flat_buffer buffer_;
Server& m_server;
http::request<http::string_body> req_;
@@ -80,6 +99,7 @@ class session : public std::enable_shared_from_this<session>
res_ = sp;
// Write the response
+#ifdef BOOST_LATEST
http::async_write(
stream_,
*sp,
@@ -87,15 +107,38 @@ class session : public std::enable_shared_from_this<session>
&session::on_write,
shared_from_this(),
sp->need_eof()));
+#else
+ http::async_write(
+ stream_,
+ *sp,
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_write,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2,
+ sp->need_eof())));
+#endif
}
public:
// Take ownership of the socket
explicit
session(
+#ifdef BOOST_LATEST
tcp::socket&& socket,
+#else
+ tcp::socket socket,
+#endif
ssl::context& ctx,
Server& server)
+#ifdef BOOST_LATEST
: stream_(std::move(socket), ctx)
+#else
+ : socket_(std::move(socket))
+ , stream_(socket_, ctx)
+ , strand_(socket_.get_executor())
+#endif
, m_server(server)
{
}
@@ -104,6 +147,7 @@ public:
void
run()
{
+#ifdef BOOST_LATEST
// We need to be executing within a strand to perform async operations
// on the I/O objects in this session.
net::dispatch(
@@ -111,8 +155,19 @@ public:
beast::bind_front_handler(
&session::on_run,
shared_from_this()));
+#else
+ stream_.async_handshake(
+ ssl::stream_base::server,
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_handshake,
+ shared_from_this(),
+ std::placeholders::_1)));
+#endif
}
+#ifdef BOOST_LATEST
void
on_run()
{
@@ -127,9 +182,16 @@ public:
&session::on_handshake,
shared_from_this()));
}
+#endif
void
- on_handshake(beast::error_code ec)
+ on_handshake(
+#ifdef BOOST_LATEST
+ beast::error_code ec
+#else
+ boost::system::error_code ec
+#endif
+ )
{
if(ec)
return fail(ec, "handshake");
@@ -144,6 +206,7 @@ public:
// otherwise the operation behavior is undefined.
req_ = {};
+#ifdef BOOST_LATEST
// Set the timeout.
beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30));
@@ -152,11 +215,25 @@ public:
beast::bind_front_handler(
&session::on_read,
shared_from_this()));
+#else
+ http::async_read(stream_, buffer_, req_,
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_read,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2)));
+#endif
}
void
on_read(
+#ifdef BOOST_LATEST
beast::error_code ec,
+#else
+ boost::system::error_code ec,
+#endif
std::size_t bytes_transferred)
{
boost::ignore_unused(bytes_transferred);
@@ -174,9 +251,16 @@ public:
void
on_write(
+#ifdef BOOST_LATEST
bool close,
beast::error_code ec,
- std::size_t bytes_transferred)
+ std::size_t bytes_transferred
+#else
+ boost::system::error_code ec,
+ std::size_t bytes_transferred,
+ bool close
+#endif
+ )
{
boost::ignore_unused(bytes_transferred);
@@ -200,6 +284,7 @@ public:
void
do_close()
{
+#ifdef BOOST_LATEST
// Set the timeout.
beast::get_lowest_layer(stream_).expires_after(std::chrono::seconds(30));
@@ -208,6 +293,15 @@ public:
beast::bind_front_handler(
&session::on_shutdown,
shared_from_this()));
+#else
+ stream_.async_shutdown(
+ boost::asio::bind_executor(
+ strand_,
+ std::bind(
+ &session::on_shutdown,
+ shared_from_this(),
+ std::placeholders::_1)));
+#endif
}
void
@@ -225,9 +319,14 @@ public:
// Accepts incoming connections and launches the sessions
class listener : public std::enable_shared_from_this<listener>
{
+#ifdef BOOST_LATEST
net::io_context& ioc_;
+#endif
ssl::context& ctx_;
tcp::acceptor acceptor_;
+#ifndef BOOST_LATEST
+ tcp::socket socket_;
+#endif
::Server& m_server;
public:
@@ -235,13 +334,22 @@ public:
net::io_context& ioc,
ssl::context& ctx,
tcp::endpoint endpoint,
- Server& server)
- : ioc_(ioc)
- , ctx_(ctx)
+ Server& server) :
+#ifdef BOOST_LATEST
+ ioc_(ioc),
+#endif
+ ctx_(ctx)
, acceptor_(ioc)
+#ifndef BOOST_LATEST
+ , socket_(ioc)
+#endif
, m_server(server)
{
+#ifdef BOOST_LATEST
beast::error_code ec;
+#else
+ boost::system::error_code ec;
+#endif
// Open the acceptor
acceptor_.open(endpoint.protocol(), ec);
@@ -281,6 +389,10 @@ public:
void
run()
{
+#ifndef BOOST_LATEST
+ if(! acceptor_.is_open())
+ return;
+#endif
do_accept();
}
@@ -289,15 +401,28 @@ private:
do_accept()
{
// The new connection gets its own strand
+#ifdef BOOST_LATEST
acceptor_.async_accept(
net::make_strand(ioc_),
beast::bind_front_handler(
&listener::on_accept,
shared_from_this()));
+#else
+ acceptor_.async_accept(
+ socket_,
+ std::bind(
+ &listener::on_accept,
+ shared_from_this(),
+ std::placeholders::_1));
+#endif
}
void
+#ifdef BOOST_LATEST
on_accept(beast::error_code ec, tcp::socket socket)
+#else
+ on_accept(boost::system::error_code ec)
+#endif
{
if(ec)
{
@@ -307,7 +432,11 @@ private:
{
// Create the session and run it
std::make_shared<session>(
+#ifdef BOOST_LATEST
std::move(socket),
+#else
+ std::move(socket_),
+#endif
ctx_,
m_server)->run();
}
diff --git a/https.h b/https.h
index 1362e59..e2aabbb 100644
--- a/https.h
+++ b/https.h
@@ -1,12 +1,21 @@
#pragma once
+#include <boost/beast/version.hpp>
+
+// Support both boost in Debian unstable (BOOST_LATEST) and in stable (boost 1.67)
+#if BOOST_VERSION >= 107100
+#define BOOST_LATEST
+#endif
+
#include <memory>
#include <string>
#include <unordered_map>
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
+#ifdef BOOST_LATEST
#include <boost/beast/ssl.hpp>
+#endif
#include <boost/asio/ssl.hpp>
#include "config.h"
@@ -16,7 +25,11 @@ namespace ssl = boost::asio::ssl; // from <boost/asio/ssl.hpp>
namespace HTTPS {
+#ifdef BOOST_LATEST
static const ssl::context_base::method tls_method {ssl::context::tlsv13};
+#else
+static const ssl::context_base::method tls_method {ssl::context::tlsv12};
+#endif
class Server: public ::Server
{
diff --git a/plugin.cpp b/plugin.cpp
index db0632d..a29e2f0 100644
--- a/plugin.cpp
+++ b/plugin.cpp
@@ -1,5 +1,12 @@
#include "plugin.h"
+#include <boost/beast/version.hpp>
+
+// Support both boost in Debian unstable (BOOST_LATEST) and in stable (boost 1.67)
+#if BOOST_VERSION >= 107100
+#define BOOST_LATEST
+#endif
+
#include <boost/dll/import.hpp>
#include <boost/filesystem.hpp>
@@ -22,7 +29,11 @@ void PluginLoader::load_plugins()
for (auto& path: fs::recursive_directory_iterator(dir)) {
if (path.is_regular_file() && path.path().extension() == ".so"s) {
+#ifdef BOOST_LATEST
dll::fs::path lib_path{path.path()};
+#else
+ boost::filesystem::path lib_path{path.path().generic_string()};
+#endif
try {
boost::shared_ptr<webserver_plugin_interface> plugin = dll::import<webserver_plugin_interface>(lib_path, "webserver_plugin", dll::load_mode::append_decorations);
@@ -31,7 +42,7 @@ void PluginLoader::load_plugins()
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))
+ if (m_plugins.find(name) != m_plugins.end())
throw std::runtime_error("Plugin already exists: "s + name);
std::cout << "Found plugin: " << name << " (" << path.path().string() << "), ";
@@ -76,7 +87,7 @@ bool PluginLoader::validate_config()
std::string plugin {it->second};
// check if plugin exists
- if (!m_plugins.contains(plugin)) {
+ if (m_plugins.find(plugin) == m_plugins.end()) {
std::cout << "Configured plugin " << plugin << " not found" << std::endl;
return false;
}
diff --git a/plugins/static-files/Makefile b/plugins/static-files/Makefile
index e0905a1..b928506 100644
--- a/plugins/static-files/Makefile
+++ b/plugins/static-files/Makefile
@@ -52,8 +52,8 @@ LIBS+= \
#-lstdc++fs
else
LIBS+= \
--lstdc++
-#-lstdc++fs
+-lstdc++ \
+-lstdc++fs
endif
PROGSRC=\
diff --git a/server.cpp b/server.cpp
index 47c50ac..26feabc 100644
--- a/server.cpp
+++ b/server.cpp
@@ -1,7 +1,19 @@
+#include <boost/beast/version.hpp>
+
+// Support both boost in Debian unstable (BOOST_LATEST) and in stable (boost 1.67)
+#if BOOST_VERSION >= 107100
+#define BOOST_LATEST
+#endif
+
#include <boost/beast/core.hpp>
#include <boost/beast/http.hpp>
#include <boost/beast/version.hpp>
+#ifdef BOOST_LATEST
#include <boost/beast/ssl.hpp>
+#else
+#include <boost/asio/ip/tcp.hpp>
+#include <boost/asio/ssl/stream.hpp>
+#endif
#include <boost/asio/dispatch.hpp>
#include <boost/asio/strand.hpp>
#include <boost/config.hpp>