mirror of
https://github.com/yhirose/cpp-httplib
synced 2024-11-21 14:29:10 -07:00
Fix: Query parameter including query delimiter ('?') not being parsed properly (#1713)
* Fix: Query parameter including query delimiter ('?') not being parsed properly * Add details::split function with and without m argument to allow split parameters with/without counter * Revert changes in SplitTest.ParseQueryString
This commit is contained in:
parent
f14accb7b6
commit
e426a38c3e
2 changed files with 26 additions and 2 deletions
15
httplib.h
15
httplib.h
|
@ -1989,8 +1989,12 @@ void read_file(const std::string &path, std::string &out);
|
||||||
std::string trim_copy(const std::string &s);
|
std::string trim_copy(const std::string &s);
|
||||||
|
|
||||||
void split(const char *b, const char *e, char d,
|
void split(const char *b, const char *e, char d,
|
||||||
|
std::function<void(const char *, const char *)> fn);
|
||||||
|
|
||||||
|
void split(const char *b, const char *e, char d, size_t m,
|
||||||
std::function<void(const char *, const char *)> fn);
|
std::function<void(const char *, const char *)> fn);
|
||||||
|
|
||||||
|
|
||||||
bool process_client_socket(socket_t sock, time_t read_timeout_sec,
|
bool process_client_socket(socket_t sock, time_t read_timeout_sec,
|
||||||
time_t read_timeout_usec, time_t write_timeout_sec,
|
time_t read_timeout_usec, time_t write_timeout_sec,
|
||||||
time_t write_timeout_usec,
|
time_t write_timeout_usec,
|
||||||
|
@ -2473,14 +2477,21 @@ inline std::string trim_double_quotes_copy(const std::string &s) {
|
||||||
|
|
||||||
inline void split(const char *b, const char *e, char d,
|
inline void split(const char *b, const char *e, char d,
|
||||||
std::function<void(const char *, const char *)> fn) {
|
std::function<void(const char *, const char *)> fn) {
|
||||||
|
return split(b, e, d, std::numeric_limits<size_t>::max(), fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void split(const char *b, const char *e, char d, size_t m,
|
||||||
|
std::function<void(const char *, const char *)> fn) {
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
size_t beg = 0;
|
size_t beg = 0;
|
||||||
|
size_t count = 1;
|
||||||
|
|
||||||
while (e ? (b + i < e) : (b[i] != '\0')) {
|
while (e ? (b + i < e) : (b[i] != '\0')) {
|
||||||
if (b[i] == d) {
|
if (b[i] == d && count < m) {
|
||||||
auto r = trim(b, e, beg, i);
|
auto r = trim(b, e, beg, i);
|
||||||
if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
|
if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
|
||||||
beg = i + 1;
|
beg = i + 1;
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -5804,7 +5815,7 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
|
||||||
|
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
detail::split(req.target.data(), req.target.data() + req.target.size(), '?',
|
detail::split(req.target.data(), req.target.data() + req.target.size(), '?', 2,
|
||||||
[&](const char *b, const char *e) {
|
[&](const char *b, const char *e) {
|
||||||
switch (count) {
|
switch (count) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
13
test/test.cc
13
test/test.cc
|
@ -1847,6 +1847,11 @@ protected:
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
.Get("/regex-with-delimiter",
|
||||||
|
[&](const Request & req, Response &res) {
|
||||||
|
ASSERT_TRUE(req.has_param("key"));
|
||||||
|
EXPECT_EQ("^(?.*(value))", req.get_param_value("key"));
|
||||||
|
})
|
||||||
.Get("/with-range",
|
.Get("/with-range",
|
||||||
[&](const Request & /*req*/, Response &res) {
|
[&](const Request & /*req*/, Response &res) {
|
||||||
res.set_content("abcdefg", "text/plain");
|
res.set_content("abcdefg", "text/plain");
|
||||||
|
@ -3352,6 +3357,14 @@ TEST_F(ServerTest, GetStreamedChunkedWithGzip2) {
|
||||||
EXPECT_EQ(std::string("123456789"), res->body);
|
EXPECT_EQ(std::string("123456789"), res->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_F(ServerTest, SplitDelimiterInPathRegex) {
|
||||||
|
auto res = cli_.Get("/regex-with-delimiter?key=^(?.*(value))");
|
||||||
|
ASSERT_TRUE(res);
|
||||||
|
EXPECT_EQ(200, res->status);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST(GzipDecompressor, ChunkedDecompression) {
|
TEST(GzipDecompressor, ChunkedDecompression) {
|
||||||
std::string data;
|
std::string data;
|
||||||
for (size_t i = 0; i < 32 * 1024; ++i) {
|
for (size_t i = 0; i < 32 * 1024; ++i) {
|
||||||
|
|
Loading…
Reference in a new issue