changeset 336:3c291753231f

url decode
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sun, 13 Jan 2013 21:50:11 +0100
parents daff912c9ffe
children 26218c4de7e0
files Core/HttpServer/HttpHandler.cpp Core/Toolbox.cpp Core/Toolbox.h UnitTests/main.cpp
diffstat 4 files changed, 70 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/Core/HttpServer/HttpHandler.cpp	Fri Jan 11 14:54:39 2013 +0100
+++ b/Core/HttpServer/HttpHandler.cpp	Sun Jan 13 21:50:11 2013 +0100
@@ -54,6 +54,9 @@
       value = std::string(equal + 1, end);
     }
 
+    Toolbox::UrlDecode(name);
+    Toolbox::UrlDecode(value);
+
     result.insert(std::make_pair(name, value));
   }
 
--- a/Core/Toolbox.cpp	Fri Jan 11 14:54:39 2013 +0100
+++ b/Core/Toolbox.cpp	Sun Jan 13 21:50:11 2013 +0100
@@ -592,4 +592,51 @@
     assert(first <= last);
     return source.substr(first, last - first);
   }
+
+
+  static uint8_t Hex2Dec(char c)
+  {
+    return ((c >= '0' && c <= '9') ? c - '0' :
+            ((c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - 'A' + 10));
+  }
+
+  void Toolbox::UrlDecode(std::string& s)
+  {
+    // http://en.wikipedia.org/wiki/Percent-encoding
+    // http://www.w3schools.com/tags/ref_urlencode.asp
+    // http://stackoverflow.com/questions/154536/encode-decode-urls-in-c
+
+    if (s.size() == 0)
+    {
+      return;
+    }
+
+    size_t source = 0;
+    size_t target = 0;
+
+    while (source < s.size())
+    {
+      if (s[source] == '%' &&
+          source + 2 < s.size() &&
+          isalnum(s[source + 1]) &&
+          isalnum(s[source + 2]))
+      {
+        s[target] = (Hex2Dec(s[source + 1]) << 4) | Hex2Dec(s[source + 2]);
+        source += 3;
+        target += 1;
+      }
+      else
+      {
+        if (s[source] == '+')
+          s[target] = ' ';
+        else
+          s[target] = s[source];
+
+        source++;
+        target++;
+      }
+    }
+
+    s.resize(target);
+  }
 }
--- a/Core/Toolbox.h	Fri Jan 11 14:54:39 2013 +0100
+++ b/Core/Toolbox.h	Sun Jan 13 21:50:11 2013 +0100
@@ -94,5 +94,8 @@
     std::string StripSpaces(const std::string& source);
 
     std::string GetNowIsoString();
+
+    // In-place percent-decoding for URL
+    void UrlDecode(std::string& s);
   }
 }
--- a/UnitTests/main.cpp	Fri Jan 11 14:54:39 2013 +0100
+++ b/UnitTests/main.cpp	Sun Jan 13 21:50:11 2013 +0100
@@ -297,6 +297,23 @@
   ASSERT_EQ(0x00, static_cast<unsigned char>(utf8[14]));  // Null-terminated string
 }
 
+TEST(Toolbox, UrlDecode)
+{
+  std::string s;
+
+  s = "Hello%20World";
+  Toolbox::UrlDecode(s);
+  ASSERT_EQ("Hello World", s);
+
+  s = "%21%23%24%26%27%28%29%2A%2B%2c%2f%3A%3b%3d%3f%40%5B%5D";
+  Toolbox::UrlDecode(s);
+  ASSERT_EQ("!#$&'()*+,/:;=?@[]", s);
+
+  s = "(2000%2C00A4)+Other";
+  Toolbox::UrlDecode(s);
+  ASSERT_EQ("(2000,00A4) Other", s);
+}
+
 
 int main(int argc, char **argv)
 {