#pragma once #include #include #include #include #include #include #include #include "settings.h" #include "logging.h" #include "utility.h" #include "routing.h" #include "middleware_context.h" #include "http_request.h" #include "http_server.h" #define CROW_ROUTE(app, url) app.route(url) namespace crow { template class Crow { public: using self_t = Crow; using server_t = Server; Crow() { } void handle(const request& req, response& res) { router_.handle(req, res); } DynamicRule& route_dynamic(std::string&& rule) { return router_.new_rule_dynamic(std::move(rule)); } template auto route(std::string&& rule) -> typename std::result_of)(Router, std::string&&)>::type { return router_.new_rule_tagged(std::move(rule)); } self_t& port(std::uint16_t port) { port_ = port; return *this; } self_t& multithreaded() { return concurrency(std::thread::hardware_concurrency()); } self_t& concurrency(std::uint16_t concurrency) { if (concurrency < 1) concurrency = 1; concurrency_ = concurrency; return *this; } void validate() { router_.validate(); } void run() { validate(); server_t server(this, port_, &middlewares_, concurrency_); server.run(); } void debug_print() { CROW_LOG_DEBUG << "Routing:"; router_.debug_print(); } // middleware using context_t = detail::context; template typename T::context& get_context(const request& req) { static_assert(black_magic::contains::value, "App doesn't have the specified middleware type."); auto& ctx = *reinterpret_cast(req.middleware_context); return ctx.template get(); } template T& get_middleware() { return utility::get_element_by_type(middlewares_); } private: uint16_t port_ = 80; uint16_t concurrency_ = 1; Router router_; std::tuple middlewares_; }; template using App = Crow; using SimpleApp = Crow<>; };