blob: d3afe60f05cc5ee09fda10949bf79b7386aa69e5 [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>
13#ifdef BMCWEB_ENABLE_SSL
14#include <boost/asio/ssl/context.hpp>
15#include <boost/beast/ssl/ssl_stream.hpp>
16#endif
17
Ed Tanous7045c8d2017-04-03 10:04:37 -070018#include <chrono>
19#include <cstdint>
20#include <functional>
21#include <future>
22#include <memory>
23#include <string>
Ed Tanous911ac312017-08-15 09:37:42 -070024#include <utility>
Ed Tanous1abe55e2018-09-05 08:30:59 -070025
Ed Tanous600d2392022-01-07 09:32:03 -080026// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
Ed Tanous1abe55e2018-09-05 08:30:59 -070027#define BMCWEB_ROUTE(app, url) \
Ed Tanous988403c2020-08-24 11:29:49 -070028 app.template route<crow::black_magic::getParameterTag(url)>(url)
Ed Tanous7045c8d2017-04-03 10:04:37 -070029
Ed Tanous1abe55e2018-09-05 08:30:59 -070030namespace crow
31{
Ed Tanous55c7b7a2018-05-22 15:27:24 -070032#ifdef BMCWEB_ENABLE_SSL
Ed Tanous7045c8d2017-04-03 10:04:37 -070033using ssl_context_t = boost::asio::ssl::context;
34#endif
Ed Tanous52cc1122020-07-18 13:51:21 -070035class App
Ed Tanous1abe55e2018-09-05 08:30:59 -070036{
37 public:
Ed Tanous55c7b7a2018-05-22 15:27:24 -070038#ifdef BMCWEB_ENABLE_SSL
Ed Tanousceac6f72018-12-02 11:58:47 -080039 using ssl_socket_t = boost::beast::ssl_stream<boost::asio::ip::tcp::socket>;
Ed Tanous52cc1122020-07-18 13:51:21 -070040 using ssl_server_t = Server<App, ssl_socket_t>;
Ed Tanous789a6a32018-11-29 15:17:22 -080041#else
Ed Tanousceac6f72018-12-02 11:58:47 -080042 using socket_t = boost::asio::ip::tcp::socket;
Ed Tanous52cc1122020-07-18 13:51:21 -070043 using server_t = Server<App, socket_t>;
Ed Tanous7045c8d2017-04-03 10:04:37 -070044#endif
Ed Tanousceac6f72018-12-02 11:58:47 -080045
Ed Tanous52cc1122020-07-18 13:51:21 -070046 explicit App(std::shared_ptr<boost::asio::io_context> ioIn =
47 std::make_shared<boost::asio::io_context>()) :
Ed Tanous271584a2019-07-09 16:24:22 -070048 io(std::move(ioIn))
Gunnar Mills1214b7e2020-06-04 10:11:30 -050049 {}
Ed Tanous52cc1122020-07-18 13:51:21 -070050 ~App()
Ed Tanous1abe55e2018-09-05 08:30:59 -070051 {
52 this->stop();
53 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070054
Ed Tanousecd6a3a2022-01-07 09:18:40 -080055 App(const App&) = delete;
56 App(App&&) = delete;
57 App& operator=(const App&) = delete;
58 App& operator=(const App&&) = delete;
59
Ed Tanous1abe55e2018-09-05 08:30:59 -070060 template <typename Adaptor>
61 void handleUpgrade(const Request& req, Response& res, Adaptor&& adaptor)
62 {
Ed Tanousf94c4ec2022-01-06 12:44:41 -080063 router.handleUpgrade(req, res, std::forward<Adaptor>(adaptor));
Ed Tanous1abe55e2018-09-05 08:30:59 -070064 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070065
zhanghch058d1b46d2021-04-01 11:18:24 +080066 void handle(Request& req,
67 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous1abe55e2018-09-05 08:30:59 -070068 {
zhanghch058d1b46d2021-04-01 11:18:24 +080069 router.handle(req, asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -070070 }
Ed Tanous7045c8d2017-04-03 10:04:37 -070071
Ed Tanous1abe55e2018-09-05 08:30:59 -070072 DynamicRule& routeDynamic(std::string&& rule)
73 {
74 return router.newRuleDynamic(rule);
75 }
76
Gunnar Mills1214b7e2020-06-04 10:11:30 -050077 template <uint64_t Tag>
78 auto& route(std::string&& rule)
Ed Tanous1abe55e2018-09-05 08:30:59 -070079 {
80 return router.newRuleTagged<Tag>(std::move(rule));
81 }
82
Ed Tanous81ce6092020-12-17 16:54:55 +000083 App& socket(int existingSocket)
Ed Tanous1abe55e2018-09-05 08:30:59 -070084 {
Ed Tanous81ce6092020-12-17 16:54:55 +000085 socketFd = existingSocket;
Ed Tanous1abe55e2018-09-05 08:30:59 -070086 return *this;
87 }
88
Ed Tanousb74e4402020-09-09 20:26:26 -070089 App& port(std::uint16_t port)
Ed Tanous1abe55e2018-09-05 08:30:59 -070090 {
91 portUint = port;
92 return *this;
93 }
94
Ed Tanousb74e4402020-09-09 20:26:26 -070095 App& bindaddr(std::string bindaddr)
Ed Tanous1abe55e2018-09-05 08:30:59 -070096 {
Ed Tanousb5a76932020-09-29 16:16:58 -070097 bindaddrStr = std::move(bindaddr);
Ed Tanous1abe55e2018-09-05 08:30:59 -070098 return *this;
99 }
100
101 void validate()
102 {
103 router.validate();
104 }
105
106 void run()
107 {
108 validate();
109#ifdef BMCWEB_ENABLE_SSL
Ed Tanous789a6a32018-11-29 15:17:22 -0800110 if (-1 == socketFd)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700111 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000112 sslServer = std::make_unique<ssl_server_t>(
113 this, bindaddrStr, portUint, sslContext, io);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700114 }
115 else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700116 {
Ed Tanous23a21a12020-07-25 04:45:05 +0000117 sslServer =
118 std::make_unique<ssl_server_t>(this, socketFd, sslContext, io);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700119 }
Ed Tanous789a6a32018-11-29 15:17:22 -0800120 sslServer->run();
121
122#else
123
124 if (-1 == socketFd)
125 {
Nan Zhoud9049df2022-08-02 18:38:18 +0000126 server = std::make_unique<server_t>(this, bindaddrStr, portUint,
127 nullptr, io);
Ed Tanous789a6a32018-11-29 15:17:22 -0800128 }
129 else
130 {
Nan Zhoud9049df2022-08-02 18:38:18 +0000131 server = std::make_unique<server_t>(this, socketFd, nullptr, io);
Ed Tanous789a6a32018-11-29 15:17:22 -0800132 }
Ed Tanous789a6a32018-11-29 15:17:22 -0800133 server->run();
134
135#endif
Ed Tanous1abe55e2018-09-05 08:30:59 -0700136 }
137
138 void stop()
139 {
140 io->stop();
141 }
142
143 void debugPrint()
144 {
145 BMCWEB_LOG_DEBUG << "Routing:";
146 router.debugPrint();
147 }
148
149 std::vector<const std::string*> getRoutes()
150 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800151 const std::string root;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700152 return router.getRoutes(root);
153 }
154 std::vector<const std::string*> getRoutes(const std::string& parent)
155 {
156 return router.getRoutes(parent);
157 }
Ed Tanousb4a7bfa2017-04-04 17:23:00 -0700158
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700159#ifdef BMCWEB_ENABLE_SSL
Ed Tanousb74e4402020-09-09 20:26:26 -0700160 App& ssl(std::shared_ptr<boost::asio::ssl::context>&& ctx)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700161 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700162 sslContext = std::move(ctx);
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600163 BMCWEB_LOG_INFO << "app::ssl context use_count="
164 << sslContext.use_count();
Ed Tanous1abe55e2018-09-05 08:30:59 -0700165 return *this;
166 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700167
Marri Devender Rao5968cae2019-01-21 10:27:12 -0600168 std::shared_ptr<ssl_context_t> sslContext = nullptr;
Ed Tanous7045c8d2017-04-03 10:04:37 -0700169
170#else
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500171 template <typename T>
Ed Tanousb74e4402020-09-09 20:26:26 -0700172 App& ssl(T&&)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700173 {
174 // We can't call .ssl() member function unless BMCWEB_ENABLE_SSL is
175 // defined.
176 static_assert(
177 // make static_assert dependent to T; always false
178 std::is_base_of<T, void>::value,
179 "Define BMCWEB_ENABLE_SSL to enable ssl support.");
180 return *this;
181 }
Ed Tanous7045c8d2017-04-03 10:04:37 -0700182#endif
183
Ed Tanous1abe55e2018-09-05 08:30:59 -0700184 private:
Ed Tanous23e64202020-09-15 19:21:30 -0700185 std::shared_ptr<boost::asio::io_context> io;
Ed Tanous789a6a32018-11-29 15:17:22 -0800186#ifdef BMCWEB_ENABLE_SSL
187 uint16_t portUint = 443;
188#else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700189 uint16_t portUint = 80;
Ed Tanous789a6a32018-11-29 15:17:22 -0800190#endif
Ed Tanousc7b9cb32021-02-11 13:28:35 -0800191 std::string bindaddrStr = "0.0.0.0";
Ed Tanous1abe55e2018-09-05 08:30:59 -0700192 int socketFd = -1;
193 Router router;
Ed Tanous7045c8d2017-04-03 10:04:37 -0700194
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700195#ifdef BMCWEB_ENABLE_SSL
Ed Tanous1abe55e2018-09-05 08:30:59 -0700196 std::unique_ptr<ssl_server_t> sslServer;
Ed Tanous789a6a32018-11-29 15:17:22 -0800197#else
Ed Tanous1abe55e2018-09-05 08:30:59 -0700198 std::unique_ptr<server_t> server;
Ed Tanous789a6a32018-11-29 15:17:22 -0800199#endif
Ed Tanous7045c8d2017-04-03 10:04:37 -0700200};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700201} // namespace crow
Ed Tanous52cc1122020-07-18 13:51:21 -0700202using App = crow::App;