summaryrefslogtreecommitdiff
path: root/http/app.hpp
diff options
context:
space:
mode:
authorEd Tanous <ed@tanous.net>2020-10-03 18:06:26 +0300
committerEd Tanous <ed@tanous.net>2020-10-23 18:03:17 +0300
commit04e438cbad66838724d78ce12f28aff1fb892a63 (patch)
tree8d8c42a8b3d3e9f8e10c108dd6273e8185d04530 /http/app.hpp
parentdc511aa73001a593a16dbcdaa5d53f320e4c7818 (diff)
downloadbmcweb-04e438cbad66838724d78ce12f28aff1fb892a63.tar.xz
fix include names
cppcheck isn't smart enough to recognize these are c++ headers, not c headers. Considering we're already inconsistent about our naming, it's easier to just be consistent, and move the last few files to use .hpp instead of .h. Tested: Code builds, no changes. Signed-off-by: Ed Tanous <ed@tanous.net> Change-Id: Ic348d695f8527fa4a0ded53f433e1558c319db40
Diffstat (limited to 'http/app.hpp')
-rw-r--r--http/app.hpp230
1 files changed, 230 insertions, 0 deletions
diff --git a/http/app.hpp b/http/app.hpp
new file mode 100644
index 0000000000..9a4eb20a04
--- /dev/null
+++ b/http/app.hpp
@@ -0,0 +1,230 @@
+#pragma once
+
+#include "http_request.hpp"
+#include "http_server.hpp"
+#include "logging.hpp"
+#include "privileges.hpp"
+#include "routing.hpp"
+#include "utility.hpp"
+
+#include <chrono>
+#include <cstdint>
+#include <functional>
+#include <future>
+#include <memory>
+#include <string>
+#include <utility>
+
+#define BMCWEB_ROUTE(app, url) \
+ app.template route<crow::black_magic::getParameterTag(url)>(url)
+
+namespace crow
+{
+#ifdef BMCWEB_ENABLE_SSL
+using ssl_context_t = boost::asio::ssl::context;
+#endif
+class App
+{
+ public:
+#ifdef BMCWEB_ENABLE_SSL
+ using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
+ using ssl_server_t = Server<App, ssl_socket_t>;
+#else
+ using socket_t = boost::asio::ip::tcp::socket;
+ using server_t = Server<App, socket_t>;
+#endif
+
+ explicit App(std::shared_ptr<boost::asio::io_context> ioIn =
+ std::make_shared<boost::asio::io_context>()) :
+ io(std::move(ioIn))
+ {}
+ ~App()
+ {
+ this->stop();
+ }
+
+ template <typename Adaptor>
+ void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
+ {
+ router.handleUpgrade(req, res, std::move(adaptor));
+ }
+
+ void handle(Request& req, Response& res)
+ {
+ router.handle(req, res);
+ }
+
+ DynamicRule& routeDynamic(std::string&& rule)
+ {
+ return router.newRuleDynamic(rule);
+ }
+
+ template <uint64_t Tag>
+ auto& route(std::string&& rule)
+ {
+ return router.newRuleTagged<Tag>(std::move(rule));
+ }
+
+ App& socket(int existing_socket)
+ {
+ socketFd = existing_socket;
+ 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()
+ {
+ validate();
+#ifdef BMCWEB_ENABLE_SSL
+ if (-1 == socketFd)
+ {
+ sslServer = std::make_unique<ssl_server_t>(
+ this, bindaddrStr, portUint, sslContext, io);
+ }
+ else
+ {
+ sslServer =
+ std::make_unique<ssl_server_t>(this, socketFd, sslContext, io);
+ }
+ sslServer->run();
+
+#else
+
+ if (-1 == socketFd)
+ {
+ server = std::move(std::make_unique<server_t>(
+ this, bindaddrStr, portUint, nullptr, io));
+ }
+ else
+ {
+ server = std::move(
+ std::make_unique<server_t>(this, socketFd, nullptr, io));
+ }
+ server->run();
+
+#endif
+ }
+
+ void stop()
+ {
+ io->stop();
+ }
+
+ void debugPrint()
+ {
+ BMCWEB_LOG_DEBUG << "Routing:";
+ router.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);
+ }
+
+#ifdef BMCWEB_ENABLE_SSL
+ App& sslFile(const std::string& crt_filename,
+ const std::string& key_filename)
+ {
+ sslContext = std::make_shared<ssl_context_t>(
+ boost::asio::ssl::context::tls_server);
+ sslContext->set_verify_mode(boost::asio::ssl::verify_peer);
+ sslContext->use_certificate_file(crt_filename, ssl_context_t::pem);
+ sslContext->use_private_key_file(key_filename, ssl_context_t::pem);
+ sslContext->set_options(boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::no_sslv3 |
+ boost::asio::ssl::context::no_tlsv1 |
+ boost::asio::ssl::context::no_tlsv1_1);
+ return *this;
+ }
+
+ App& sslFile(const std::string& pem_filename)
+ {
+ sslContext = std::make_shared<ssl_context_t>(
+ boost::asio::ssl::context::tls_server);
+ sslContext->set_verify_mode(boost::asio::ssl::verify_peer);
+ sslContext->load_verify_file(pem_filename);
+ sslContext->set_options(boost::asio::ssl::context::default_workarounds |
+ boost::asio::ssl::context::no_sslv2 |
+ boost::asio::ssl::context::no_sslv3 |
+ boost::asio::ssl::context::no_tlsv1 |
+ boost::asio::ssl::context::no_tlsv1_1);
+ return *this;
+ }
+
+ 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, typename... Remain>
+ App& ssl_file(T&&, Remain&&...)
+ {
+ // 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;
+ }
+
+ template <typename T>
+ App& ssl(T&&)
+ {
+ // 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;
+#endif
+ std::string bindaddrStr = "::";
+ int socketFd = -1;
+ Router router;
+
+#ifdef BMCWEB_ENABLE_SSL
+ std::unique_ptr<ssl_server_t> sslServer;
+#else
+ std::unique_ptr<server_t> server;
+#endif
+};
+} // namespace crow
+using App = crow::App;