Some license server improvements

This commit is contained in:
WolverinDEV
2020-02-06 13:49:39 +01:00
parent 14d9936d90
commit 3e39bcc38c
9 changed files with 322 additions and 250 deletions
+78 -24
View File
@@ -38,11 +38,10 @@ bool WebStatistics::start(std::string &error, uint16_t port, const std::shared_p
this->ssl = ssl;
{
this->socket.local_address = make_unique<sockaddr_in>();
memset(this->socket.local_address.get(), 0, sizeof(sockaddr_in));
this->socket.local_address->sin_family = AF_INET;
this->socket.local_address->sin_addr.s_addr = INADDR_ANY;
this->socket.local_address->sin_port = htons(port);
memset(&this->socket.address, 0, sizeof(sockaddr_in));
this->socket.address.sin_family = AF_INET;
this->socket.address.sin_addr.s_addr = INADDR_ANY;
this->socket.address.sin_port = htons(port);
}
this->socket.file_descriptor = ::socket(AF_INET, SOCK_STREAM, 0);
@@ -50,7 +49,7 @@ bool WebStatistics::start(std::string &error, uint16_t port, const std::shared_p
if(setsockopt(this->socket.file_descriptor, SOL_SOCKET, SO_REUSEADDR, &enabled, sizeof(enabled)) < 0) SFAIL("could not set reuse address");
if(setsockopt(this->socket.file_descriptor, IPPROTO_TCP, TCP_CORK, &disabled, sizeof(disabled)) < 0) SFAIL("could not set no push");
if(bind(this->socket.file_descriptor, (struct sockaddr *) this->socket.local_address.get(), sizeof(sockaddr_in)) < 0) SFAIL("Could not bind socket on " + string(inet_ntoa(this->socket.local_address->sin_addr)));
if(bind(this->socket.file_descriptor, (struct sockaddr *) &this->socket.address, sizeof(sockaddr_in)) < 0) SFAIL("Could not bind socket on " + string(inet_ntoa(this->socket.address.sin_addr)));
if(listen(this->socket.file_descriptor, 32) < 0) SFAIL("Could not listen on socket");
@@ -162,13 +161,11 @@ void WebStatistics::initialize_client(const std::shared_ptr<license::web::WebSta
auto lmethod = request.method;
transform(lmethod.begin(), lmethod.end(), lmethod.begin(), ::tolower);
if(lmethod == "get" && !request.parameters["type"].empty())
if(lmethod == "get" && request.parameters.count("type") && !request.parameters.at("type").empty())
this->handle_request(_client, request, response);
};
client->pipe_websocket->initialize();
//FIXME Setup ssl
}
{
@@ -369,6 +366,15 @@ std::shared_ptr<WebStatistics::Client> WebStatistics::find_client_by_fd(int file
return nullptr;
}
bool WebStatistics::send_message(const std::shared_ptr<Client> &client, const pipes::buffer_view &buffer) {
lock_guard<recursive_mutex> lock(client->execute_lock);
if(client->pipe_websocket) {
client->pipe_websocket->send({pipes::TEXT, buffer.own_buffer()});
return true;
}
return false;
}
#define HERR(message, ...) \
do {\
logError(LOG_LICENSE_WEB, "[{}] " message, client->client_prefix(), ##__VA_ARGS__); \
@@ -393,7 +399,7 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
_response = json_dump(response);
}
client->pipe_websocket->send({pipes::TEXT, _response});
this->send_message(client, _response);
return true;
}
@@ -426,9 +432,9 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
response["statistics"]["clients"] = to_string(stats->clients);
response["statistics"]["music"] = to_string(stats->bots);
client->pipe_websocket->send({pipes::TEXT, json_dump(response)});
this->send_message(client, json_dump(response));
return true;
} else if(message["request_type"].asString() == "history") {
} else if(message["request_type"].asString() == "history" ) {
auto type = message["history_type"].asInt();
if(type < 0 || type > stats::HistoryStatistics::LAST_HALF_YEAR)
__throw_range_error("invalid range!");
@@ -447,6 +453,7 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
this->update_flood(client, 80);
//TODO: Some kind of handle else this could crash the server on shutdown
std::thread([&, client, type, message]() {
auto history = this->statistics_manager->history((stats::HistoryStatistics::HistoryType) type);
@@ -462,18 +469,65 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
int index;
auto stats = history->statistics;
for(index = 0; index < stats->record_count; index++) {
response["history"]["data"][index]["instances"] = stats->history[index].instance_online;
response["history"]["data"][index]["servers"] = stats->history[index].servers_online;
response["history"]["data"][index]["clients"] = stats->history[index].clients_online;
response["history"]["data"][index]["music"] = stats->history[index].bots_online;
}
auto& history_data = response["history"]["data"];
for(index = 0; index < stats->record_count; index++) {
auto& indexed_data = history_data[index];
indexed_data["instances"] = stats->history[index].instance_online;
indexed_data["servers"] = stats->history[index].servers_online;
indexed_data["clients"] = stats->history[index].clients_online;
indexed_data["music"] = stats->history[index].bots_online;
}
lock_guard lock(client->execute_lock);
if(client->pipe_websocket)
client->pipe_websocket->send({pipes::TEXT, json_dump(response)});
this->send_message(client, json_dump(response));
}).detach();
return true;
} else if(message["request_type"].asString() == "history_custom") {
auto begin = std::chrono::milliseconds{message["history_begin"].asInt64()};
auto end = std::chrono::milliseconds{message["history_end"].asInt64()};
auto interval = std::chrono::milliseconds{message["history_interval"].asInt64()};
auto code = message["code"].asString();
auto token = message["token"].asString();
if(token != "blubalutsch") {
Json::Value response;
response["type"] = "error";
response["code"] = code;
response["message"] = "invalid token";
this->send_message(client, json_dump(response));
return true;
}
//TODO: Some kind of handle else this could crash the server on shutdown
std::thread([&, client, begin, end, interval, code]{
auto data = this->license_manager->list_statistics_user(
std::chrono::system_clock::time_point{} + begin,
std::chrono::system_clock::time_point{} + end,
interval
);
Json::Value response;
response["type"] = "response";
response["code"] = code;
response["history"]["timestamp"] = duration_cast<milliseconds>(system_clock::now().time_since_epoch()).count();
response["history"]["begin"] = duration_cast<milliseconds>(begin).count();
response["history"]["end"] = duration_cast<milliseconds>(end).count();
response["history"]["interval"] = duration_cast<milliseconds>(interval).count();
int index;
auto& history_data = response["history"]["data"];
for(index = 0; index < data->record_count; index++) {
auto& indexed_data = history_data[index];
indexed_data["instances"] = data->history[index].instance_online;
indexed_data["servers"] = data->history[index].servers_online;
indexed_data["clients"] = data->history[index].clients_online;
indexed_data["music"] = data->history[index].bots_online;
}
this->send_message(client, json_dump(response));
}).detach();
return true;
}
}
} catch (const std::exception& ex) {
@@ -482,8 +536,8 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
Json::Value response;
response["type"] = "error";
response["code"] = message["code"];
response["message"] = "could not assign action";
client->pipe_websocket->send({pipes::TEXT, json_dump(response)});
response["message"] = "could not execute action";
this->send_message(client, json_dump(response));
return false;
}
@@ -492,7 +546,7 @@ bool WebStatistics::handle_message(const std::shared_ptr<license::web::WebStatis
response["type"] = "error";
response["code"] = message["code"];
response["message"] = "could not assign action";
client->pipe_websocket->send({pipes::TEXT, json_dump(response)});
this->send_message(client, json_dump(response));
}
return true;
}