15#include <boost/describe/modifiers.hpp>
16#include <boost/asio/ssl/context.hpp>
17#include <boost/describe/members.hpp>
18#include <boost/leaf.hpp>
19#include <boost/mp11/algorithm.hpp>
20#include <boost/beast/http/verb.hpp>
25#include <unordered_map>
42 std::optional<std::variant<SslServerContext, boost::asio::ssl::context>>
sslContext;
48 std::function<void(boost::system::error_code)>
onAcceptAbort = [](
auto) {};
53 std::make_unique<StandardTextResponseProvider>();
75 boost::leaf::result<void>
start(
unsigned short port = 0, std::string
const& host =
"::");
101 template <
typename RequestListenerT,
typename... ConstructionArgsT>
104 auto listener = std::make_shared<RequestListenerT>(std::forward<ConstructionArgsT>(args)...);
105 using routes = boost::describe::
106 describe_members<RequestListenerT, boost::describe::mod_any_access | boost::describe::mod_static>;
107 std::unordered_multimap<boost::beast::http::verb, ProtoRoute> extractedRoutes;
108 boost::mp11::mp_for_each<routes>([&extractedRoutes, &listener,
this]<
typename T>(T route) {
109 this->
addRoute(listener, extractedRoutes, *route.pointer);
131 template <
typename RequestListenerT>
133 std::shared_ptr<RequestListenerT> listener,
134 std::unordered_multimap<boost::beast::http::verb, ProtoRoute>& extractedRoutes,
142 protoRoute.
path = std::string{info.path};
143 protoRoute.matches = [p = info.path](std::string
const& path, std::vector<std::string>&) {
150 protoRoute.path = std::regex{info.path};
152 [p = info.path](std::string
const& path, std::vector<std::string>& regexMatches) {
154 auto result = std::regex_match(path, smatch, std::regex{p});
155 regexMatches.reserve(smatch.size());
156 for (
auto submatch = std::next(std::begin(smatch)), end = std::end(smatch); submatch < end;
158 regexMatches.push_back(submatch->str());
164 throw std::runtime_error(
"Invalid path type for route.");
166 protoRoute.routeOptions = info.routeOptions;
167 protoRoute.callRoute = [serverIsSecure =
isSecure(),
170 allowUnsecure = protoRoute.routeOptions.allowUnsecure](
172 if (serverIsSecure && !session.isSecure() && !allowUnsecure)
173 return session.sendStrictTransportSecurityResponse();
174 std::invoke(handler, *listener, session, std::move(req));
176 extractedRoutes.emplace(*info.
verb, protoRoute);
178 if (protoRoute.routeOptions.cors && protoRoute.routeOptions.cors->generatePreflightOptionsRoute)
180 auto preflightRoute = protoRoute;
181 protoRoute.callRoute = [serverIsSecure =
isSecure(),
182 allowUnsecure = protoRoute.routeOptions.allowUnsecure](
184 if (serverIsSecure && !session.isSecure() && !allowUnsecure)
185 return session.sendStrictTransportSecurityResponse();
186 session.send<boost::beast::http::empty_body>(session.prepareResponse(req))->commit();
188 extractedRoutes.emplace(boost::beast::http::verb::options, preflightRoute);
192 template <
typename RequestListenerT>
194 std::shared_ptr<RequestListenerT> listener,
195 std::unordered_multimap<boost::beast::http::verb, ProtoRoute>& extractedRoutes,
198 namespace http = boost::beast::http;
202 protoRoute.routeOptions = info.routeOptions;
206 .listener_ = listener,
208 auto dserverCpy = dserver;
209 dserverCpy(session, req);
211 protoRoute.matches = [p = info.path](std::string
const& path, std::vector<std::string>&) {
212 return path.starts_with(p);
215 extractedRoutes.emplace(http::verb::options, protoRoute);
216 extractedRoutes.emplace(http::verb::head, protoRoute);
217 extractedRoutes.emplace(http::verb::get, protoRoute);
218 extractedRoutes.emplace(http::verb::put, protoRoute);
219 extractedRoutes.emplace(http::verb::delete_, protoRoute);
225 struct Implementation;
226 std::shared_ptr<Implementation>
impl_;
static constexpr int port
Definition main.cpp:16
Definition request_listener.hpp:8
Internal helper class to serve directories.
Definition directory_server.hpp:63
This class extends the boost::beast::http::request<BodyT> with additional convenience.
Definition request.hpp:52
Server & operator=(Server &&)
boost::leaf::result< void > start(boost::asio::ip::basic_endpoint< boost::asio::ip::tcp > const &bindEndpoint)
Starts the server given the already resolved bind endpoint.
Server(Server const &)=delete
void addRoute(std::shared_ptr< RequestListenerT > listener, std::unordered_multimap< boost::beast::http::verb, ProtoRoute > &extractedRoutes, RouteInfo< RequestListenerT > const &info)
Definition server.hpp:132
boost::asio::any_io_executor getExecutor() const
Get the Executor object.
Definition server.cpp:105
std::shared_ptr< RequestListenerT > installRequestListener(ConstructionArgsT &&... args)
Attach a request listener to this server to receive requests.
Definition server.hpp:102
boost::leaf::result< void > start(unsigned short port=0, std::string const &host="::")
Bind and listen for network interface and port.
Definition server.cpp:110
boost::asio::ip::basic_endpoint< boost::asio::ip::tcp > const & getLocalEndpoint() const
Get the local endpoint that this server bound to.
Definition server.cpp:116
void stop()
Stop and shutdown the server.
Definition server.cpp:148
~Server()
Definition server.cpp:100
std::shared_ptr< Implementation > impl_
Definition server.hpp:226
void addRoute(std::shared_ptr< RequestListenerT > listener, std::unordered_multimap< boost::beast::http::verb, ProtoRoute > &extractedRoutes, ServeInfo< RequestListenerT > const &info)
Definition server.hpp:193
Server & operator=(Server const &)=delete
void addRequestListenerToRouter(std::unordered_multimap< boost::beast::http::verb, ProtoRoute > &&routes)
Definition server.cpp:154
bool isSecure() const
Returns whether this server has a certificate and key and is therefore a HTTPS server.
Definition server.cpp:159
Definition session.hpp:41
Definition forward.hpp:18
Definition authorization.hpp:10
@ RegularString
Take precedence over any other path.
@ Regex
Take precedence over serve paths.
bool serverIsSecure_
Definition directory_server.hpp:51
Definition proto_route.hpp:32
Holds errors that are produced asynchronously anywhere.
Definition error.hpp:20
A proper Route is built up from this object. This object is usually created internally.
Definition proto_route.hpp:45
std::variant< std::string, std::regex, Detail::ServedPath > path
Definition proto_route.hpp:46
This class is what is used in ROAR_GET, ROAR_PUT, ... requests All options you can set for routes beh...
Definition request_listener.hpp:120
HandlerType< RequestListenerT > handler
Set automatically by the macro.
Definition request_listener.hpp:130
RoutePathType pathType
Is the path a string or a regex, ...?
Definition request_listener.hpp:127
std::optional< boost::beast::http::verb > verb
What verb for this route?
Definition request_listener.hpp:124
Definition request_listener.hpp:135
std::optional< std::variant< SslServerContext, boost::asio::ssl::context > > sslContext
Supply for SSL support.
Definition server.hpp:42
std::unique_ptr< StandardResponseProvider > standardResponseProvider
Definition server.hpp:52
boost::asio::any_io_executor executor
Required io executor for boost::asio.
Definition server.hpp:39
std::function< void(boost::system::error_code)> onAcceptAbort
Called when the server stops accepting connections for error reasons.
Definition server.hpp:48
std::function< void(Error &&)> onError
Called when an error occurs in an asynchronous routine.
Definition server.hpp:45