mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-15 10:39:37 +00:00
match mount points on a segment boundary in handle_file_request (#2529)
This commit is contained in:
1 parent
095a5c1caf
commit
2b8658fa99
2 files changed
+41
-2
No files matched your search
@@ -12448,8 +12448,14 @@ inline bool Server::read_content_core(
|
|||||||
|
|
||||||
inline bool Server::handle_file_request(Request &req, Response &res) {
|
inline bool Server::handle_file_request(Request &req, Response &res) {
|
||||||
for (const auto &entry : base_dirs_) {
|
for (const auto &entry : base_dirs_) {
|
||||||
// Prefix match
|
// Prefix match, on a path segment boundary. A mount point of "/mount"
|
||||||
if (!req.path.compare(0, entry.mount_point.size(), entry.mount_point)) {
|
// covers "/mount" and "/mount/...", but must not swallow "/mountdir/...".
|
||||||
|
// One that already ends in '/' (the root mount among them) carries its own
|
||||||
|
// boundary; set_mount_point() guarantees the mount point is not empty.
|
||||||
|
if (!req.path.compare(0, entry.mount_point.size(), entry.mount_point) &&
|
||||||
|
(entry.mount_point.back() == '/' ||
|
||||||
|
req.path.size() == entry.mount_point.size() ||
|
||||||
|
req.path[entry.mount_point.size()] == '/')) {
|
||||||
std::string sub_path = "/" + req.path.substr(entry.mount_point.size());
|
std::string sub_path = "/" + req.path.substr(entry.mount_point.size());
|
||||||
if (detail::is_valid_path(sub_path)) {
|
if (detail::is_valid_path(sub_path)) {
|
||||||
auto path = entry.base_dir + sub_path;
|
auto path = entry.base_dir + sub_path;
|
||||||
|
|||||||
@@ -9635,6 +9635,39 @@ TEST(MountTest, Unmount) {
|
|||||||
EXPECT_EQ(StatusCode::NotFound_404, res->status);
|
EXPECT_EQ(StatusCode::NotFound_404, res->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(MountTest, PathSegmentBoundary) {
|
||||||
|
Server svr;
|
||||||
|
|
||||||
|
svr.set_mount_point("/mount2", "./www2");
|
||||||
|
svr.set_mount_point("/", "./www");
|
||||||
|
|
||||||
|
auto port = svr.bind_to_any_port(HOST);
|
||||||
|
auto listen_thread = std::thread([&svr]() { svr.listen_after_bind(); });
|
||||||
|
auto se = detail::scope_exit([&] {
|
||||||
|
svr.stop();
|
||||||
|
listen_thread.join();
|
||||||
|
ASSERT_FALSE(svr.is_running());
|
||||||
|
});
|
||||||
|
|
||||||
|
svr.wait_until_ready();
|
||||||
|
|
||||||
|
Client cli(HOST, port);
|
||||||
|
|
||||||
|
auto res = cli.Get("/mount2/dir/test.html");
|
||||||
|
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
|
||||||
|
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||||
|
|
||||||
|
// "/mount2" must not match part-way through a path segment.
|
||||||
|
res = cli.Get("/mount2dir/test.html");
|
||||||
|
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
|
||||||
|
EXPECT_EQ(StatusCode::NotFound_404, res->status);
|
||||||
|
|
||||||
|
// A mount point ending in '/' keeps matching every path below it.
|
||||||
|
res = cli.Get("/dir/test.html");
|
||||||
|
ASSERT_TRUE(res) << "Error: " << to_string(res.error());
|
||||||
|
EXPECT_EQ(StatusCode::OK_200, res->status);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(MountTest, Redicect) {
|
TEST(MountTest, Redicect) {
|
||||||
Server svr;
|
Server svr;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user