diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0004-Remove-QueryString.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0004-Remove-QueryString.patch | 621 |
1 files changed, 0 insertions, 621 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0004-Remove-QueryString.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0004-Remove-QueryString.patch deleted file mode 100644 index 238fb83c7..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb/0004-Remove-QueryString.patch +++ /dev/null @@ -1,621 +0,0 @@ -From f8749b5898403ee04a623a5bc534bd939865e221 Mon Sep 17 00:00:00 2001 -From: James Feist <james.feist@linux.intel.com> -Date: Wed, 22 Jul 2020 09:08:38 -0700 -Subject: [PATCH 1/1] Remove QueryString - -QueryString is an error-prone library that was -leftover from crow. Replace it with boost::url, -a header only library based and written by the -one of the authors of boost beast. - -Tested: Verified logging paging still worked -as expected - -Change-Id: I47c225089aa7d0f7d2299142f91806294f879381 -Signed-off-by: James Feist <james.feist@linux.intel.com> ---- - CMakeLists.txt | 2 + - CMakeLists.txt.in | 10 + - http/http_connection.h | 21 +- - http/http_request.h | 5 +- - http/query_string.h | 421 ----------------------------- - redfish-core/lib/event_service.hpp | 7 +- - redfish-core/lib/log_services.hpp | 20 +- - 7 files changed, 45 insertions(+), 441 deletions(-) - delete mode 100644 http/query_string.h - -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 2886438..50483ad 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -280,6 +280,8 @@ add_definitions (-DBOOST_ALL_NO_LIB) - add_definitions (-DBOOST_NO_RTTI) - add_definitions (-DBOOST_NO_TYPEID) - add_definitions (-DBOOST_COROUTINES_NO_DEPRECATION_WARNING) -+add_definitions (-DBOOST_URL_STANDALONE) -+add_definitions (-DBOOST_URL_HEADER_ONLY) - - # sdbusplus - if (NOT ${YOCTO_DEPENDENCIES}) -diff --git a/CMakeLists.txt.in b/CMakeLists.txt.in -index d14910f..5cd73f6 100644 ---- a/CMakeLists.txt.in -+++ b/CMakeLists.txt.in -@@ -53,3 +53,13 @@ externalproject_add ( - cp -r "${CMAKE_BINARY_DIR}/nlohmann-json-src/include/nlohmann" - "${CMAKE_BINARY_DIR}/prefix/include" - ) -+ -+externalproject_add ( -+ Boost-URL GIT_REPOSITORY "https://github.com/CPPAlliance/url.git" GIT_TAG -+ a56ae0df6d3078319755fbaa67822b4fa7fd352b SOURCE_DIR -+ "${CMAKE_BINARY_DIR}/boost-url-src" BINARY_DIR -+ "${CMAKE_BINARY_DIR}/boost-url-build" CONFIGURE_COMMAND "" BUILD_COMMAND -+ "" INSTALL_COMMAND mkdir -p "${CMAKE_BINARY_DIR}/prefix/include" && -+ cp -r "${CMAKE_BINARY_DIR}/boost-url-src/include/boost" -+ "${CMAKE_BINARY_DIR}/prefix/include" -+) -diff --git a/http/http_connection.h b/http/http_connection.h -index 35bf99c..8dba3d6 100644 ---- a/http/http_connection.h -+++ b/http/http_connection.h -@@ -728,13 +728,9 @@ class Connection : - return; - } - -- // Compute the url parameters for the request -- req->url = req->target(); -- std::size_t index = req->url.find("?"); -- if (index != std::string_view::npos) -- { -- req->url = req->url.substr(0, index); -- } -+ req->urlView = boost::urls::url_view(req->target()); -+ req->url = req->urlView.encoded_path(); -+ - crow::authorization::authenticate(*req, res, session); - - bool loggedIn = req && req->session; -@@ -743,7 +739,16 @@ class Connection : - startDeadline(loggedInAttempts); - BMCWEB_LOG_DEBUG << "Starting slow deadline"; - -- req->urlParams = QueryString(std::string(req->target())); -+ req->urlParams = req->urlView.params(); -+ -+#ifdef BMCWEB_ENABLE_DEBUG -+ std::string paramList = ""; -+ for (const auto param : req->urlParams) -+ { -+ paramList += param->key() + " " + param->value() + " "; -+ } -+ BMCWEB_LOG_DEBUG << "QueryParams: " << paramList; -+#endif - } - else - { -diff --git a/http/http_request.h b/http/http_request.h -index 0691465..95f88c7 100644 ---- a/http/http_request.h -+++ b/http/http_request.h -@@ -1,7 +1,6 @@ - #pragma once - - #include "common.h" --#include "query_string.h" - - #include "sessions.hpp" - -@@ -9,6 +8,7 @@ - #include <boost/beast/http.hpp> - #include <boost/beast/ssl/ssl_stream.hpp> - #include <boost/beast/websocket.hpp> -+#include <boost/url/url_view.hpp> - - namespace crow - { -@@ -24,7 +24,8 @@ struct Request - boost::beast::http::request<boost::beast::http::string_body>& req; - boost::beast::http::fields& fields; - std::string_view url{}; -- QueryString urlParams{}; -+ boost::urls::url_view urlView{}; -+ boost::urls::url_view::params_type urlParams{}; - bool isSecure{false}; - - const std::string& body; -diff --git a/http/query_string.h b/http/query_string.h -deleted file mode 100644 -index e980280..0000000 ---- a/http/query_string.h -+++ /dev/null -@@ -1,421 +0,0 @@ --#pragma once -- --#include <cstdio> --#include <cstring> --#include <iostream> --#include <string> --#include <vector> -- --namespace crow --{ --// ---------------------------------------------------------------------------- --// qs_parse (modified) --// https://github.com/bartgrantham/qs_parse --// ---------------------------------------------------------------------------- --/* Similar to strncmp, but handles URL-encoding for either string */ --int qsStrncmp(const char* s, const char* qs, size_t n); -- --/* Finds the beginning of each key/value pair and stores a pointer in qs_kv. -- * Also decodes the value portion of the k/v pair *in-place*. In a future -- * enhancement it will also have a compile-time option of sorting qs_kv -- * alphabetically by key. */ --size_t qsParse(char* qs, char* qs_kv[], size_t qs_kv_size); -- --/* Used by qs_parse to decode the value portion of a k/v pair */ --int qsDecode(char* qs); -- --/* Looks up the value according to the key on a pre-processed query string -- * A future enhancement will be a compile-time option to look up the key -- * in a pre-sorted qs_kv array via a binary search. */ --// char * qs_k2v(const char * key, char * qs_kv[], int qs_kv_size); --char* qsK2v(const char* key, char* const* qs_kv, int qs_kv_size, int nth); -- --/* Non-destructive lookup of value, based on key. User provides the -- * destinaton string and length. */ --char* qsScanvalue(const char* key, const char* qs, char* val, size_t val_len); -- --// TODO: implement sorting of the qs_kv array; for now ensure it's not compiled --#undef _qsSORTING -- --// isxdigit _is_ available in <ctype.h>, but let's avoid another header instead --#define BMCWEB_QS_ISHEX(x) \ -- ((((x) >= '0' && (x) <= '9') || ((x) >= 'A' && (x) <= 'F') || \ -- ((x) >= 'a' && (x) <= 'f')) \ -- ? 1 \ -- : 0) --#define BMCWEB_QS_HEX2DEC(x) \ -- (((x) >= '0' && (x) <= '9') \ -- ? (x)-48 \ -- : ((x) >= 'A' && (x) <= 'F') \ -- ? (x)-55 \ -- : ((x) >= 'a' && (x) <= 'f') ? (x)-87 : 0) --#define BMCWEB_QS_ISQSCHR(x) \ -- ((((x) == '=') || ((x) == '#') || ((x) == '&') || ((x) == '\0')) ? 0 : 1) -- --inline int qsStrncmp(const char* s, const char* qs, size_t n) --{ -- int i = 0; -- char u1, u2; -- char unyb, lnyb; -- -- while (n-- > 0) -- { -- u1 = *s++; -- u2 = *qs++; -- -- if (!BMCWEB_QS_ISQSCHR(u1)) -- { -- u1 = '\0'; -- } -- if (!BMCWEB_QS_ISQSCHR(u2)) -- { -- u2 = '\0'; -- } -- -- if (u1 == '+') -- { -- u1 = ' '; -- } -- if (u1 == '%') // easier/safer than scanf -- { -- unyb = static_cast<char>(*s++); -- lnyb = static_cast<char>(*s++); -- if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) -- { -- u1 = static_cast<char>((BMCWEB_QS_HEX2DEC(unyb) * 16) + -- BMCWEB_QS_HEX2DEC(lnyb)); -- } -- else -- { -- u1 = '\0'; -- } -- } -- -- if (u2 == '+') -- { -- u2 = ' '; -- } -- if (u2 == '%') // easier/safer than scanf -- { -- unyb = static_cast<char>(*qs++); -- lnyb = static_cast<char>(*qs++); -- if (BMCWEB_QS_ISHEX(unyb) && BMCWEB_QS_ISHEX(lnyb)) -- { -- u2 = static_cast<char>((BMCWEB_QS_HEX2DEC(unyb) * 16) + -- BMCWEB_QS_HEX2DEC(lnyb)); -- } -- else -- { -- u2 = '\0'; -- } -- } -- -- if (u1 != u2) -- { -- return u1 - u2; -- } -- if (u1 == '\0') -- { -- return 0; -- } -- i++; -- } -- if (BMCWEB_QS_ISQSCHR(*qs)) -- { -- return -1; -- } -- else -- { -- return 0; -- } --} -- --inline size_t qsParse(char* qs, char* qs_kv[], size_t qs_kv_size) --{ -- size_t i; -- size_t j; -- char* substrPtr; -- -- for (i = 0; i < qs_kv_size; i++) -- { -- qs_kv[i] = nullptr; -- } -- -- // find the beginning of the k/v substrings or the fragment -- substrPtr = qs + strcspn(qs, "?#"); -- if (substrPtr[0] != '\0') -- { -- substrPtr++; -- } -- else -- { -- return 0; // no query or fragment -- } -- -- i = 0; -- while (i < qs_kv_size) -- { -- qs_kv[i++] = substrPtr; -- j = strcspn(substrPtr, "&"); -- if (substrPtr[j] == '\0') -- { -- break; -- } -- substrPtr += j + 1; -- } -- -- // we only decode the values in place, the keys could have '='s in them -- // which will hose our ability to distinguish keys from values later -- for (j = 0; j < i; j++) -- { -- substrPtr = qs_kv[j] + strcspn(qs_kv[j], "=&#"); -- if (substrPtr[0] == '&' || substrPtr[0] == '\0') -- { // blank value: skip decoding -- substrPtr[0] = '\0'; -- } -- else -- { -- qsDecode(++substrPtr); -- } -- } -- --#ifdef _qsSORTING --// TODO: qsort qs_kv, using qs_strncmp() for the comparison --#endif -- -- return i; --} -- --inline int qsDecode(char* qs) --{ -- int i = 0, j = 0; -- -- while (BMCWEB_QS_ISQSCHR(qs[j])) -- { -- if (qs[j] == '+') -- { -- qs[i] = ' '; -- } -- else if (qs[j] == '%') // easier/safer than scanf -- { -- if (!BMCWEB_QS_ISHEX(qs[j + 1]) || !BMCWEB_QS_ISHEX(qs[j + 2])) -- { -- qs[i] = '\0'; -- return i; -- } -- qs[i] = static_cast<char>((BMCWEB_QS_HEX2DEC(qs[j + 1]) * 16) + -- BMCWEB_QS_HEX2DEC(qs[j + 2])); -- j += 2; -- } -- else -- { -- qs[i] = qs[j]; -- } -- i++; -- j++; -- } -- qs[i] = '\0'; -- -- return i; --} -- --inline char* qsK2v(const char* key, char* const* qs_kv, int qs_kv_size, -- int nth = 0) --{ -- int i; -- size_t keyLen, skip; -- -- keyLen = strlen(key); -- --#ifdef _qsSORTING --// TODO: binary search for key in the sorted qs_kv --#else // _qsSORTING -- for (i = 0; i < qs_kv_size; i++) -- { -- // we rely on the unambiguous '=' to find the value in our k/v pair -- if (qsStrncmp(key, qs_kv[i], keyLen) == 0) -- { -- skip = strcspn(qs_kv[i], "="); -- if (qs_kv[i][skip] == '=') -- { -- skip++; -- } -- // return (zero-char value) ? ptr to trailing '\0' : ptr to value -- if (nth == 0) -- { -- return qs_kv[i] + skip; -- } -- else -- { -- --nth; -- } -- } -- } --#endif // _qsSORTING -- -- return nullptr; --} -- --inline char* qsScanvalue(const char* key, const char* qs, char* val, -- size_t val_len) --{ -- size_t i, keyLen; -- const char* tmp; -- -- // find the beginning of the k/v substrings -- if ((tmp = strchr(qs, '?')) != nullptr) -- { -- qs = tmp + 1; -- } -- -- keyLen = strlen(key); -- while (qs[0] != '#' && qs[0] != '\0') -- { -- if (qsStrncmp(key, qs, keyLen) == 0) -- { -- break; -- } -- qs += strcspn(qs, "&") + 1; -- } -- -- if (qs[0] == '\0') -- { -- return nullptr; -- } -- -- qs += strcspn(qs, "=&#"); -- if (qs[0] == '=') -- { -- qs++; -- i = strcspn(qs, "&=#"); -- strncpy(val, qs, (val_len - 1) < (i + 1) ? (val_len - 1) : (i + 1)); -- qsDecode(val); -- } -- else -- { -- if (val_len > 0) -- { -- val[0] = '\0'; -- } -- } -- -- return val; --} --} // namespace crow --// ---------------------------------------------------------------------------- -- --namespace crow --{ --class QueryString --{ -- public: -- static const size_t maxKeyValuePairsCount = 256; -- -- QueryString() = default; -- -- QueryString(const QueryString& qs) : url(qs.url) -- { -- for (auto p : qs.keyValuePairs) -- { -- keyValuePairs.push_back( -- const_cast<char*>(p - qs.url.c_str() + url.c_str())); -- } -- } -- -- QueryString& operator=(const QueryString& qs) -- { -- if (this == &qs) -- { -- return *this; -- } -- -- url = qs.url; -- keyValuePairs.clear(); -- for (auto p : qs.keyValuePairs) -- { -- keyValuePairs.push_back( -- const_cast<char*>(p - qs.url.c_str() + url.c_str())); -- } -- return *this; -- } -- -- QueryString& operator=(QueryString&& qs) -- { -- keyValuePairs = std::move(qs.keyValuePairs); -- auto* oldData = const_cast<char*>(qs.url.c_str()); -- url = std::move(qs.url); -- for (auto& p : keyValuePairs) -- { -- p += const_cast<char*>(url.c_str()) - oldData; -- } -- return *this; -- } -- -- explicit QueryString(std::string newUrl) : url(std::move(newUrl)) -- { -- if (url.empty()) -- { -- return; -- } -- -- keyValuePairs.resize(maxKeyValuePairsCount); -- -- size_t count = -- qsParse(&url[0], &keyValuePairs[0], maxKeyValuePairsCount); -- keyValuePairs.resize(count); -- } -- -- void clear() -- { -- keyValuePairs.clear(); -- url.clear(); -- } -- -- friend std::ostream& operator<<(std::ostream& os, const QueryString& qs) -- { -- os << "[ "; -- for (size_t i = 0; i < qs.keyValuePairs.size(); ++i) -- { -- if (i != 0u) -- { -- os << ", "; -- } -- os << qs.keyValuePairs[i]; -- } -- os << " ]"; -- return os; -- } -- -- char* get(const std::string& name) const -- { -- char* ret = qsK2v(name.c_str(), keyValuePairs.data(), -- static_cast<int>(keyValuePairs.size())); -- return ret; -- } -- -- std::vector<char*> getList(const std::string& name) const -- { -- std::vector<char*> ret; -- std::string plus = name + "[]"; -- char* element = nullptr; -- -- int count = 0; -- while (true) -- { -- element = qsK2v(plus.c_str(), keyValuePairs.data(), -- static_cast<int>(keyValuePairs.size()), count++); -- if (element == nullptr) -- { -- break; -- } -- ret.push_back(element); -- } -- return ret; -- } -- -- private: -- std::string url; -- std::vector<char*> keyValuePairs; --}; -- --} // namespace crow -diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp -index b27c6e0..8bd30f5 100644 ---- a/redfish-core/lib/event_service.hpp -+++ b/redfish-core/lib/event_service.hpp -@@ -445,13 +445,16 @@ class EventServiceSSE : public Node - subValue->protocol = "Redfish"; - subValue->retryPolicy = "TerminateAfterRetries"; - -- char* filters = req.urlParams.get("$filter"); -- if (filters == nullptr) -+ boost::urls::url_view::params_type::iterator it = -+ req.urlParams.find("$filter"); -+ if (it == req.urlParams.end()) - { - subValue->eventFormatType = "Event"; - } -+ - else - { -+ std::string filters = it->value(); - // Reading from query params. - bool status = readSSEQueryParams( - filters, subValue->eventFormatType, subValue->registryMsgIds, -diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp -index bee1a92..590243c 100644 ---- a/redfish-core/lib/log_services.hpp -+++ b/redfish-core/lib/log_services.hpp -@@ -218,12 +218,14 @@ static bool getEntryTimestamp(sd_journal* journal, std::string& entryTimestamp) - static bool getSkipParam(crow::Response& res, const crow::Request& req, - uint64_t& skip) - { -- char* skipParam = req.urlParams.get("$skip"); -- if (skipParam != nullptr) -+ boost::urls::url_view::params_type::iterator it = -+ req.urlParams.find("$skip"); -+ if (it != req.urlParams.end()) - { -+ std::string skipParam = it->value(); - char* ptr = nullptr; -- skip = std::strtoul(skipParam, &ptr, 10); -- if (*skipParam == '\0' || *ptr != '\0') -+ skip = std::strtoul(skipParam.c_str(), &ptr, 10); -+ if (skipParam.empty() || *ptr != '\0') - { - - messages::queryParameterValueTypeError(res, std::string(skipParam), -@@ -238,12 +240,14 @@ static constexpr const uint64_t maxEntriesPerPage = 1000; - static bool getTopParam(crow::Response& res, const crow::Request& req, - uint64_t& top) - { -- char* topParam = req.urlParams.get("$top"); -- if (topParam != nullptr) -+ boost::urls::url_view::params_type::iterator it = -+ req.urlParams.find("$top"); -+ if (it != req.urlParams.end()) - { -+ std::string topParam = it->value(); - char* ptr = nullptr; -- top = std::strtoul(topParam, &ptr, 10); -- if (*topParam == '\0' || *ptr != '\0') -+ top = std::strtoul(topParam.c_str(), &ptr, 10); -+ if (topParam.empty() || *ptr != '\0') - { - messages::queryParameterValueTypeError(res, std::string(topParam), - "$top"); --- -2.17.1 - |