hello-world-cpp/task_5/routes.cpp

119 lines
3.3 KiB
C++
Raw Normal View History

2025-01-13 04:58:58 +10:00
#include "routes.h"
2025-01-14 04:53:43 +10:00
std::string RouteHandler::get_string_from_regex(std::string text, std::regex pattern) {
auto parts_begin = std::sregex_iterator(
text.begin(),
text.end(),
pattern
);
auto parts_end = std::sregex_iterator();
if (std::distance(parts_begin, parts_end)) {
std::smatch part_match = *parts_begin;
return part_match.str();
}
return "";
}
2025-01-13 04:58:58 +10:00
2025-01-14 04:53:43 +10:00
struct request_info RouteHandler::parse_request(const std::string& request) {
struct request_info this_request;
2025-01-13 23:44:26 +00:00
std::regex request_line_regex(
"(GET|POST|PUT|DELETE|HEAD|TRACE|OPTIONS|CONNECT) .* HTTP/"
);
2025-01-14 04:53:43 +10:00
std::regex method_regex("^[A-Z]+");
std::regex path_regex("/[^? ]*");
std::regex params_regex(R"(\?[^ ]*)");
2025-01-13 04:58:58 +10:00
2025-01-14 04:53:43 +10:00
std::string request_line = get_string_from_regex(request, request_line_regex);
this_request.method = get_string_from_regex(request_line, method_regex);
this_request.path = get_string_from_regex(request_line, path_regex);
this_request.params = get_string_from_regex(request_line, params_regex);
2025-01-13 04:58:58 +10:00
2025-01-14 04:53:43 +10:00
return this_request;
}
std::string RouteHandler::get_response_by_request(const std::string& request) {
struct request_info this_request = parse_request(request);
if (this_request.method == "GET") {
if (this_request.path == "/current") {
return get_current_temperature(this_request);
}
if (this_request.path == "/get") {
return get_temperature_by_period(this_request);
}
2025-01-13 04:58:58 +10:00
}
2025-01-14 04:53:43 +10:00
2025-01-13 04:58:58 +10:00
return format_http_response("404 NOT FOUND", "404 Not Found");
}
2025-01-14 04:53:43 +10:00
std::string RouteHandler::get_current_temperature(struct request_info this_request) {
2025-01-13 04:58:58 +10:00
std::string temperature_info = (
"{\"temperature\": \"22°C\", \"weather\": \"good\"}"
);
return format_http_response("200 OK", temperature_info);
}
2025-01-14 04:53:43 +10:00
std::string RouteHandler::get_temperature_by_period(struct request_info this_request) {
std::map<std::string, std::string> params_data;
std::string temp = "", temp_key = "", temp_value = "";
bool key_is_ready = 0;
for (char sym : this_request.params) {
if (sym == '?') {
continue;
}
if (sym == '&') {
if (temp_value.length()) {
params_data[temp_key] = temp_value;
}
temp = "";
temp_key = "";
temp_value = "";
key_is_ready = 0;
continue;
}
if (sym == '=') {
key_is_ready = 1;
continue;
}
if (!key_is_ready) {
temp_key += sym;
}
else {
temp_value += sym;
}
}
if (temp_value.length()) {
params_data[temp_key] = temp_value;
}
std::string response_json = "{";
2025-01-13 04:58:58 +10:00
2025-01-14 04:53:43 +10:00
for (auto item : params_data) {
response_json += ("\"" + item.first + "\": \"" + item.second + "\",");
2025-01-13 04:58:58 +10:00
2025-01-14 04:53:43 +10:00
}
response_json.pop_back();
response_json += "}";
return format_http_response("200 OK", response_json);
}
2025-01-13 04:58:58 +10:00
std::string RouteHandler::format_http_response(std::string status, std::string text) {
return (
"HTTP/1.1 " + status + "\r\n"
"Content-Type: application/json\r\n"
"Content-Length: " + std::to_string(text.length()) + "\r\n"
"\r\n"
+ text
);
}