-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathHttpController.cpp
121 lines (107 loc) · 4.41 KB
/
HttpController.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//
// Created by l2pic on 15.04.2021.
//
#include "app.h"
#include <so_5/send_functions.hpp>
#include <absl/strings/str_split.h>
#include "SysSignal.h"
#include "ThreadName.h"
#include "http/server/HTTPResponseFactory.h"
#include "HttpController.h"
#define match(num, arg) path[num] == #arg
#define match_handle2(arg1, arg2) if (path[1] == #arg2) return so_5::send<hreq::arg1::arg2>(listeners, std::move(req), std::move(send))
#define match_handle3(arg1, arg2, arg3) if (path[2] == #arg3) return so_5::send<hreq::arg1::arg2::arg3>(listeners, std::move(req), std::move(send))
HttpController::HttpController(const context_t &ctx,
so_5::mbox_t listeners,
Config &config,
std::shared_ptr<Logger> logger)
: so_5::agent_t(ctx), config(config),
logger(std::move(logger)), listeners(std::move(listeners)) {
}
HttpController::~HttpController() = default;
void HttpController::so_define_agent() {
so_subscribe_self().event([this](mhood_t<HttpController::ShutdownCheck>) {
if (SysSignal::serviceTerminated()) {
so_deregister_agent_coop_normally();
}
});
so_subscribe(listeners).event([](mhood_t<hreq::resp> resp) {
resp->send(HTTPResponseFactory::CreateResponse(
resp->req, static_cast<http::status>(resp->status), std::move(resp->body)));
}, so_5::thread_safe);
}
void HttpController::so_evt_start() {
set_thread_name("http_controller");
HTTPServerConfig httpCfg;
httpCfg.host = config[HTTP_CONTROL]["host"].value_or("localhost");
httpCfg.port = config[HTTP_CONTROL]["port"].value_or(8080);
httpCfg.user = config[HTTP_CONTROL]["user"].value_or("admin");
httpCfg.pass = config[HTTP_CONTROL]["password"].value_or("admin");
httpCfg.threads = config[HTTP_CONTROL]["threads"].value_or(std::thread::hardware_concurrency());
httpCfg.secure = config[HTTP_CONTROL]["secure"].value_or(true);
if (httpCfg.secure) {
httpCfg.ssl.verify = config[HTTP_CONTROL]["verify"].value_or(false);
httpCfg.ssl.cert = config[HTTP_CONTROL]["cert_file"].value_or("cert.pem");
httpCfg.ssl.key = config[HTTP_CONTROL]["key_file"].value_or("key.pem");
httpCfg.ssl.dh = config[HTTP_CONTROL]["dh_file"].value_or("dh.pem");
}
try {
server = std::make_shared<HTTPServer>(std::move(httpCfg), this, this->logger);
if (!server->start()) {
throw;
}
} catch (...) {
so_deregister_agent_coop(so_5::dereg_reason::user_defined_reason);
}
shutdownCheckTimer = so_5::send_periodic<HttpController::ShutdownCheck>(so_direct_mbox(),
std::chrono::seconds(1),
std::chrono::seconds(1));
}
void HttpController::so_evt_finish() {
if (server)
server->stop();
}
void HttpController::handleRequest(http::request<http::string_body> &&req, HTTPServerSession::SendLambda &&send) {
std::vector<std::string_view> path = absl::StrSplit(sv(req.target()), '/', absl::SkipWhitespace());
if (path.size() < 2)
return send(HTTPResponseFactory::BadRequest(req, "Invalid path"));
if (match(0, stats)) {
match_handle2(stats, irc);
match_handle2(stats, account);
match_handle2(stats, channel);
match_handle2(stats, bot);
match_handle2(stats, storage);
match_handle2(stats, db);
match_handle2(stats, so5disp);
}
else
if (match(0, irc)) {
match_handle2(irc, reload);
match_handle2(irc, custom);
if (path.size() > 2) {
if (match(1, channel)) {
match_handle3(irc, channel, join);
match_handle3(irc, channel, leave);
match_handle3(irc, channel, message);
}
else if (match(1, account)) {
match_handle3(irc, account, reload);
match_handle3(irc, account, add);
match_handle3(irc, account, remove);
}
}
}
else
if (match(0, app)) {
match_handle2(app, shutdown);
match_handle2(app, version);
}
else
if (match(0, bot)) {
match_handle2(bot, add);
match_handle2(bot, remove);
match_handle2(bot, reload);
match_handle2(bot, reloadall);
}
send(HTTPResponseFactory::NotFound(req, req.target()));
}