Add parse_url_query.
This commit is contained in:
parent
4cc60bbc25
commit
200da2c684
@ -173,6 +173,40 @@ StringBuilder &operator<<(StringBuilder &sb, const HttpUrl &url) {
|
||||
return sb;
|
||||
}
|
||||
|
||||
HttpUrlQuery parse_url_query(Slice query) {
|
||||
size_t path_size = 0;
|
||||
while (path_size < query.size() && query[path_size] != '?' && query[path_size] != '#') {
|
||||
path_size++;
|
||||
}
|
||||
|
||||
HttpUrlQuery result;
|
||||
result.path_ = url_decode(query.substr(0, path_size), false);
|
||||
|
||||
if (path_size < query.size() && query[path_size] == '?') {
|
||||
query = query.substr(path_size + 1);
|
||||
query.truncate(query.find('#'));
|
||||
|
||||
ConstParser parser(query);
|
||||
while (!parser.data().empty()) {
|
||||
auto key_value = split(parser.read_till_nofail('&'), '=');
|
||||
parser.skip_nofail('&');
|
||||
auto key = url_decode(key_value.first, true);
|
||||
if (!key.empty()) {
|
||||
result.args_.emplace_back(std::move(key), url_decode(key_value.second, true));
|
||||
}
|
||||
}
|
||||
CHECK(parser.status().is_ok());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Slice HttpUrlQuery::get_arg(Slice key) const {
|
||||
auto it =
|
||||
std::find_if(args_.begin(), args_.end(), [&key](const std::pair<string, string> &s) { return s.first == key; });
|
||||
return it == args_.end() ? Slice() : it->second;
|
||||
}
|
||||
|
||||
string get_url_query_file_name(const string &query) {
|
||||
Slice query_slice = query;
|
||||
query_slice.truncate(query.find_first_of("?#"));
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include "td/utils/Status.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace td {
|
||||
|
||||
class HttpUrl {
|
||||
@ -41,6 +43,16 @@ Result<HttpUrl> parse_url(Slice url,
|
||||
|
||||
StringBuilder &operator<<(StringBuilder &sb, const HttpUrl &url);
|
||||
|
||||
class HttpUrlQuery {
|
||||
public:
|
||||
string path_;
|
||||
vector<std::pair<string, string>> args_;
|
||||
|
||||
Slice get_arg(Slice key) const;
|
||||
};
|
||||
|
||||
HttpUrlQuery parse_url_query(Slice query);
|
||||
|
||||
string get_url_query_file_name(const string &query);
|
||||
|
||||
string get_url_file_name(Slice url);
|
||||
|
@ -166,6 +166,13 @@ size_t url_decode(Slice from, MutableSlice to, bool decode_plus_sign_as_space) {
|
||||
return to_i;
|
||||
}
|
||||
|
||||
string url_decode(Slice from, bool decode_plus_sign_as_space) {
|
||||
string to;
|
||||
to.resize(from.size());
|
||||
to.resize(url_decode(from, to, decode_plus_sign_as_space));
|
||||
return to;
|
||||
}
|
||||
|
||||
MutableSlice url_decode_inplace(MutableSlice str, bool decode_plus_sign_as_space) {
|
||||
size_t result_size = url_decode(str, str, decode_plus_sign_as_space);
|
||||
str.truncate(result_size);
|
||||
|
@ -263,6 +263,8 @@ string url_encode(Slice data);
|
||||
|
||||
size_t url_decode(Slice from, MutableSlice to, bool decode_plus_sign_as_space);
|
||||
|
||||
string url_decode(Slice from, bool decode_plus_sign_as_space);
|
||||
|
||||
MutableSlice url_decode_inplace(MutableSlice str, bool decode_plus_sign_as_space);
|
||||
|
||||
// run-time checked narrowing cast (type conversion):
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "td/utils/HttpUrl.h"
|
||||
#include "td/utils/tests.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
static void test_get_url_query_file_name(const char *prefix, const char *suffix, const char *file_name) {
|
||||
auto path = td::string(prefix) + td::string(file_name) + td::string(suffix);
|
||||
ASSERT_STREQ(file_name, td::get_url_query_file_name(path));
|
||||
@ -26,3 +28,24 @@ TEST(HttpUrl, get_url_query_file_name) {
|
||||
test_get_url_query_file_name("/", suffix, "\\a\\1\\2\\3\\a\\s\\a\\das");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_parse_url_query(const td::string &query, const td::string &path,
|
||||
const td::vector<std::pair<td::string, td::string>> &args) {
|
||||
for (auto hash : {"", "#", "#?t=1", "#t=1&a=b"}) {
|
||||
auto url_query = td::parse_url_query(query + hash);
|
||||
ASSERT_STREQ(path, url_query.path_);
|
||||
ASSERT_EQ(args, url_query.args_);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HttpUrl, parce_url_query) {
|
||||
test_parse_url_query("", "", {});
|
||||
test_parse_url_query("a", "a", {});
|
||||
test_parse_url_query("/a/b/c/", "/a/b/c/", {});
|
||||
test_parse_url_query("/a/b/?c/", "/a/b/", {{"c/", ""}});
|
||||
test_parse_url_query("?", "", {});
|
||||
test_parse_url_query("???", "", {{"??", ""}});
|
||||
test_parse_url_query("?a=b=c=d?e=f=g=h&x=y=z?d=3&", "", {{"a", "b=c=d?e=f=g=h"}, {"x", "y=z?d=3"}});
|
||||
test_parse_url_query("c?&&&a=b", "c", {{"a", "b"}});
|
||||
test_parse_url_query("c?&&&=b", "c", {});
|
||||
}
|
||||
|
@ -4,12 +4,11 @@
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#include "td/utils/tests.h"
|
||||
|
||||
#include "td/utils/JsonBuilder.h"
|
||||
#include "td/utils/logging.h"
|
||||
#include "td/utils/Slice.h"
|
||||
#include "td/utils/StringBuilder.h"
|
||||
#include "td/utils/tests.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user