blob: 6893cd4924cac36664b4474a2306d046dc0f9235 [file] [log] [blame]
#ifndef THIRD_PARTY_GBMCWEB_HTTP_APP_H_
#define THIRD_PARTY_GBMCWEB_HTTP_APP_H_
#include "http_request.hpp"
#include "async_resp.hpp"
#include "privileges.hpp"
#include "app_interface.h"
#include "smart_router.h"
// #include "utility.hpp"
#include "boost/asio/io_context.hpp" // NOLINT
#include "boost/asio/ip/tcp.hpp" // NOLINT
#include "routing.hpp"
#ifdef BMCWEB_ENABLE_SSL
#include "boost/asio/ssl/context.hpp" // NOLINT
#include "boost/beast/ssl/ssl_stream.hpp" // NOLINT
#endif
#include <array>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
#define BMCWEB_ROUTE(app, url) \
app.template route<crow::black_magic::getParameterTag(url)>(url)
#ifdef BMCWEB_ENABLE_SSL
using ssl_context_t = boost::asio::ssl::context;
using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
#else
using socket_t = boost::asio::ip::tcp::socket;
#endif
namespace crow {
class App {
public:
explicit App(bool allowSessionEmpty,
std::shared_ptr<boost::asio::io_context> ioIn =
std::make_shared<boost::asio::io_context>(),
AppInterface* tlbmc_app = nullptr)
: io(std::move(ioIn)), router(allowSessionEmpty, tlbmc_app) {}
~App() { this->stop(); }
App(const App&) = delete;
App(App&&) = delete;
App& operator=(const App&) = delete;
App& operator=(const App&&) = delete;
template <typename Adaptor>
void handleUpgrade(Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Adaptor&& adaptor) {
router.HandleUpgrade(req, asyncResp, std::forward<Adaptor>(adaptor));
}
void handle(Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
DynamicRule& routeDynamic(std::string&& rule) {
return router.NewRuleDynamic(std::move(rule));
}
template <uint64_t Tag>
auto& route(std::string&& rule) {
return router.NewRuleTagged<Tag>(std::move(rule));
}
App& socket(int existingSocket) {
socketFd = existingSocket;
return *this;
}
App& port(std::uint16_t port) {
portUint = port;
return *this;
}
App& bindaddr(std::string bindaddr) {
bindaddrStr = std::move(bindaddr);
return *this;
}
void validate() { router.Validate(); }
void run();
void stop() { io->stop(); }
void debugPrint();
std::vector<const std::string*> getRoutes() {
const std::string root;
return router.GetRoutes(root);
}
std::vector<const std::string*> getRoutes(const std::string& parent) {
return router.GetRoutes(parent);
}
template <uint64_t Tag, typename Func, size_t N>
void addHandler(std::string_view url, boost::beast::http::verb verb,
const std::array<redfish::Privileges, N>& p, Func&& func) {
router.NewRuleTagged<Tag>(url).methods(verb).privileges(p)(func);
}
template <uint64_t Tag, typename Func>
void replaceHandler(std::string_view url, boost::beast::http::verb verb,
Func&& func) {
router.ReplaceHandler<Tag>(url, verb, func);
}
template <uint64_t Tag>
void removeHandler(std::string_view url, boost::beast::http::verb verb) {
router.RemoveHandler<Tag>(url, verb);
}
template <uint64_t Tag, typename Func>
void appendHandler(std::string_view url, boost::beast::http::verb verb,
Func&& func) {
router.AppendHandler<Tag>(url, verb, func);
}
#ifdef BMCWEB_ENABLE_SSL
App& ssl(std::shared_ptr<boost::asio::ssl::context>&& ctx) {
sslContext = std::move(ctx);
BMCWEB_LOG_INFO << "app::ssl context use_count=" << sslContext.use_count();
return *this;
}
std::shared_ptr<ssl_context_t> sslContext = nullptr;
#else
template <typename T>
App& ssl(T&& /*unused*/) {
// We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
// defined.
static_assert(
// make static_assert dependent to T; always false
std::is_base_of<T, void>::value,
"Define BMCWEB_ENABLE_SSL to enable ssl support.");
return *this;
}
#endif
private:
std::shared_ptr<boost::asio::io_context> io;
#ifdef BMCWEB_ENABLE_SSL
uint16_t portUint = 443;
#else
uint16_t portUint = 80; // NOLINT
#endif
std::string bindaddrStr = "0.0.0.0"; // NOLINT
int socketFd = -1; // NOLINT
SmartRouter router; // NOLINT
};
} // namespace crow
using App = crow::App;
#endif // THIRD_PARTY_GBMCWEB_HTTP_APP_H_