Commit 1e5e33a5 authored by Jun LI's avatar Jun LI Committed by Chip Turner

Add method to parse parameter list in query string to folly::Uri

Summary:
Add a method to folly::Uri to get parsed query string

e.g. http://localhost?key1=foo&key2=bar

We can get key value map containing:
"key1" => "foo"
"key2" => "bar"

Test Plan:
fbconfig folly/test
fbmake runtests_dbg

Reviewed By: tudorb@fb.com

Subscribers: wormhole-dev@

FB internal diff: D1455158

Tasks: 4768038
parent b942767a
......@@ -91,6 +91,26 @@ Uri::Uri(StringPiece str) : port_(0) {
}
query_ = submatch(match, 3);
if (!query_.empty()) {
// Parse query string
static const boost::regex queryParamRegex(
"(^|&)([^=&]*)=?([^=&]*)(?=(&|$))");
boost::cregex_iterator paramBeginItr(
match[3].first,
match[3].second,
queryParamRegex);
boost::cregex_iterator paramEndItr;
for(auto itr = paramBeginItr; itr != paramEndItr; itr++) {
if (itr->length(2) == 0) {
// key is empty, ignore it
continue;
}
queryParams_.emplace_back(
fbstring((*itr)[2].first, (*itr)[2].second), // parameter name
fbstring((*itr)[3].first, (*itr)[3].second) // parameter value
);
}
}
fragment_ = submatch(match, 4);
}
......
......@@ -18,6 +18,7 @@
#define FOLLY_URI_H_
#include <folly/String.h>
#include <vector>
namespace folly {
......@@ -77,6 +78,26 @@ class Uri {
void setPort(uint16_t port) {port_ = port;}
/**
* Get query parameters as key-value pairs.
* e.g. for URI containing query string: key1=foo&key2=&key3&=bar&=bar=
* In returned list, there are 3 entries:
* "key1" => "foo"
* "key2" => ""
* "key3" => ""
* Parts "=bar" and "=bar=" are ignored, as they are not valid query
* parameters. "=bar" is missing parameter name, while "=bar=" has more than
* one equal signs, we don't know which one is the delimiter for key and
* value.
*
* @return query parameter key-value pairs in a vector, each element is a
* pair of which the first element is parameter name and the second
* one is parameter value
*/
const std::vector<std::pair<fbstring, fbstring>>& getQueryParams() const {
return queryParams_;
};
private:
fbstring scheme_;
fbstring username_;
......@@ -86,6 +107,7 @@ class Uri {
fbstring path_;
fbstring query_;
fbstring fragment_;
std::vector<std::pair<fbstring, fbstring>> queryParams_;
};
} // namespace folly
......
......@@ -19,6 +19,7 @@
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>
#include <gtest/gtest.h>
#include <map>
using namespace folly;
......@@ -255,6 +256,73 @@ TEST(Uri, Simple) {
EXPECT_EQ(s, u.fbstr());
}
{
// test query parameters
fbstring s("http://localhost?&key1=foo&key2=&key3&=bar&=bar=&");
Uri u(s);
auto paramsList = u.getQueryParams();
std::map<fbstring, fbstring> params;
for (auto& param : paramsList) {
params[param.first] = param.second;
}
EXPECT_EQ(3, params.size());
EXPECT_EQ("foo", params["key1"]);
EXPECT_NE(params.end(), params.find("key2"));
EXPECT_EQ("", params["key2"]);
EXPECT_NE(params.end(), params.find("key3"));
EXPECT_EQ("", params["key3"]);
}
{
// test query parameters
fbstring s("http://localhost?&&&&&&&&&&&&&&&");
Uri u(s);
auto params = u.getQueryParams();
EXPECT_TRUE(params.empty());
}
{
// test query parameters
fbstring s("http://localhost?&=invalid_key&key2&key3=foo");
Uri u(s);
auto paramsList = u.getQueryParams();
std::map<fbstring, fbstring> params;
for (auto& param : paramsList) {
params[param.first] = param.second;
}
EXPECT_EQ(2, params.size());
EXPECT_NE(params.end(), params.find("key2"));
EXPECT_EQ("", params["key2"]);
EXPECT_EQ("foo", params["key3"]);
}
{
// test query parameters
fbstring s("http://localhost?&key1=====&&=key2&key3=");
Uri u(s);
auto paramsList = u.getQueryParams();
std::map<fbstring, fbstring> params;
for (auto& param : paramsList) {
params[param.first] = param.second;
}
EXPECT_EQ(1, params.size());
EXPECT_NE(params.end(), params.find("key3"));
EXPECT_EQ("", params["key3"]);
}
{
// test query parameters
fbstring s("http://localhost?key1=foo=bar&key2=foobar&");
Uri u(s);
auto paramsList = u.getQueryParams();
std::map<fbstring, fbstring> params;
for (auto& param : paramsList) {
params[param.first] = param.second;
}
EXPECT_EQ(1, params.size());
EXPECT_EQ("foobar", params["key2"]);
}
{
fbstring s("2http://www.facebook.com");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment