diff options
author | ipknHama <ipknhama@gmail.com> | 2016-09-21 23:11:06 +0900 |
---|---|---|
committer | ipknHama <ipknhama@gmail.com> | 2016-09-21 23:11:06 +0900 |
commit | 3081e4e1a82a4efd8feff68850c4cc04af230cd7 (patch) | |
tree | 3ad16ef2e940abd2d47c4ac3ca224365387b7f37 /include/crow/app.h | |
parent | 8b04940d2f28290451db439ad29155a0b8771ba3 (diff) | |
download | crow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.tar.gz crow-3081e4e1a82a4efd8feff68850c4cc04af230cd7.zip |
Cleanup include folder into crow subfolder
- only crow.h is exposed now
Diffstat (limited to 'include/crow/app.h')
-rw-r--r-- | include/crow/app.h | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/include/crow/app.h b/include/crow/app.h new file mode 100644 index 0000000..cb72d3a --- /dev/null +++ b/include/crow/app.h @@ -0,0 +1,242 @@ +#pragma once + +#include <chrono> +#include <string> +#include <functional> +#include <memory> +#include <future> +#include <cstdint> +#include <type_traits> +#include <thread> + +#include "crow/settings.h" +#include "crow/logging.h" +#include "crow/utility.h" +#include "crow/routing.h" +#include "crow/middleware_context.h" +#include "crow/http_request.h" +#include "crow/http_server.h" + + +#ifdef CROW_MSVC_WORKAROUND +#define CROW_ROUTE(app, url) app.route_dynamic(url) +#else +#define CROW_ROUTE(app, url) app.route<crow::black_magic::get_parameter_tag(url)>(url) +#endif + +namespace crow +{ +#ifdef CROW_ENABLE_SSL + using ssl_context_t = boost::asio::ssl::context; +#endif + template <typename ... Middlewares> + class Crow + { + public: + using self_t = Crow; + using server_t = Server<Crow, SocketAdaptor, Middlewares...>; +#ifdef CROW_ENABLE_SSL + using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>; +#endif + Crow() + { + } + + template <typename Adaptor> + void handle_upgrade(const request& req, response& res, Adaptor&& adaptor) + { + router_.handle_upgrade(req, res, adaptor); + } + + 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 <uint64_t Tag> + auto route(std::string&& rule) + -> typename std::result_of<decltype(&Router::new_rule_tagged<Tag>)(Router, std::string&&)>::type + { + return router_.new_rule_tagged<Tag>(std::move(rule)); + } + + self_t& port(std::uint16_t port) + { + port_ = port; + return *this; + } + + self_t& bindaddr(std::string bindaddr) + { + bindaddr_ = bindaddr; + 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(); +#ifdef CROW_ENABLE_SSL + if (use_ssl_) + { + ssl_server_ = std::move(std::unique_ptr<ssl_server_t>(new ssl_server_t(this, bindaddr_, port_, &middlewares_, concurrency_, &ssl_context_))); + ssl_server_->set_tick_function(tick_interval_, tick_function_); + ssl_server_->run(); + } + else +#endif + { + server_ = std::move(std::unique_ptr<server_t>(new server_t(this, bindaddr_, port_, &middlewares_, concurrency_, nullptr))); + server_->set_tick_function(tick_interval_, tick_function_); + server_->run(); + } + } + + void stop() + { +#ifdef CROW_ENABLE_SSL + if (use_ssl_) + { + ssl_server_->stop(); + } + else +#endif + { + server_->stop(); + } + } + + void debug_print() + { + CROW_LOG_DEBUG << "Routing:"; + router_.debug_print(); + } + +#ifdef CROW_ENABLE_SSL + self_t& ssl_file(const std::string& crt_filename, const std::string& key_filename) + { + use_ssl_ = true; + ssl_context_.set_verify_mode(boost::asio::ssl::verify_peer); + ssl_context_.use_certificate_file(crt_filename, ssl_context_t::pem); + ssl_context_.use_private_key_file(key_filename, ssl_context_t::pem); + ssl_context_.set_options( + boost::asio::ssl::context::default_workarounds + | boost::asio::ssl::context::no_sslv2 + | boost::asio::ssl::context::no_sslv3 + ); + return *this; + } + + self_t& ssl_file(const std::string& pem_filename) + { + use_ssl_ = true; + ssl_context_.set_verify_mode(boost::asio::ssl::verify_peer); + ssl_context_.load_verify_file(pem_filename); + ssl_context_.set_options( + boost::asio::ssl::context::default_workarounds + | boost::asio::ssl::context::no_sslv2 + | boost::asio::ssl::context::no_sslv3 + ); + return *this; + } + + self_t& ssl(boost::asio::ssl::context&& ctx) + { + use_ssl_ = true; + ssl_context_ = std::move(ctx); + return *this; + } + + + bool use_ssl_{false}; + ssl_context_t ssl_context_{boost::asio::ssl::context::sslv23}; + +#else + template <typename T, typename ... Remain> + self_t& ssl_file(T&&, Remain&&...) + { + // We can't call .ssl() member function unless CROW_ENABLE_SSL is defined. + static_assert( + // make static_assert dependent to T; always false + std::is_base_of<T, void>::value, + "Define CROW_ENABLE_SSL to enable ssl support."); + return *this; + } + + template <typename T> + self_t& ssl(T&&) + { + // We can't call .ssl() member function unless CROW_ENABLE_SSL is defined. + static_assert( + // make static_assert dependent to T; always false + std::is_base_of<T, void>::value, + "Define CROW_ENABLE_SSL to enable ssl support."); + return *this; + } +#endif + + // middleware + using context_t = detail::context<Middlewares...>; + template <typename T> + typename T::context& get_context(const request& req) + { + static_assert(black_magic::contains<T, Middlewares...>::value, "App doesn't have the specified middleware type."); + auto& ctx = *reinterpret_cast<context_t*>(req.middleware_context); + return ctx.template get<T>(); + } + + template <typename T> + T& get_middleware() + { + return utility::get_element_by_type<T, Middlewares...>(middlewares_); + } + + template <typename Duration, typename Func> + self_t& tick(Duration d, Func f) { + tick_interval_ = std::chrono::duration_cast<std::chrono::milliseconds>(d); + tick_function_ = f; + return *this; + } + + private: + uint16_t port_ = 80; + uint16_t concurrency_ = 1; + std::string bindaddr_ = "0.0.0.0"; + Router router_; + + std::chrono::milliseconds tick_interval_; + std::function<void()> tick_function_; + + std::tuple<Middlewares...> middlewares_; + +#ifdef CROW_ENABLE_SSL + std::unique_ptr<ssl_server_t> ssl_server_; +#endif + std::unique_ptr<server_t> server_; + }; + template <typename ... Middlewares> + using App = Crow<Middlewares...>; + using SimpleApp = Crow<>; +} |