From aee6c23082535009a60e3c2151f4551ed318e905 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Tue, 5 Dec 2023 17:48:10 +0400 Subject: [PATCH] Decoupled RequestContext from MHD_Connection This will simplify testing of Response utilities. --- src/server/internalServer.cpp | 18 +++++++++++++++++- src/server/request_context.cpp | 29 +++++++++++++++-------------- src/server/request_context.h | 15 ++++++++++----- test/response.cpp | 8 +++++--- 4 files changed, 47 insertions(+), 23 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 72b71b044..dcf6f170b 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -513,6 +513,19 @@ static MHD_Result staticHandlerCallback(void* cls, cont_cls); } +namespace +{ + +MHD_Result add_name_value_pair(void *nvp, enum MHD_ValueKind kind, + const char *key, const char *value) +{ + auto& nameValuePairs = *reinterpret_cast(nvp); + nameValuePairs.push_back({key, value}); + return MHD_YES; +} + +} // unnamed namespace + MHD_Result InternalServer::handlerCallback(struct MHD_Connection* connection, const char* fullUrl, const char* method, @@ -529,7 +542,10 @@ MHD_Result InternalServer::handlerCallback(struct MHD_Connection* connection, } const auto url = fullURL2LocalURL(fullUrl, m_rootPrefixOfDecodedURL); - RequestContext request(connection, m_root, url, method, version); + RequestContext::NameValuePairs headers, queryArgs; + MHD_get_connection_values(connection, MHD_HEADER_KIND, add_name_value_pair, &headers); + MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, add_name_value_pair, &queryArgs); + RequestContext request(m_root, url, method, version, headers, queryArgs); if (m_verbose.load() ) { request.print_debug_info(); diff --git a/src/server/request_context.cpp b/src/server/request_context.cpp index 2b5b6fd4c..d879240cd 100644 --- a/src/server/request_context.cpp +++ b/src/server/request_context.cpp @@ -51,11 +51,12 @@ RequestMethod str2RequestMethod(const std::string& method) { } // unnamed namespace -RequestContext::RequestContext(struct MHD_Connection* connection, - const std::string& _rootLocation, // URI-encoded +RequestContext::RequestContext(const std::string& _rootLocation, // URI-encoded const std::string& unrootedUrl, // URI-decoded const std::string& _method, - const std::string& version) : + const std::string& version, + const NameValuePairs& headers, + const NameValuePairs& queryArgs) : rootLocation(_rootLocation), url(unrootedUrl), method(str2RequestMethod(_method)), @@ -64,8 +65,13 @@ RequestContext::RequestContext(struct MHD_Connection* connection, acceptEncodingGzip(false), byteRange_() { - MHD_get_connection_values(connection, MHD_HEADER_KIND, &RequestContext::fill_header, this); - MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &RequestContext::fill_argument, this); + for ( const auto& kv : headers ) { + add_header(kv.first, kv.second); + } + + for ( const auto& kv : queryArgs ) { + add_argument(kv.first, kv.second); + } try { acceptEncodingGzip = @@ -82,18 +88,14 @@ RequestContext::RequestContext(struct MHD_Connection* connection, RequestContext::~RequestContext() {} -MHD_Result RequestContext::fill_header(void *__this, enum MHD_ValueKind kind, - const char *key, const char *value) +void RequestContext::add_header(const char *key, const char *value) { - RequestContext *_this = static_cast(__this); - _this->headers[lcAll(key)] = value; - return MHD_YES; + this->headers[lcAll(key)] = value; } -MHD_Result RequestContext::fill_argument(void *__this, enum MHD_ValueKind kind, - const char *key, const char* value) +void RequestContext::add_argument(const char *key, const char* value) { - RequestContext *_this = static_cast(__this); + RequestContext *_this = this; _this->arguments[key].push_back(value == nullptr ? "" : value); if ( ! _this->queryString.empty() ) { _this->queryString += "&"; @@ -103,7 +105,6 @@ MHD_Result RequestContext::fill_argument(void *__this, enum MHD_ValueKind kind, _this->queryString += "="; _this->queryString += urlEncode(value); } - return MHD_YES; } void RequestContext::print_debug_info() const { diff --git a/src/server/request_context.h b/src/server/request_context.h index 0393dce77..d4fe53dd5 100644 --- a/src/server/request_context.h +++ b/src/server/request_context.h @@ -55,12 +55,17 @@ class IndexError: public std::runtime_error {}; class RequestContext { + public: // types + typedef std::vector> NameValuePairs; + public: // functions - RequestContext(struct MHD_Connection* connection, - const std::string& rootLocation, // URI-encoded + RequestContext(const std::string& rootLocation, // URI-encoded const std::string& unrootedUrl, // URI-decoded const std::string& method, - const std::string& version); + const std::string& version, + const NameValuePairs& headers, + const NameValuePairs& queryArgs); + ~RequestContext(); void print_debug_info() const; @@ -151,8 +156,8 @@ class RequestContext { private: // functions UserLanguage determine_user_language() const; - static MHD_Result fill_header(void *, enum MHD_ValueKind, const char*, const char*); - static MHD_Result fill_argument(void *, enum MHD_ValueKind, const char*, const char*); + void add_header(const char* name, const char* value); + void add_argument(const char* name, const char* value); }; template<> std::string RequestContext::get_argument(const std::string& name) const; diff --git a/test/response.cpp b/test/response.cpp index 5d5efe649..c65691b8d 100644 --- a/test/response.cpp +++ b/test/response.cpp @@ -8,9 +8,11 @@ namespace using namespace kiwix; -RequestContext makeHttpGetRequest(const std::string& url) +RequestContext makeHttpGetRequest(const std::string& url, + const RequestContext::NameValuePairs& headers, + const RequestContext::NameValuePairs& queryArgs) { - return RequestContext(nullptr, "", url, "GET", "1.1"); + return RequestContext("", url, "GET", "1.1", headers, queryArgs); } std::string getResponseContent(const ContentResponseBlueprint& crb) @@ -23,7 +25,7 @@ std::string getResponseContent(const ContentResponseBlueprint& crb) TEST(HTTPErrorResponse, shouldBeInEnglishByDefault) { - const RequestContext req = makeHttpGetRequest("/asdf"); + const RequestContext req = makeHttpGetRequest("/asdf", {}, {}); HTTPErrorResponse errResp(req, MHD_HTTP_NOT_FOUND, "404-page-title", "404-page-heading",