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
|
@ -1991,6 +1991,10 @@ std::string trim_copy(const std::string &s);
|
|||
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);
|
||||
|
||||
|
||||
bool process_client_socket(socket_t sock, time_t read_timeout_sec,
|
||||
time_t read_timeout_usec, time_t write_timeout_sec,
|
||||
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,
|
||||
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 beg = 0;
|
||||
size_t count = 1;
|
||||
|
||||
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);
|
||||
if (r.first < r.second) { fn(&b[r.first], &b[r.second]); }
|
||||
beg = i + 1;
|
||||
count++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -5804,7 +5815,7 @@ inline bool Server::parse_request_line(const char *s, Request &req) const {
|
|||
|
||||
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) {
|
||||
switch (count) {
|
||||
case 0:
|
||||
|
|
13
test/test.cc
13
test/test.cc
|
@ -1847,6 +1847,11 @@ protected:
|
|||
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",
|
||||
[&](const Request & /*req*/, Response &res) {
|
||||
res.set_content("abcdefg", "text/plain");
|
||||
|
@ -3352,6 +3357,14 @@ TEST_F(ServerTest, GetStreamedChunkedWithGzip2) {
|
|||
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) {
|
||||
std::string data;
|
||||
for (size_t i = 0; i < 32 * 1024; ++i) {
|
||||
|
|
Loading…
Reference in a new issue