From 8d151582ce879d272d16d6bb65349d0be5837309 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sat, 18 Mar 2023 10:54:43 -0400 Subject: [PATCH] correct file formatting; fix issue where RequestDispatcher was not properly handling requests; --- network/rest/RequestDispatcher.h | 39 +++++-- network/rest/http/Connection.h | 9 +- network/rest/http/ConnectionManager.h | 9 +- network/rest/http/HTTPHeader.h | 9 +- network/rest/http/HTTPReply.cpp | 136 ++++++++++++++++++------- network/rest/http/HTTPReply.h | 9 +- network/rest/http/HTTPRequest.h | 9 +- network/rest/http/HTTPRequestHandler.h | 9 +- network/rest/http/HTTPRequestLexer.h | 9 +- network/rest/http/HTTPServer.h | 9 +- 10 files changed, 176 insertions(+), 71 deletions(-) diff --git a/network/rest/RequestDispatcher.h b/network/rest/RequestDispatcher.h index e78b11c2..449bd97f 100644 --- a/network/rest/RequestDispatcher.h +++ b/network/rest/RequestDispatcher.h @@ -29,6 +29,7 @@ #include "Defines.h" #include "network/rest/http/HTTPRequest.h" #include "network/rest/http/HTTPReply.h" +#include "Log.h" #include #include @@ -36,8 +37,10 @@ #include #include -namespace network { - namespace rest { +namespace network +{ + namespace rest + { // --------------------------------------------------------------------------- // Structure Declaration // @@ -119,16 +122,25 @@ namespace network { typedef RequestMatcher MatcherType; public: /// Initializes a new instance of the RequestDispatcher class. - RequestDispatcher() : m_basePath() { /* stub */ } + RequestDispatcher() : m_basePath(), m_debug(false) { /* stub */ } /// Initializes a new instance of the RequestDispatcher class. - RequestDispatcher(const std::string& basePath) : m_basePath(basePath) { /* stub */ } + RequestDispatcher(bool debug) : m_basePath(), m_debug(debug) { /* stub */ } + /// Initializes a new instance of the RequestDispatcher class. + RequestDispatcher(const std::string& basePath, bool debug) : m_basePath(basePath), m_debug(debug) { /* stub */ } /// MatcherType& match(const std::string& expression) { MatcherTypePtr& p = m_matchers[expression]; if (!p) { + if (m_debug) { + ::LogDebug(LOG_RCON, "creating REST RequestDispatcher, expression = %s", expression.c_str()); + } p = std::make_shared(expression); + } else { + if (m_debug) { + ::LogDebug(LOG_RCON, "fetching REST RequestDispatcher, expression = %s", expression.c_str()); + } } return *p; @@ -141,19 +153,28 @@ namespace network { std::smatch what; if (!matcher.second->regex()) { if (request.uri.find(matcher.first) != std::string::npos) { + if (m_debug) { + ::LogDebug(LOG_RCON, "non-regex endpoint, uri = %s, expression = %s", request.uri.c_str(), matcher.first.c_str()); + } + //what = matcher.first; matcher.second->handleRequest(request, reply, what); - } else { - reply = http::HTTPReply::stockReply(http::HTTPReply::BAD_REQUEST); + return; } } else { if (std::regex_match(request.uri, what, std::regex(matcher.first))) { + if (m_debug) { + ::LogDebug(LOG_RCON, "regex endpoint, uri = %s, expression = %s", request.uri.c_str(), matcher.first.c_str()); + } + matcher.second->handleRequest(request, reply, what); - } else { - reply = http::HTTPReply::stockReply(http::HTTPReply::BAD_REQUEST); + return; } } } + + ::LogError(LOG_RCON, "unknown endpoint, uri = %s", request.uri.c_str()); + reply = http::HTTPReply::stockReply(http::HTTPReply::BAD_REQUEST, "application/json"); } private: @@ -161,6 +182,8 @@ namespace network { std::string m_basePath; std::map m_matchers; + + bool m_debug; }; typedef RequestDispatcher DefaultRequestDispatcher; diff --git a/network/rest/http/Connection.h b/network/rest/http/Connection.h index 1757f37f..035f5093 100644 --- a/network/rest/http/Connection.h +++ b/network/rest/http/Connection.h @@ -48,9 +48,12 @@ #include #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Class Prototypes diff --git a/network/rest/http/ConnectionManager.h b/network/rest/http/ConnectionManager.h index 6d8f855e..f3d1a3f9 100644 --- a/network/rest/http/ConnectionManager.h +++ b/network/rest/http/ConnectionManager.h @@ -42,9 +42,12 @@ #include #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Class Declaration diff --git a/network/rest/http/HTTPHeader.h b/network/rest/http/HTTPHeader.h index 506e518b..02997624 100644 --- a/network/rest/http/HTTPHeader.h +++ b/network/rest/http/HTTPHeader.h @@ -41,9 +41,12 @@ #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Structure Declaration diff --git a/network/rest/http/HTTPReply.cpp b/network/rest/http/HTTPReply.cpp index b2d76c2d..cd1acb5a 100644 --- a/network/rest/http/HTTPReply.cpp +++ b/network/rest/http/HTTPReply.cpp @@ -108,120 +108,178 @@ namespace misc_strings { namespace stock_replies { const char ok[] = ""; + const char json_ok[] = "{status:200,message:\"ok\"}"; const char created[] = "" "Created" "

