diff --git a/httplib.h b/httplib.h index 96c24e3..d6d2d1b 100644 --- a/httplib.h +++ b/httplib.h @@ -13869,7 +13869,11 @@ inline bool Server::handle_file_request(Request &req, Response &res) { detail::FileStat stat(path); if (stat.is_dir()) { - res.set_redirect(req.path + "/", StatusCode::MovedPermanently_301); + // Relative, so "//dir" cannot name another host; "./" keeps a ':' + // in the name from reading as a scheme. + auto name = req.path.substr(req.path.rfind('/') + 1); + res.set_redirect("./" + encode_path_component(name) + "/", + StatusCode::MovedPermanently_301); return true; } diff --git a/test/test.cc b/test/test.cc index 663d902..d6efb50 100644 --- a/test/test.cc +++ b/test/test.cc @@ -6664,7 +6664,14 @@ TEST_F(ServerTest, GetMethodDirMountWithoutTrailingSlash) { auto res = cli_.Get("/mount/dir"); ASSERT_TRUE(res) << "Error: " << to_string(res.error()); EXPECT_EQ(StatusCode::MovedPermanently_301, res->status); - EXPECT_EQ("/mount/dir/", res->get_header_value("Location")); + EXPECT_EQ("./dir/", res->get_header_value("Location")); +} + +TEST_F(ServerTest, GetMethodDirWithLeadingDoubleSlash) { + auto res = cli_.Get("//dir"); + ASSERT_TRUE(res) << "Error: " << to_string(res.error()); + EXPECT_EQ(StatusCode::MovedPermanently_301, res->status); + EXPECT_EQ("./dir/", res->get_header_value("Location")); } TEST_F(ServerTest, PostMethod303) {