#pragma once #include "async_resp.hpp" #include "http_request.hpp" #include "http_server.hpp" #include "logging.hpp" #include "privileges.hpp" #include "routing.hpp" #include "utility.hpp" #include #include #include #include #include #include #include #include #include #include #include // NOLINTNEXTLINE(cppcoreguidelines-macro-usage, clang-diagnostic-unused-macros) #define BMCWEB_ROUTE(app, url) \ app.template route(url) namespace crow { class App { public: using ssl_socket_t = boost::beast::ssl_stream; using ssl_server_t = Server; using socket_t = boost::asio::ip::tcp::socket; using server_t = Server; explicit App(std::shared_ptr ioIn = std::make_shared()) : io(std::move(ioIn)) {} ~App() { stop(); } App(const App&) = delete; App(App&&) = delete; App& operator=(const App&) = delete; App& operator=(const App&&) = delete; template void handleUpgrade(Request& req, const std::shared_ptr& asyncResp, Adaptor&& adaptor) { router.handleUpgrade(req, asyncResp, std::forward(adaptor)); } void handle(Request& req, const std::shared_ptr& asyncResp) { router.handle(req, asyncResp); } DynamicRule& routeDynamic(const std::string& rule) { return router.newRuleDynamic(rule); } template auto& route(std::string&& rule) { return router.newRuleTagged(std::move(rule)); } App& socket(int existingSocket) { socketFd = existingSocket; return *this; } App& port(std::uint16_t port) { portUint = port; return *this; } void validate() { router.validate(); } void run() { validate(); #ifdef BMCWEB_ENABLE_SSL if (-1 == socketFd) { sslServer = std::make_unique(this, portUint, sslContext, io); } else { sslServer = std::make_unique(this, socketFd, sslContext, io); } sslServer->run(); #else if (-1 == socketFd) { server = std::make_unique(this, portUint, nullptr, io); } else { server = std::make_unique(this, socketFd, nullptr, io); } server->run(); #endif } void stop() { io->stop(); } void debugPrint() { BMCWEB_LOG_DEBUG("Routing:"); router.debugPrint(); } std::vector getRoutes() { const std::string root; return router.getRoutes(root); } std::vector getRoutes(const std::string& parent) { return router.getRoutes(parent); } App& ssl(std::shared_ptr&& ctx) { sslContext = std::move(ctx); BMCWEB_LOG_INFO("app::ssl context use_count={}", sslContext.use_count()); return *this; } std::shared_ptr sslContext = nullptr; boost::asio::io_context& ioContext() { return *io; } private: std::shared_ptr io; #ifdef BMCWEB_ENABLE_SSL uint16_t portUint = 443; #else uint16_t portUint = 80; #endif int socketFd = -1; Router router; #ifdef BMCWEB_ENABLE_SSL std::unique_ptr sslServer; #else std::unique_ptr server; #endif }; } // namespace crow using App = crow::App;