diff options
-rw-r--r-- | http/ut/utility_test.cpp | 41 | ||||
-rw-r--r-- | http/utility.hpp | 46 | ||||
-rw-r--r-- | redfish-core/include/event_service_manager.hpp | 50 |
3 files changed, 89 insertions, 48 deletions
diff --git a/http/ut/utility_test.cpp b/http/ut/utility_test.cpp index eecd1f6e41..5fdfcb5c4e 100644 --- a/http/ut/utility_test.cpp +++ b/http/ut/utility_test.cpp @@ -1,6 +1,9 @@ +#include "bmcweb_config.h" + #include "utility.hpp" #include "gmock/gmock.h" +#include "gtest/gtest.h" namespace crow::utility { @@ -123,5 +126,43 @@ TEST(Utility, UrlFromPieces) url = urlFromPieces("/", "bad&tring"); EXPECT_EQ(std::string_view(url.data(), url.size()), "/%2f/bad&tring"); } + +TEST(Utility, ValidateAndSplitUrlPositive) +{ + using crow::utility::validateAndSplitUrl; + std::string host; + std::string urlProto; + std::string port; + std::string path; + ASSERT_TRUE(validateAndSplitUrl("https://foo.com:18080/bar", urlProto, host, + port, path)); + EXPECT_EQ(host, "foo.com"); + EXPECT_EQ(urlProto, "https"); + EXPECT_EQ(port, "18080"); + + EXPECT_EQ(path, "/bar"); + + // query string + ASSERT_TRUE(validateAndSplitUrl("https://foo.com:18080/bar?foobar=1", + urlProto, host, port, path)); + EXPECT_EQ(path, "/bar?foobar=1"); + + // Missing port + ASSERT_TRUE( + validateAndSplitUrl("https://foo.com/bar", urlProto, host, port, path)); + EXPECT_EQ(port, "443"); + + // If http push eventing is allowed, allow http, if it's not, parse should + // fail. +#ifdef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING + ASSERT_TRUE( + validateAndSplitUrl("http://foo.com/bar", urlProto, host, port, path)); + EXPECT_EQ(port, "80"); +#else + ASSERT_FALSE( + validateAndSplitUrl("http://foo.com/bar", urlProto, host, port, path)); +#endif +} + } // namespace } // namespace crow::utility diff --git a/http/utility.hpp b/http/utility.hpp index 873cfe41ed..37c06cd7ed 100644 --- a/http/utility.hpp +++ b/http/utility.hpp @@ -11,6 +11,7 @@ #include <ctime> #include <functional> #include <limits> +#include <regex> #include <stdexcept> #include <string> #include <string_view> @@ -692,5 +693,50 @@ inline boost::urls::url urlFromPieces(const AV... args) return details::urlFromPiecesDetail({args...}); } +inline bool validateAndSplitUrl(std::string_view destUrl, std::string& urlProto, + std::string& host, std::string& port, + std::string& path) +{ + // Validate URL using regex expression + // Format: <protocol>://<host>:<port>/<path> + // protocol: http/https + const std::regex urlRegex( + "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/" + "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)"); + std::cmatch match; + if (!std::regex_match(destUrl.begin(), destUrl.end(), match, urlRegex)) + { + return false; + } + + urlProto = std::string(match[1].first, match[1].second); + if (urlProto == "http") + { +#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING + return false; +#endif + } + + host = std::string(match[2].first, match[2].second); + port = std::string(match[3].first, match[3].second); + path = std::string(match[4].first, match[4].second); + if (port.empty()) + { + if (urlProto == "http") + { + port = "80"; + } + else + { + port = "443"; + } + } + if (path.empty()) + { + path = "/"; + } + return true; +} + } // namespace utility } // namespace crow diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp index 5592d641d3..e879f9e039 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -620,8 +620,8 @@ class EventServiceManager std::string urlProto; std::string port; std::string path; - bool status = validateAndSplitUrl(newSub->destinationUrl, urlProto, - host, port, path); + bool status = crow::utility::validateAndSplitUrl( + newSub->destinationUrl, urlProto, host, port, path); if (!status) { @@ -1392,52 +1392,6 @@ class EventServiceManager getReadingsForReport(msg); }); } - - bool validateAndSplitUrl(const std::string& destUrl, std::string& urlProto, - std::string& host, std::string& port, - std::string& path) - { - // Validate URL using regex expression - // Format: <protocol>://<host>:<port>/<path> - // protocol: http/https - const std::regex urlRegex( - "(http|https)://([^/\\x20\\x3f\\x23\\x3a]+):?([0-9]*)(/" - "([^\\x20\\x23\\x3f]*\\x3f?([^\\x20\\x23\\x3f])*)?)"); - std::cmatch match; - if (!std::regex_match(destUrl.c_str(), match, urlRegex)) - { - BMCWEB_LOG_INFO << "Dest. url did not match "; - return false; - } - - urlProto = std::string(match[1].first, match[1].second); - if (urlProto == "http") - { -#ifndef BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING - return false; -#endif - } - - host = std::string(match[2].first, match[2].second); - port = std::string(match[3].first, match[3].second); - path = std::string(match[4].first, match[4].second); - if (port.empty()) - { - if (urlProto == "http") - { - port = "80"; - } - else - { - port = "443"; - } - } - if (path.empty()) - { - path = "/"; - } - return true; - } }; } // namespace redfish |