diff --git a/httplib.h b/httplib.h index bb31cfe..656013f 100644 --- a/httplib.h +++ b/httplib.h @@ -203,6 +203,7 @@ using socket_t = int; #include #include #include +#include #ifdef CPPHTTPLIB_OPENSSL_SUPPORT #include @@ -214,7 +215,6 @@ using socket_t = int; #include #endif -#include #include #include @@ -1457,6 +1457,33 @@ inline bool is_valid_path(const std::string &path) { return true; } +inline std::string encode_query_param(const std::string &value){ + std::ostringstream escaped; + escaped.fill('0'); + escaped << std::hex; + + for (char const &c: value) { + if (std::isalnum(c) || + c == '-' || + c == '_' || + c == '.' || + c == '!' || + c == '~' || + c == '*' || + c == '\'' || + c == '(' || + c == ')') { + escaped << c; + } else { + escaped << std::uppercase; + escaped << '%' << std::setw(2) << static_cast(static_cast(c)); + escaped << std::nouppercase; + } + } + + return escaped.str(); +} + inline std::string encode_url(const std::string &s) { std::string result; @@ -3045,7 +3072,7 @@ inline std::string params_to_query_str(const Params ¶ms) { if (it != params.begin()) { query += "&"; } query += it->first; query += "="; - query += encode_url(it->second); + query += encode_query_param(it->second); } return query; } diff --git a/test/test.cc b/test/test.cc index c638ba3..9eb577b 100644 --- a/test/test.cc +++ b/test/test.cc @@ -46,6 +46,18 @@ TEST(StartupTest, WSAStartup) { } #endif +TEST(EncodeQueryParamTest, ParseUnescapedChararactersTest){ + string unescapedCharacters = "-_.!~*'()"; + + EXPECT_EQ(detail::encode_query_param(unescapedCharacters), "-_.!~*'()"); +} + +TEST(EncodeQueryParamTest, ParseReservedCharactersTest){ + string reservedCharacters = ";,/?:@&=+$"; + + EXPECT_EQ(detail::encode_query_param(reservedCharacters), "%3B%2C%2F%3F%3A%40%26%3D%2B%24"); +} + TEST(TrimTests, TrimStringTests) { EXPECT_EQ("abc", detail::trim_copy("abc")); EXPECT_EQ("abc", detail::trim_copy(" abc "));