diff --git a/task_5/main.cpp b/task_5/main.cpp index 6862c1c..4bb2c50 100644 --- a/task_5/main.cpp +++ b/task_5/main.cpp @@ -3,6 +3,48 @@ #include +#include +#include + + +struct request_info { + std::string method, path, params; +}; + +std::string 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 ""; +} + +struct request_info parse_request(const std::string& request) { + std::regex request_line_regex( + "(GET|POST|PUT|DELETE) .* HTTP/", + std::regex_constants::ECMAScript | std::regex_constants::icase + ); + std::string request_line = get_string_from_regex(request, request_line_regex); + + std::regex method_regex("^[A-Z]+"); + std::regex path_regex("/[^? ]*"); + std::regex params_regex(R"(\?[^ ]*)"); + + struct request_info this_request; + + 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); + + return this_request; +} + int main() { @@ -11,6 +53,5 @@ int main() { closesocket(listenSocket); WSACleanup(); - return 0; } \ No newline at end of file diff --git a/task_5/routes.cpp b/task_5/routes.cpp index 528ac28..d640064 100644 --- a/task_5/routes.cpp +++ b/task_5/routes.cpp @@ -1,29 +1,109 @@ #include "routes.h" +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 ""; +} + +struct request_info RouteHandler::parse_request(const std::string& request) { + struct request_info this_request; + + std::regex request_line_regex("(GET|POST|PUT|DELETE) .* HTTP/"); + std::regex method_regex("^[A-Z]+"); + std::regex path_regex("/[^? ]*"); + std::regex params_regex(R"(\?[^ ]*)"); + + + 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); + + return this_request; +} + + + std::string RouteHandler::get_response_by_request(const std::string& request) { - - - - - if (request.find("GET /current") != std::string::npos) { - return get_current_temperature(); + 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); + } } - + return format_http_response("404 NOT FOUND", "404 Not Found"); } -std::string RouteHandler::get_current_temperature() { +std::string RouteHandler::get_current_temperature(struct request_info this_request) { std::string temperature_info = ( "{\"temperature\": \"22°C\", \"weather\": \"good\"}" ); return format_http_response("200 OK", temperature_info); } +std::string RouteHandler::get_temperature_by_period(struct request_info this_request) { + std::map 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 = "{"; + + for (auto item : params_data) { + response_json += ("\"" + item.first + "\": \"" + item.second + "\","); + + } + + response_json.pop_back(); + response_json += "}"; + return format_http_response("200 OK", response_json); +} std::string RouteHandler::format_http_response(std::string status, std::string text) { diff --git a/task_5/routes.h b/task_5/routes.h index 566c27a..029ec63 100644 --- a/task_5/routes.h +++ b/task_5/routes.h @@ -1,12 +1,22 @@ #include +#include +#include +#include + +struct request_info { + std::string method, path, params; +}; class RouteHandler { public: static std::string get_response_by_request(const std::string& request); protected: + static std::string get_string_from_regex(std::string text, std::regex pattern); + static struct request_info parse_request(const std::string& request); static std::string format_http_response(std::string status, std::string text); private: - static std::string get_current_temperature(); + static std::string get_current_temperature(struct request_info this_request); + static std::string get_temperature_by_period(struct request_info this_request); }; \ No newline at end of file