diff --git a/include/roar/server.hpp b/include/roar/server.hpp index eb0d8f0b..7176ef8a 100644 --- a/include/roar/server.hpp +++ b/include/roar/server.hpp @@ -25,6 +25,7 @@ #include #include #include +#include namespace Roar { @@ -38,7 +39,7 @@ namespace Roar boost::asio::any_io_executor executor; /// Supply for SSL support. - std::optional sslContext; + std::optional> sslContext; /// Called when an error occurs in an asynchronous routine. std::function onError = [](auto&&) {}; diff --git a/include/roar/session/factory.hpp b/include/roar/session/factory.hpp index b4ad7c74..151b6330 100644 --- a/include/roar/session/factory.hpp +++ b/include/roar/session/factory.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace Roar @@ -24,7 +25,9 @@ namespace Roar constexpr static std::chrono::seconds sslDetectionTimeout{10}; public: - Factory(std::optional& sslContext, std::function onError); + Factory( + std::optional>& sslContext, + std::function onError); ROAR_PIMPL_SPECIAL_FUNCTIONS(Factory); /** diff --git a/include/roar/session/session.hpp b/include/roar/session/session.hpp index 171f3ef4..95d913e0 100644 --- a/include/roar/session/session.hpp +++ b/include/roar/session/session.hpp @@ -50,7 +50,7 @@ namespace Roar Session( boost::asio::basic_stream_socket&& socket, boost::beast::basic_flat_buffer>&& buffer, - std::optional& sslContext, + std::optional>& sslContext, bool isSecure, std::function onError, std::weak_ptr router, diff --git a/include/roar/ssl/make_ssl_context.hpp b/include/roar/ssl/make_ssl_context.hpp index aaed972f..f722ea66 100644 --- a/include/roar/ssl/make_ssl_context.hpp +++ b/include/roar/ssl/make_ssl_context.hpp @@ -25,4 +25,6 @@ namespace Roar * @return boost::asio::ssl::context */ void initializeServerSslContext(SslServerContext& ctx); + + boost::asio::ssl::context makeSslContext(const std::string& certificate, const std::string& privateKey); } \ No newline at end of file diff --git a/src/roar/server.cpp b/src/roar/server.cpp index 85dd83de..bdaf417d 100644 --- a/src/roar/server.cpp +++ b/src/roar/server.cpp @@ -20,7 +20,7 @@ namespace Roar struct Server::Implementation : public std::enable_shared_from_this { boost::asio::ip::tcp::acceptor acceptor; - std::optional sslContext; + std::optional> sslContext; boost::asio::ip::tcp::endpoint bindEndpoint; boost::asio::ip::tcp::endpoint resolvedEndpoint; std::shared_mutex acceptorStopGuard; @@ -32,7 +32,7 @@ namespace Roar Implementation( boost::asio::any_io_executor& executor, - std::optional sslContext, + std::optional> sslContext, std::function onError, std::function onAcceptAbort, std::unique_ptr standardResponseProvider); @@ -42,7 +42,7 @@ namespace Roar //------------------------------------------------------------------------------------------------------------------ Server::Implementation::Implementation( boost::asio::any_io_executor& executor, - std::optional sslContext, + std::optional> sslContext, std::function onError, std::function onAcceptAbort, std::unique_ptr standardResponseProvider) diff --git a/src/roar/session/factory.cpp b/src/roar/session/factory.cpp index b2193a94..0a4b21d5 100644 --- a/src/roar/session/factory.cpp +++ b/src/roar/session/factory.cpp @@ -28,16 +28,16 @@ namespace Roar // ################################################################################################################## struct Factory::Implementation { - std::optional& sslContext; + std::optional>& sslContext; std::function onError; - Implementation(std::optional& sslContext, std::function onError) + Implementation(std::optional>& sslContext, std::function onError) : sslContext{sslContext} , onError{std::move(onError)} {} }; // ################################################################################################################## - Factory::Factory(std::optional& sslContext, std::function onError) + Factory::Factory(std::optional>& sslContext, std::function onError) : impl_{std::make_unique(sslContext, std::move(onError))} {} //------------------------------------------------------------------------------------------------------------------ diff --git a/src/roar/session/session.cpp b/src/roar/session/session.cpp index cfa80165..5d98d319 100644 --- a/src/roar/session/session.cpp +++ b/src/roar/session/session.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -33,14 +34,29 @@ namespace Roar Implementation( boost::asio::ip::tcp::socket&& socket, boost::beast::flat_buffer&& buffer, - std::optional& sslContext, + std::optional>& sslContext, bool isSecure, std::function onError, std::weak_ptr router, std::shared_ptr standardResponseProvider) - : stream{[&socket, &sslContext, isSecure]() -> decltype(stream) { + : stream{[&socket, &sslContext, isSecure]() mutable -> decltype(stream) { if (isSecure) - return boost::beast::ssl_stream{std::move(socket), sslContext->ctx}; + { + if (!sslContext) + throw std::runtime_error{"No SSL context available."}; + + return boost::beast::ssl_stream{ + std::move(socket), [&sslContext]() -> boost::asio::ssl::context& { + return std::visit( + [](auto& ctx) -> boost::asio::ssl::context& { + if constexpr (std::is_same_v, SslServerContext>) + return ctx.ctx; + else + return ctx; + }, + *sslContext); + }()}; + } return Detail::StreamType{std::move(socket)}; }()} , buffer{std::move(buffer)} @@ -62,7 +78,7 @@ namespace Roar Session::Session( boost::asio::ip::tcp::socket&& socket, boost::beast::flat_buffer&& buffer, - std::optional& sslContext, + std::optional>& sslContext, bool isSecure, std::function onError, std::weak_ptr router, diff --git a/src/roar/ssl/make_ssl_context.cpp b/src/roar/ssl/make_ssl_context.cpp index deade578..285fe245 100644 --- a/src/roar/ssl/make_ssl_context.cpp +++ b/src/roar/ssl/make_ssl_context.cpp @@ -42,4 +42,13 @@ namespace Roar boost::asio::buffer(ctx.diffieHellmanParameters.data(), ctx.diffieHellmanParameters.size())); } } + + boost::asio::ssl::context makeSslContext(const std::string& certificate, const std::string& privateKey) + { + SslServerContext ctx; + ctx.certificate = certificate; + ctx.privateKey = privateKey; + initializeServerSslContext(ctx); + return std::move(ctx.ctx); + } } \ No newline at end of file