mirror of
https://github.com/typesense/typesense.git
synced 2025-05-17 20:22:32 +08:00
Proper error in API response when GET query > 4K chars.
This commit is contained in:
parent
e93971a747
commit
ba91e69c04
@ -309,7 +309,7 @@ struct StringUtils {
|
||||
return str.rfind(prefix, 0) == 0;
|
||||
}
|
||||
|
||||
static std::map<std::string, std::string> parse_query_string(const std::string& query);
|
||||
static void parse_query_string(const std::string& query, std::map<std::string, std::string>& query_map);
|
||||
|
||||
static std::string float_to_str(float value);
|
||||
|
||||
|
@ -326,8 +326,15 @@ int HttpServer::catch_all_handler(h2o_handler_t *_h2o_handler, h2o_req_t *req) {
|
||||
h2o_iovec_init(req->path.base + req->query_at, req->path.len - req->query_at) :
|
||||
h2o_iovec_init(H2O_STRLIT(""));
|
||||
|
||||
if(query.len > 4000) {
|
||||
nlohmann::json resp;
|
||||
resp["message"] = "Query string exceeds max allowed length of 4000. Use the /multi_search end-point for larger payloads.";
|
||||
return send_response(req, 400, resp.dump());
|
||||
}
|
||||
|
||||
std::string query_str(query.base, query.len);
|
||||
std::map<std::string, std::string> query_map = StringUtils::parse_query_string(query_str);
|
||||
std::map<std::string, std::string> query_map;
|
||||
StringUtils::parse_query_string(query_str, query_map);
|
||||
|
||||
// Extract auth key from header. If that does not exist, look for a GET parameter.
|
||||
std::string api_auth_key_sent = "";
|
||||
|
@ -80,13 +80,7 @@ std::string StringUtils::hash_sha256(const std::string& str) {
|
||||
return StringUtils::str2hex(std::string(reinterpret_cast<char*>(hash_buf), SHA256_SIZE));
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> StringUtils::parse_query_string(const std::string &query) {
|
||||
if(query.size() > 4000) {
|
||||
LOG(ERROR) << "Query string exceeds max allowed length of 4000. Actual length: " << query.size();
|
||||
return {};
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> query_map;
|
||||
void StringUtils::parse_query_string(const std::string& query, std::map<std::string, std::string>& query_map) {
|
||||
std::string key_value;
|
||||
|
||||
int query_len = int(query.size());
|
||||
@ -145,8 +139,6 @@ std::map<std::string, std::string> StringUtils::parse_query_string(const std::st
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return query_map;
|
||||
}
|
||||
|
||||
void StringUtils::split_to_values(const std::string& vals_str, std::vector<std::string>& filter_values) {
|
||||
|
@ -102,120 +102,138 @@ TEST(StringUtilsTest, ShouldComputeSHA256) {
|
||||
}
|
||||
|
||||
TEST(StringUtilsTest, ShouldParseQueryString) {
|
||||
std::map<std::string, std::string> qmap;
|
||||
|
||||
std::string qs = "?q=bar&filter_by=points: >100 && points: <200";
|
||||
auto qmap = StringUtils::parse_query_string(qs);
|
||||
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("points: >100 && points: <200", qmap["filter_by"]);
|
||||
|
||||
qs = "?q=bar&filter_by=points%3A%20%3E100%20%26%26%20points%3A%20%3C200";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("points: >100 && points: <200", qmap["filter_by"]);
|
||||
|
||||
qs = "?q=bar&filter_by=points%3A%20%3E100%20%26%26%20points%3A%20%3C200&";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("points: >100 && points: <200", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bar&filter_by=baz&&";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("baz&", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bar&filter_by=";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bread && breakfast&filter_by=";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bread && breakfast", qmap["q"]);
|
||||
ASSERT_EQ("", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bread & breakfast&filter_by=";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(3, qmap.size());
|
||||
ASSERT_EQ("bread ", qmap["q"]);
|
||||
ASSERT_EQ("", qmap[" breakfast"]);
|
||||
ASSERT_EQ("", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bar&filter_by=&";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("", qmap["filter_by"]);
|
||||
|
||||
qs = "q=bar&filter_by=points :> 100&enable_typos";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(3, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["q"]);
|
||||
ASSERT_EQ("points :> 100", qmap["filter_by"]);
|
||||
ASSERT_EQ("", qmap["enable_typos"]);
|
||||
|
||||
qs = "foo=" + StringUtils::randstring(4000);
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
ASSERT_EQ(0, qmap.size());
|
||||
|
||||
qs = "foo=bar&baz=&bazinga=true";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(3, qmap.size());
|
||||
ASSERT_EQ("bar", qmap["foo"]);
|
||||
ASSERT_EQ("", qmap["baz"]);
|
||||
ASSERT_EQ("true", qmap["bazinga"]);
|
||||
|
||||
qs = "foo=bar&bazinga=true&foo=buzz";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("buzz", qmap["foo"]);
|
||||
ASSERT_EQ("true", qmap["bazinga"]);
|
||||
|
||||
qs = "filter_by=points:>100&bazinga=true&filter_by=points:<=200";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("points:>100&&points:<=200", qmap["filter_by"]);
|
||||
ASSERT_EQ("true", qmap["bazinga"]);
|
||||
|
||||
qs = "filter_by=points:>100 && brand:= nike&bazinga=true&filter_by=points:<=200";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(2, qmap.size());
|
||||
ASSERT_EQ("points:>100 && brand:= nike&&points:<=200", qmap["filter_by"]);
|
||||
ASSERT_EQ("true", qmap["bazinga"]);
|
||||
|
||||
qs = "foo";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(1, qmap.size());
|
||||
ASSERT_EQ("", qmap["foo"]);
|
||||
|
||||
qs = "?foo=";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(1, qmap.size());
|
||||
ASSERT_EQ("", qmap["foo"]);
|
||||
|
||||
qs = "?foo";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(1, qmap.size());
|
||||
ASSERT_EQ("", qmap["foo"]);
|
||||
|
||||
qs = "?";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(0, qmap.size());
|
||||
|
||||
qs = "";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(0, qmap.size());
|
||||
|
||||
qs = "&";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(0, qmap.size());
|
||||
|
||||
qs = "&&";
|
||||
qmap = StringUtils::parse_query_string(qs);
|
||||
qmap.clear();
|
||||
StringUtils::parse_query_string(qs, qmap);
|
||||
ASSERT_EQ(0, qmap.size());
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user