yhirose 1 year ago
parent
commit
3f2922b3fa
2 changed files with 27 additions and 16 deletions
  1. 21 12
      httplib.h
  2. 6 4
      test/test.cc

+ 21 - 12
httplib.h

@@ -2253,9 +2253,15 @@ make_basic_authentication_header(const std::string &username,
 
 namespace detail {
 
-bool is_file(const std::string &path);
+struct FileStat {
+  FileStat(const std::string &path);
+  bool is_file() const;
+  bool is_dir() const;
 
-bool is_dir(const std::string &path);
+private:
+  struct stat st_;
+  int ret_ = -1;
+};
 
 std::string encode_query_param(const std::string &value);
 
@@ -2626,14 +2632,14 @@ inline bool is_valid_path(const std::string &path) {
   return true;
 }
 
-inline bool is_file(const std::string &path) {
-  struct stat st;
-  return stat(path.c_str(), &st) >= 0 && S_ISREG(st.st_mode);
+inline FileStat::FileStat(const std::string &path) {
+  ret_ = stat(path.c_str(), &st_);
 }
-
-inline bool is_dir(const std::string &path) {
-  struct stat st;
-  return stat(path.c_str(), &st) >= 0 && S_ISDIR(st.st_mode);
+inline bool FileStat::is_file() const {
+  return ret_ >= 0 && S_ISREG(st_.st_mode);
+}
+inline bool FileStat::is_dir() const {
+  return ret_ >= 0 && S_ISDIR(st_.st_mode);
 }
 
 inline std::string encode_query_param(const std::string &value) {
@@ -6085,7 +6091,8 @@ inline bool Server::set_base_dir(const std::string &dir,
 
 inline bool Server::set_mount_point(const std::string &mount_point,
                                     const std::string &dir, Headers headers) {
-  if (detail::is_dir(dir)) {
+  detail::FileStat stat(dir);
+  if (stat.is_dir()) {
     std::string mnt = !mount_point.empty() ? mount_point : "/";
     if (!mnt.empty() && mnt[0] == '/') {
       base_dirs_.push_back({mnt, dir, std::move(headers)});
@@ -6569,12 +6576,14 @@ inline bool Server::handle_file_request(const Request &req, Response &res,
         auto path = entry.base_dir + sub_path;
         if (path.back() == '/') { path += "index.html"; }
 
-        if (detail::is_dir(path)) {
+        detail::FileStat stat(path);
+
+        if (stat.is_dir()) {
           res.set_redirect(sub_path + "/", StatusCode::MovedPermanently_301);
           return true;
         }
 
-        if (detail::is_file(path)) {
+        if (stat.is_file()) {
           for (const auto &kv : entry.headers) {
             res.set_header(kv.first, kv.second);
           }

+ 6 - 4
test/test.cc

@@ -7676,11 +7676,13 @@ TEST(FileSystemTest, FileAndDirExistenceCheck) {
   auto file_path = "./www/dir/index.html";
   auto dir_path = "./www/dir";
 
-  EXPECT_TRUE(detail::is_file(file_path));
-  EXPECT_FALSE(detail::is_dir(file_path));
+  detail::FileStat stat_file(file_path);
+  EXPECT_TRUE(stat_file.is_file());
+  EXPECT_FALSE(stat_file.is_dir());
 
-  EXPECT_FALSE(detail::is_file(dir_path));
-  EXPECT_TRUE(detail::is_dir(dir_path));
+  detail::FileStat stat_dir(dir_path);
+  EXPECT_FALSE(stat_dir.is_file());
+  EXPECT_TRUE(stat_dir.is_dir());
 }
 
 TEST(DirtyDataRequestTest, HeadFieldValueContains_CR_LF_NUL) {