Browse Source

[PR] Special function to encode query params (#801)

* Special function to encode query params

* Fix #include <iomanip>

* Added unescaped charsets to encode_query_param

* Unit tests for encode_query_param
Yuri Santos 5 years ago
parent
commit
78ea786abd
2 changed files with 41 additions and 2 deletions
  1. 29 2
      httplib.h
  2. 12 0
      test/test.cc

+ 29 - 2
httplib.h

@@ -203,6 +203,7 @@ using socket_t = int;
 #include <string>
 #include <string>
 #include <sys/stat.h>
 #include <sys/stat.h>
 #include <thread>
 #include <thread>
+#include <iomanip>
 
 
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #ifdef CPPHTTPLIB_OPENSSL_SUPPORT
 #include <openssl/err.h>
 #include <openssl/err.h>
@@ -214,7 +215,6 @@ using socket_t = int;
 #include <openssl/applink.c>
 #include <openssl/applink.c>
 #endif
 #endif
 
 
-#include <iomanip>
 #include <iostream>
 #include <iostream>
 #include <sstream>
 #include <sstream>
 
 
@@ -1457,6 +1457,33 @@ inline bool is_valid_path(const std::string &path) {
   return true;
   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<int>(static_cast<unsigned char>(c));
+      escaped << std::nouppercase;
+    }
+  }
+
+  return escaped.str();
+}
+
 inline std::string encode_url(const std::string &s) {
 inline std::string encode_url(const std::string &s) {
   std::string result;
   std::string result;
 
 
@@ -3045,7 +3072,7 @@ inline std::string params_to_query_str(const Params &params) {
     if (it != params.begin()) { query += "&"; }
     if (it != params.begin()) { query += "&"; }
     query += it->first;
     query += it->first;
     query += "=";
     query += "=";
-    query += encode_url(it->second);
+    query += encode_query_param(it->second);
   }
   }
   return query;
   return query;
 }
 }

+ 12 - 0
test/test.cc

@@ -46,6 +46,18 @@ TEST(StartupTest, WSAStartup) {
 }
 }
 #endif
 #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) {
 TEST(TrimTests, TrimStringTests) {
   EXPECT_EQ("abc", detail::trim_copy("abc"));
   EXPECT_EQ("abc", detail::trim_copy("abc"));
   EXPECT_EQ("abc", detail::trim_copy("  abc  "));
   EXPECT_EQ("abc", detail::trim_copy("  abc  "));