/
wwivd_http.cpp
127 lines (108 loc) · 4.2 KB
/
wwivd_http.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
122
123
124
125
126
127
/**************************************************************************/
/* */
/* WWIV BBS Software */
/* Copyright (C)2017-2022, WWIV Software Services */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, */
/* software distributed under the License is distributed on an */
/* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, */
/* either express or implied. See the License for the specific */
/* language governing permissions and limitations under the License. */
/**************************************************************************/
#include <string>
#include <vector>
#include <cereal/archives/json.hpp>
#include <cereal/cereal.hpp>
#include <cereal/types/memory.hpp>
// ReSharper disable once CppUnusedIncludeDirective
#include <cereal/types/string.hpp>
// ReSharper disable once CppUnusedIncludeDirective
#include <cereal/types/vector.hpp>
#include "core/http_server.h"
#include "core/jsonfile.h"
#include "core/log.h"
#include "core/net.h"
#include "core/os.h"
#include "core/socket_connection.h"
#include "core/stl.h"
#include "core/strings.h"
#include "sdk/config.h"
#include "wwivd/connection_data.h"
#include "wwivd/node_manager.h"
#include <string>
namespace wwiv::wwivd {
using namespace wwiv::core;
using namespace wwiv::sdk;
using namespace wwiv::stl;
using namespace wwiv::strings;
using namespace wwiv::os;
struct status_reponse_t {
int num_instances;
int used_instances;
std::vector<std::string> lines;
template <class Archive> void serialize(Archive& ar) {
ar(cereal::make_nvp("num_instances", num_instances),
cereal::make_nvp("used_instances", used_instances), cereal::make_nvp("lines", lines));
}
};
std::string ToJson(status_reponse_t r) {
std::ostringstream ss;
try {
cereal::JSONOutputArchive save(ss);
save(cereal::make_nvp("status", r));
}
catch (const cereal::RapidJSONException& e) {
LOG(ERROR) << e.what();
}
return ss.str();
}
class StatusHandler : public HttpHandler {
public:
StatusHandler(std::map<const std::string, std::shared_ptr<NodeManager>>* nodes) : nodes_(nodes) {}
HttpResponse Handle(HttpMethod, const std::string&, std::vector<std::string> headers) override {
// We only handle status
HttpResponse response(200);
response.headers.emplace("Content-Type: ", "text/json");
status_reponse_t r{};
for (const auto& n : *nodes_) {
const auto v = n.second->status_lines();
r.num_instances += n.second->total_nodes();
r.used_instances += n.second->nodes_used();
for (const auto& l : v) {
r.lines.push_back(l);
}
}
response.text = ToJson(r);
return response;
}
private:
std::map<const std::string, std::shared_ptr<NodeManager>>* nodes_;
};
void HandleHttpConnection(ConnectionData data, accepted_socket_t r) {
const auto sock = r.client_socket;
const auto& b = data.c->blocking;
try {
std::string remote_peer;
if (GetRemotePeerAddress(sock, remote_peer)) {
const auto cc = get_dns_cc(remote_peer, b.dns_cc_server);
LOG(INFO) << "Accepted HTTP connection on port: " << r.port << "; from: " << remote_peer
<< "; country code: " << cc;
}
// HTTP Request
HttpServer h(std::make_unique<SocketConnection>(r.client_socket));
StatusHandler status(data.nodes);
h.add(HttpMethod::GET, "/status", &status);
h.Run();
}
catch (const std::exception& e) {
LOG(ERROR) << "HandleHttpConnection: Handled Uncaught Exception: " << e.what();
}
VLOG(1) << "Exiting HandleHttpConnection (exception)";
}
}