Finished query string parsing implementation (PR #109)
This commit is contained in:
parent
e68488a157
commit
550bbfe9d7
2 changed files with 66 additions and 20 deletions
|
|
@ -107,13 +107,39 @@ namespace SimpleWeb {
|
|||
Content content;
|
||||
|
||||
std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> header;
|
||||
std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> query_string;
|
||||
|
||||
REGEX_NS::smatch path_match;
|
||||
|
||||
std::string remote_endpoint_address;
|
||||
unsigned short remote_endpoint_port;
|
||||
|
||||
/// Returns query keys with percent-decoded values.
|
||||
std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> parse_query_string() {
|
||||
std::unordered_multimap<std::string, std::string, case_insensitive_hash, case_insensitive_equals> result;
|
||||
auto qs_start_pos = path.find('?');
|
||||
if (qs_start_pos != std::string::npos && qs_start_pos + 1 < path.size()) {
|
||||
++qs_start_pos;
|
||||
static REGEX_NS::regex pattern("([\\w+%]+)=?([^&]*)");
|
||||
int submatches[] = {1, 2};
|
||||
auto it_begin = REGEX_NS::sregex_token_iterator(path.begin() + qs_start_pos, path.end(), pattern, submatches);
|
||||
auto it_end = REGEX_NS::sregex_token_iterator();
|
||||
for (auto it = it_begin; it != it_end; ++it) {
|
||||
auto query_it = result.emplace(it->str(), (++it)->str());
|
||||
auto &value = query_it->second;
|
||||
for (size_t c = 0; c < value.size(); ++c) {
|
||||
if (value[c] == '+')
|
||||
value[c] = ' ';
|
||||
else if (value[c] == '%' && c + 2 < value.size()) {
|
||||
auto hex = value.substr(c + 1, 2);
|
||||
auto chr = static_cast<char>(std::strtol(hex.c_str(), nullptr, 16));
|
||||
value.replace(c, 3, &chr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
Request(const socket_type &socket): content(streambuf) {
|
||||
try {
|
||||
|
|
@ -321,25 +347,6 @@ namespace SimpleWeb {
|
|||
request->method=line.substr(0, method_end);
|
||||
request->path=line.substr(method_end+1, path_end-method_end-1);
|
||||
|
||||
//search and populte query_string
|
||||
size_t qs_start;
|
||||
if ((qs_start = request->path.find('?')) != std::string::npos)
|
||||
{
|
||||
std::string qs = request->path.substr(qs_start, request->path.size() - qs_start - 1);
|
||||
REGEX_NS::regex pattern("([\\w+%]+)=?([^&]*)");
|
||||
int submatches[] = { 1, 2 };
|
||||
auto qs_begin = REGEX_NS::sregex_token_iterator(qs.begin(), qs.end(), pattern, submatches);
|
||||
auto qs_end = REGEX_NS::sregex_token_iterator();
|
||||
|
||||
for (auto it = qs_begin; it != qs_end; it++)
|
||||
{
|
||||
std::string key = it->str();
|
||||
std::string value = (++it)->str();
|
||||
request->query_string.emplace(std::make_pair(key, value));
|
||||
}
|
||||
request->path = request->path.substr(0, qs_start);
|
||||
}
|
||||
|
||||
size_t protocol_end;
|
||||
if((protocol_end=line.find('/', path_end+1))!=std::string::npos) {
|
||||
if(line.compare(path_end+1, protocol_end-path_end-1, "HTTP")!=0)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue