}
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);
}
#define FOLLY_URI_H_
#include <folly/String.h>
+#include <vector>
namespace folly {
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_;
fbstring path_;
fbstring query_;
fbstring fragment_;
+ std::vector<std::pair<fbstring, fbstring>> queryParams_;
};
} // namespace folly
#include <boost/algorithm/string.hpp>
#include <glog/logging.h>
#include <gtest/gtest.h>
+#include <map>
using namespace folly;
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");