Only match path params that span full path segment (#1919)
* Only match path params that span full path segment * Fix C++11 build
This commit is contained in:
parent
2480c0342c
commit
80fb03628b
12
httplib.h
12
httplib.h
@ -840,7 +840,6 @@ public:
|
|||||||
bool match(Request &request) const override;
|
bool match(Request &request) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr char marker = ':';
|
|
||||||
// Treat segment separators as the end of path parameter capture
|
// Treat segment separators as the end of path parameter capture
|
||||||
// Does not need to handle query parameters as they are parsed before path
|
// Does not need to handle query parameters as they are parsed before path
|
||||||
// matching
|
// matching
|
||||||
@ -5887,6 +5886,8 @@ inline socket_t BufferStream::socket() const { return 0; }
|
|||||||
inline const std::string &BufferStream::get_buffer() const { return buffer; }
|
inline const std::string &BufferStream::get_buffer() const { return buffer; }
|
||||||
|
|
||||||
inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {
|
inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {
|
||||||
|
static constexpr char marker[] = "/:";
|
||||||
|
|
||||||
// One past the last ending position of a path param substring
|
// One past the last ending position of a path param substring
|
||||||
std::size_t last_param_end = 0;
|
std::size_t last_param_end = 0;
|
||||||
|
|
||||||
@ -5899,13 +5900,14 @@ inline PathParamsMatcher::PathParamsMatcher(const std::string &pattern) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
const auto marker_pos = pattern.find(marker, last_param_end);
|
const auto marker_pos = pattern.find(
|
||||||
|
marker, last_param_end == 0 ? last_param_end : last_param_end - 1);
|
||||||
if (marker_pos == std::string::npos) { break; }
|
if (marker_pos == std::string::npos) { break; }
|
||||||
|
|
||||||
static_fragments_.push_back(
|
static_fragments_.push_back(
|
||||||
pattern.substr(last_param_end, marker_pos - last_param_end));
|
pattern.substr(last_param_end, marker_pos - last_param_end + 1));
|
||||||
|
|
||||||
const auto param_name_start = marker_pos + 1;
|
const auto param_name_start = marker_pos + 2;
|
||||||
|
|
||||||
auto sep_pos = pattern.find(separator, param_name_start);
|
auto sep_pos = pattern.find(separator, param_name_start);
|
||||||
if (sep_pos == std::string::npos) { sep_pos = pattern.length(); }
|
if (sep_pos == std::string::npos) { sep_pos = pattern.length(); }
|
||||||
@ -5967,7 +5969,7 @@ inline bool PathParamsMatcher::match(Request &request) const {
|
|||||||
request.path_params.emplace(
|
request.path_params.emplace(
|
||||||
param_name, request.path.substr(starting_pos, sep_pos - starting_pos));
|
param_name, request.path.substr(starting_pos, sep_pos - starting_pos));
|
||||||
|
|
||||||
// Mark everythin up to '/' as matched
|
// Mark everything up to '/' as matched
|
||||||
starting_pos = sep_pos + 1;
|
starting_pos = sep_pos + 1;
|
||||||
}
|
}
|
||||||
// Returns false if the path is longer than the pattern
|
// Returns false if the path is longer than the pattern
|
||||||
|
12
test/test.cc
12
test/test.cc
@ -7599,6 +7599,18 @@ TEST(PathParamsTest, SequenceOfParams) {
|
|||||||
EXPECT_EQ(request.path_params, expected_params);
|
EXPECT_EQ(request.path_params, expected_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(PathParamsTest, SemicolonInTheMiddleIsNotAParam) {
|
||||||
|
const auto pattern = "/prefix:suffix";
|
||||||
|
detail::PathParamsMatcher matcher(pattern);
|
||||||
|
|
||||||
|
Request request;
|
||||||
|
request.path = "/prefix:suffix";
|
||||||
|
ASSERT_TRUE(matcher.match(request));
|
||||||
|
|
||||||
|
const std::unordered_map<std::string, std::string> expected_params = {};
|
||||||
|
EXPECT_EQ(request.path_params, expected_params);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(UniversalClientImplTest, Ipv6LiteralAddress) {
|
TEST(UniversalClientImplTest, Ipv6LiteralAddress) {
|
||||||
// If ipv6 regex working, regex match codepath is taken.
|
// If ipv6 regex working, regex match codepath is taken.
|
||||||
// else port will default to 80 in Client impl
|
// else port will default to 80 in Client impl
|
||||||
|
Loading…
x
Reference in New Issue
Block a user