blob: 1a7af8324139f7defbee02a8f097ff5c7cd80205 [file] [log] [blame]
Ed Tanous7045c8d2017-04-03 10:04:37 -07001#pragma once
2
zhanghch058d1b46d2021-04-01 11:18:24 +08003#include "async_resp.hpp"
Ed Tanous04e438c2020-10-03 08:06:26 -07004#include "http_request.hpp"
5#include "http_server.hpp"
6#include "logging.hpp"
Tanousf00032d2018-11-05 01:18:10 -03007#include "privileges.hpp"
Ed Tanous04e438c2020-10-03 08:06:26 -07008#include "routing.hpp"
9#include "utility.hpp"
Tanousf00032d2018-11-05 01:18:10 -030010
Nan Zhoucec58fe2022-06-14 20:45:45 +000011#include <boost/asio/io_context.hpp>
12#include <boost/asio/ip/tcp.hpp>
Nan Zhoucec58fe2022-06-14 20:45:45 +000013#include <boost/asio/ssl/context.hpp>
14#include <boost/beast/ssl/ssl_stream.hpp>
Nan Zhoucec58fe2022-06-14 20:45:45 +000015
Ed Tanous7045c8d2017-04-03 10:04:37 -070016#include <chrono>
17#include <cstdint>
18#include <functional>
19#include <future>
20#include <memory>
21#include <string>
Ed Tanous911ac312017-08-15 09:37:42 -070022#include <utility>
Ed Tanous1abe55e2018-09-05 08:30:59 -070023
Patrick Williamsa2323432023-05-12 10:06:35 -050024// NOLINTNEXTLINE(cppcoreguidelines-macro-usage, clang-diagnostic-unused-macros)
Ed Tanous1abe55e2018-09-05 08:30:59 -070025#define BMCWEB_ROUTE(app, url) \
Ed Tanous47488a92023-06-26 18:19:33 -070026 app.template route<crow::utility::getParameterTag(url)>(url)
Ed Tanous7045c8d2017-04-03 10:04:37 -070027
Ed Tanous1abe55e2018-09-05 08:30:59 -070028namespace crow
29{
Ed Tanous52cc1122020-07-18 13:51:21 -070030class App
Ed Tanous1abe55e2018-09-05 08:30:59 -070031{
32 public:
Ed Tanousceac6f72018-12-02 11:58:47 -080033 using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
Ed Tanous52cc1122020-07-18 13:51:21 -070034 using ssl_server_t = Server<App, ssl_socket_t>;
Ed Tanousceac6f72018-12-02 11:58:47 -080035 using socket_t = boost::asio::ip::tcp::socket;
Ed Tanous52cc1122020-07-18 13:51:21 -070036 using server_t = Server<App, socket_t>;
Ed Tanousceac6f72018-12-02 11:58:47 -080037
Ed Tanous52cc1122020-07-18 13:51:21 -070038 explicit App(std::shared_ptr<boost::asio::io_context> ioIn =
39 std::make_shared<boost::asio::io_context>()) :
Ed Tanous271584a2019-07-09 16:24:22 -070040 io(std::move(ioIn))
Gunnar Mills1214b7e2020-06-04 10:11:30 -050041 {}
Ed Tanous52cc1122020-07-18 13:51:21 -070042 ~App()
Ed Tanous1abe55e2018-09-05 08:30:59 -070043 {
Ed Tanous21b4aba2023-06-05 11:42:43 -070044 stop();
Ed Tanous1abe55e2018-09-05 08:30:59 -070045 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070046
Ed Tanousecd6a3a2022-01-07 09:18:40 -080047 App(const App&) = delete;
48 App(App&&) = delete;
49 App& operator=(const App&) = delete;
50 App& operator=(const App&&) = delete;
51
Ed Tanous1abe55e2018-09-05 08:30:59 -070052 template <typename Adaptor>
P Dheeraj Srujan Kumar7e9093e2021-09-18 01:19:04 +053053 void handleUpgrade(Request& req,
P Dheeraj Srujan Kumara9f076e2021-10-18 22:45:37 +053054 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
55 Adaptor&& adaptor)
Ed Tanous1abe55e2018-09-05 08:30:59 -070056 {
P Dheeraj Srujan Kumara9f076e2021-10-18 22:45:37 +053057 router.handleUpgrade(req, asyncResp, std::forward<Adaptor>(adaptor));
Ed Tanous1abe55e2018-09-05 08:30:59 -070058 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070059
zhanghch058d1b46d2021-04-01 11:18:24 +080060 void handle(Request& req,
61 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous1abe55e2018-09-05 08:30:59 -070062 {
zhanghch058d1b46d2021-04-01 11:18:24 +080063 router.handle(req, asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -070064 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070065
Ed Tanous1abe55e2018-09-05 08:30:59 -070066 DynamicRule& routeDynamic(std::string&& rule)
67 {
68 return router.newRuleDynamic(rule);
69 }
70
Gunnar Mills1214b7e2020-06-04 10:11:30 -050071 template <uint64_t Tag>
72 auto& route(std::string&& rule)
Ed Tanous1abe55e2018-09-05 08:30:59 -070073 {
74 return router.newRuleTagged<Tag>(std::move(rule));
75 }
76
Ed Tanous81ce6092020-12-17 16:54:55 +000077 App& socket(int existingSocket)
Ed Tanous1abe55e2018-09-05 08:30:59 -070078 {
Ed Tanous81ce6092020-12-17 16:54:55 +000079 socketFd = existingSocket;
Ed Tanous1abe55e2018-09-05 08:30:59 -070080 return *this;
81 }
82
Ed Tanousb74e4402020-09-09 20:26:26 -070083 App& port(std::uint16_t port)
Ed Tanous1abe55e2018-09-05 08:30:59 -070084 {
85 portUint = port;
86 return *this;
87 }
88
Ed Tanous1abe55e2018-09-05 08:30:59 -070089 void validate()
90 {
91 router.validate();
92 }
93
94 void run()
95 {
96 validate();
97#ifdef BMCWEB_ENABLE_SSL
Ed Tanous789a6a32018-11-29 15:17:22 -080098 if (-1 == socketFd)
Ed Tanous1abe55e2018-09-05 08:30:59 -070099 {
Ed Tanous4fa45df2023-09-01 14:20:50 -0700100 sslServer = std::make_unique<ssl_server_t>(this, portUint,
101 sslContext, io);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700102 }
103 else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700104 {
Patrick Williams89492a12023-05-10 07:51:34 -0500105 sslServer = std::make_unique<ssl_server_t>(this, socketFd,
106 sslContext, io);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700107 }
Ed Tanous789a6a32018-11-29 15:17:22 -0800108 sslServer->run();
109
110#else
111
112 if (-1 == socketFd)
113 {
Ed Tanous4fa45df2023-09-01 14:20:50 -0700114 server = std::make_unique<server_t>(this, portUint, nullptr, io);
Ed Tanous789a6a32018-11-29 15:17:22 -0800115 }
116 else
117 {
Nan Zhoud9049df2022-08-02 18:38:18 +0000118 server = std::make_unique<server_t>(this, socketFd, nullptr, io);
Ed Tanous789a6a32018-11-29 15:17:22 -0800119 }
Ed Tanous789a6a32018-11-29 15:17:22 -0800120 server->run();
121
122#endif
Ed Tanous1abe55e2018-09-05 08:30:59 -0700123 }
124
125 void stop()
126 {
127 io->stop();
128 }
129
130 void debugPrint()
131 {
Ed Tanous62598e32023-07-17 17:06:25 -0700132 BMCWEB_LOG_DEBUG("Routing:");
Ed Tanous1abe55e2018-09-05 08:30:59 -0700133 router.debugPrint();
134 }
135
136 std::vector<const std::string*> getRoutes()
137 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800138 const std::string root;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700139 return router.getRoutes(root);
140 }
141 std::vector<const std::string*> getRoutes(const std::string& parent)
142 {
143 return router.getRoutes(parent);
144 }
Ed Tanousb4a7bfa2017-04-04 17:23:00 -0700145
Ed Tanousb74e4402020-09-09 20:26:26 -0700146 App& ssl(std::shared_ptr<boost::asio::ssl::context>&& ctx)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700147 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700148 sslContext = std::move(ctx);
Ed Tanous62598e32023-07-17 17:06:25 -0700149 BMCWEB_LOG_INFO("app::ssl context use_count={}",
150 sslContext.use_count());
Ed Tanous1abe55e2018-09-05 08:30:59 -0700151 return *this;
152 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700153
Ed Tanous4fa45df2023-09-01 14:20:50 -0700154 std::shared_ptr<boost::asio::ssl::context> sslContext = nullptr;
Ed Tanous7045c8d2017-04-03 10:04:37 -0700155
Ed Tanousf8ca6d72022-06-28 12:12:03 -0700156 boost::asio::io_context& ioContext()
157 {
158 return *io;
159 }
160
Ed Tanous1abe55e2018-09-05 08:30:59 -0700161 private:
Ed Tanous23e64202020-09-15 19:21:30 -0700162 std::shared_ptr<boost::asio::io_context> io;
Ed Tanous789a6a32018-11-29 15:17:22 -0800163#ifdef BMCWEB_ENABLE_SSL
164 uint16_t portUint = 443;
165#else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700166 uint16_t portUint = 80;
Ed Tanous789a6a32018-11-29 15:17:22 -0800167#endif
Ed Tanous1abe55e2018-09-05 08:30:59 -0700168 int socketFd = -1;
169 Router router;
Ed Tanous7045c8d2017-04-03 10:04:37 -0700170
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700171#ifdef BMCWEB_ENABLE_SSL
Ed Tanous1abe55e2018-09-05 08:30:59 -0700172 std::unique_ptr<ssl_server_t> sslServer;
Ed Tanous789a6a32018-11-29 15:17:22 -0800173#else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700174 std::unique_ptr<server_t> server;
Ed Tanous789a6a32018-11-29 15:17:22 -0800175#endif
Ed Tanous7045c8d2017-04-03 10:04:37 -0700176};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700177} // namespace crow
Ed Tanous52cc1122020-07-18 13:51:21 -0700178using App = crow::App;