201 Created

" ""; + const char json_created[] = "{status:201,message:\"created\"}"; const char accepted[] = "" "Accepted" "

202 Accepted

" ""; + const char json_accepted[] = "{status:202,message:\"accepted\"}"; const char no_content[] = "" "No Content" "

204 Content

" ""; + const char json_no_content[] = "{status:204,message:\"no content\"}"; const char multiple_choices[] = "" "Multiple Choices" "

300 Multiple Choices

" ""; + const char json_multiple_choices[] = "{status:300,message:\"multiple choices\"}"; const char moved_permanently[] = "" "Moved Permanently" "

301 Moved Permanently

" ""; + const char json_moved_permanently[] = "{status:301,message:\"moved permanently\"}"; const char moved_temporarily[] = "" "Moved Temporarily" "

302 Moved Temporarily

" ""; + const char json_moved_temporarily[] = "{status:302,message:\"moved temporarily\"}"; const char not_modified[] = "" "Not Modified" "

304 Not Modified

" ""; + const char json_not_modified[] = "{status:304,message:\"not modified\"}"; const char bad_request[] = "" "Bad Request" "

400 Bad Request

" ""; + const char json_bad_request[] = "{status:400,message:\"bad request\"}"; const char unauthorized[] = "" "Unauthorized" "

401 Unauthorized

" ""; + const char json_unauthorized[] = "{status:401,message:\"unauthorized\"}"; const char forbidden[] = "" "Forbidden" "

403 Forbidden

" ""; + const char json_forbidden[] = "{status:403,message:\"forbidden\"}"; const char not_found[] = "" "Not Found" "

404 Not Found

" ""; + const char json_not_found[] = "{status:404,message:\"not found\"}"; const char internal_server_error[] = "" "Internal Server Error" "

500 Internal Server Error

" ""; + const char json_internal_server_error[] = "{status:500,message:\"internal server error\"}"; const char not_implemented[] = "" "Not Implemented" "

501 Not Implemented

" ""; + const char json_not_implemented[] = "{status:501,message:\"not implemented\"}"; const char bad_gateway[] = "" "Bad Gateway" "

502 Bad Gateway

" ""; + const char json_bad_gateway[] = "{status:502,message:\"bad gateway\"}"; const char service_unavailable[] = "" "Service Unavailable" "

503 Service Unavailable

" ""; + const char json_service_unavailable[] = "{status:503,message:\"service unavailable\"}"; - std::string to_string(HTTPReply::StatusType status) + std::string to_string(HTTPReply::StatusType status, std::string contentType) { - switch (status) - { - case HTTPReply::OK: - return ok; - case HTTPReply::CREATED: - return created; - case HTTPReply::ACCEPTED: - return accepted; - case HTTPReply::NO_CONTENT: - return no_content; - case HTTPReply::MULTIPLE_CHOICES: - return multiple_choices; - case HTTPReply::MOVED_PERMANENTLY: - return moved_permanently; - case HTTPReply::MOVED_TEMPORARILY: - return moved_temporarily; - case HTTPReply::NOT_MODIFIED: - return not_modified; - case HTTPReply::BAD_REQUEST: - return bad_request; - case HTTPReply::UNAUTHORIZED: - return unauthorized; - case HTTPReply::FORBIDDEN: - return forbidden; - case HTTPReply::NOT_FOUND: - return not_found; - case HTTPReply::INTERNAL_SERVER_ERROR: - return internal_server_error; - case HTTPReply::NOT_IMPLEMENTED: - return not_implemented; - case HTTPReply::BAD_GATEWAY: - return bad_gateway; - case HTTPReply::SERVICE_UNAVAILABLE: - return service_unavailable; - default: - return internal_server_error; + std::transform(contentType.begin(), contentType.end(), contentType.begin(), ::tolower); + if (contentType == "application/json") { + switch (status) + { + case HTTPReply::OK: + return json_ok; + case HTTPReply::CREATED: + return json_created; + case HTTPReply::ACCEPTED: + return json_accepted; + case HTTPReply::NO_CONTENT: + return json_no_content; + case HTTPReply::MULTIPLE_CHOICES: + return json_multiple_choices; + case HTTPReply::MOVED_PERMANENTLY: + return json_moved_permanently; + case HTTPReply::MOVED_TEMPORARILY: + return json_moved_temporarily; + case HTTPReply::NOT_MODIFIED: + return json_not_modified; + case HTTPReply::BAD_REQUEST: + return json_bad_request; + case HTTPReply::UNAUTHORIZED: + return json_unauthorized; + case HTTPReply::FORBIDDEN: + return json_forbidden; + case HTTPReply::NOT_FOUND: + return json_not_found; + case HTTPReply::INTERNAL_SERVER_ERROR: + return json_internal_server_error; + case HTTPReply::NOT_IMPLEMENTED: + return json_not_implemented; + case HTTPReply::BAD_GATEWAY: + return json_bad_gateway; + case HTTPReply::SERVICE_UNAVAILABLE: + return json_service_unavailable; + default: + return json_internal_server_error; + } + } + else { + switch (status) + { + case HTTPReply::OK: + return ok; + case HTTPReply::CREATED: + return created; + case HTTPReply::ACCEPTED: + return accepted; + case HTTPReply::NO_CONTENT: + return no_content; + case HTTPReply::MULTIPLE_CHOICES: + return multiple_choices; + case HTTPReply::MOVED_PERMANENTLY: + return moved_permanently; + case HTTPReply::MOVED_TEMPORARILY: + return moved_temporarily; + case HTTPReply::NOT_MODIFIED: + return not_modified; + case HTTPReply::BAD_REQUEST: + return bad_request; + case HTTPReply::UNAUTHORIZED: + return unauthorized; + case HTTPReply::FORBIDDEN: + return forbidden; + case HTTPReply::NOT_FOUND: + return not_found; + case HTTPReply::INTERNAL_SERVER_ERROR: + return internal_server_error; + case HTTPReply::NOT_IMPLEMENTED: + return not_implemented; + case HTTPReply::BAD_GATEWAY: + return bad_gateway; + case HTTPReply::SERVICE_UNAVAILABLE: + return service_unavailable; + default: + return internal_server_error; + } } } } // namespace stock_replies @@ -262,7 +320,7 @@ void HTTPReply::reply(json::object obj, HTTPReply::StatusType s) { json::value v = json::value(obj); std::string json = v.serialize(); - reply(json, s, "text/json"); + reply(json, s, "application/json"); } /// @@ -293,7 +351,7 @@ HTTPReply HTTPReply::stockReply(HTTPReply::StatusType status, const std::string rep.status = status; if (status != HTTPReply::NO_CONTENT) { - rep.content = stock_replies::to_string(status); + rep.content = stock_replies::to_string(status, contentType); rep.ensureDefaultHeaders(contentType); } diff --git a/network/rest/http/HTTPReply.h b/network/rest/http/HTTPReply.h index 6b9ce8e8..66a53420 100644 --- a/network/rest/http/HTTPReply.h +++ b/network/rest/http/HTTPReply.h @@ -46,9 +46,12 @@ #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Structure Declaration diff --git a/network/rest/http/HTTPRequest.h b/network/rest/http/HTTPRequest.h index e3ec8c38..3b9c10c4 100644 --- a/network/rest/http/HTTPRequest.h +++ b/network/rest/http/HTTPRequest.h @@ -43,9 +43,12 @@ #include #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Structure Declaration diff --git a/network/rest/http/HTTPRequestHandler.h b/network/rest/http/HTTPRequestHandler.h index b6522f47..6cc7a35e 100644 --- a/network/rest/http/HTTPRequestHandler.h +++ b/network/rest/http/HTTPRequestHandler.h @@ -41,9 +41,12 @@ #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Class Prototypes diff --git a/network/rest/http/HTTPRequestLexer.h b/network/rest/http/HTTPRequestLexer.h index 1ae7f882..105165bc 100644 --- a/network/rest/http/HTTPRequestLexer.h +++ b/network/rest/http/HTTPRequestLexer.h @@ -39,9 +39,12 @@ #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Class Prototypes diff --git a/network/rest/http/HTTPServer.h b/network/rest/http/HTTPServer.h index d222913d..be78362c 100644 --- a/network/rest/http/HTTPServer.h +++ b/network/rest/http/HTTPServer.h @@ -52,9 +52,12 @@ #include #include -namespace network { - namespace rest { - namespace http { +namespace network +{ + namespace rest + { + namespace http + { // --------------------------------------------------------------------------- // Class Declaration