Skip to content

Commit 8bd4846

Browse files
committed
Handle percent encoding of URL and request parameters. Resolves #19
1 parent db2a1aa commit 8bd4846

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

src/ResourceResolver.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,7 @@ void ResourceResolver::resolveNode(const std::string &method, const std::string
5858
std::string name = param.substr(0, nvSplitIdx);
5959
std::string value = "";
6060
if (nvSplitIdx != std::string::npos) {
61-
// TODO: There may be url encoding in here.
62-
value = param.substr(nvSplitIdx+1);
61+
value = urlDecode(param.substr(nvSplitIdx+1));
6362
}
6463

6564
// Now we finally have name and value.
@@ -116,15 +115,15 @@ void ResourceResolver::resolveNode(const std::string &method, const std::string
116115
// Second step: Grab the parameter value
117116
if (nodeIdx == nodepath.length()) {
118117
// Easy case: parse until end of string
119-
params->setUrlParameter(pIdx, resourceName.substr(urlIdx));
118+
params->setUrlParameter(pIdx, urlDecode(resourceName.substr(urlIdx)));
120119
} else {
121120
// parse until first char after the placeholder
122121
char terminatorChar = nodepath[nodeIdx];
123122
size_t terminatorPosition = resourceName.find(terminatorChar, urlIdx);
124123
if (terminatorPosition != std::string::npos) {
125124
// We actually found the terminator
126125
size_t dynamicLength = terminatorPosition-urlIdx;
127-
params->setUrlParameter(pIdx, resourceName.substr(urlIdx, dynamicLength));
126+
params->setUrlParameter(pIdx, urlDecode(resourceName.substr(urlIdx, dynamicLength)));
128127
urlIdx = urlIdx + dynamicLength;
129128
} else {
130129
// We did not find the terminator

src/util.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,34 @@ std::string intToString(int i) {
5858
}
5959

6060
}
61+
62+
std::string urlDecode(std::string input) {
63+
std::size_t idxReplaced = 0;
64+
std::size_t idxFound = input.find('%');
65+
while (idxFound != std::string::npos) {
66+
if (idxFound <= input.length() + 3) {
67+
char hex[2] = { input[idxFound+1], input[idxFound+2] };
68+
byte val = 0;
69+
for(int n = 0; n < sizeof(hex); n++) {
70+
val <<= 4;
71+
if ('0' <= hex[n] && hex[n] <= '9') {
72+
val += hex[n]-'0';
73+
}
74+
else if ('A' <= hex[n] && hex[n] <= 'F') {
75+
val += hex[n]-'A'+10;
76+
}
77+
else if ('a' <= hex[n] && hex[n] <= 'f') {
78+
val += hex[n]-'a'+10;
79+
}
80+
else {
81+
goto skipChar;
82+
}
83+
}
84+
input.replace(idxFound, 3, 1, (char)val);
85+
}
86+
skipChar:
87+
idxReplaced = idxFound + 1;
88+
idxFound = input.find('%', idxReplaced);
89+
}
90+
return input;
91+
}

src/util.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,9 @@ std::string intToString(int i);
2727

2828
}
2929

30+
/**
31+
* \brief **Utility function**: Removes URL encoding from the string (e.g. %20 -> space)
32+
*/
33+
std::string urlDecode(std::string input);
34+
3035
#endif /* SRC_UTIL_HPP_ */

0 commit comments

Comments
 (0)