Browse Source

Merge pull request #342 from yhirose/remove_mount_point

Fix #341
yhirose 5 years ago
parent
commit
82c11168c1
4 changed files with 91 additions and 25 deletions
  1. 26 20
      README.md
  2. 1 1
      example/simplesvr.cc
  3. 17 1
      httplib.h
  4. 47 3
      test/test.cc

+ 26 - 20
README.md

@@ -50,17 +50,21 @@ svr.listen_after_bind();
 ### Static File Server
 ### Static File Server
 
 
 ```cpp
 ```cpp
-auto ret = svr.set_base_dir("./www"); // This is same as `svr.set_base_dir("./www", "/")`;
+// Mount / to ./www directory
+auto ret = svr.set_mount_point("./www", "/");
 if (!ret) {
 if (!ret) {
   // The specified base directory doesn't exist...
   // The specified base directory doesn't exist...
 }
 }
 
 
 // Mount /public to ./www directory
 // Mount /public to ./www directory
-ret = svr.set_base_dir("./www", "/public");
+ret = svr.set_mount_point("./www", "/public");
 
 
 // Mount /public to ./www1 and ./www2 directories
 // Mount /public to ./www1 and ./www2 directories
-ret = svr.set_base_dir("./www1", "/public"); // 1st order to search
-ret = svr.set_base_dir("./www2", "/public"); // 2nd order to search
+ret = svr.set_mount_point("./www1", "/public"); // 1st order to search
+ret = svr.set_mount_point("./www2", "/public"); // 2nd order to search
+
+// Remove mount /
+ret = svr.remove_mount_point("/");
 ```
 ```
 
 
 ```cpp
 ```cpp
@@ -72,22 +76,24 @@ svr.set_file_extension_and_mimetype_mapping("hh", "text/x-h");
 
 
 The followings are built-in mappings:
 The followings are built-in mappings:
 
 
-| Extension  |     MIME Type          |
-| :--------- | :--------------------- |
-| .txt       | text/plain             |
-| .html .htm | text/html              |
-| .css       | text/css               |
-| .jpeg .jpg | image/jpg              |
-| .png       | image/png              |
-| .gif       | image/gif              |
-| .svg       | image/svg+xml          |
-| .ico       | image/x-icon           |
-| .json      | application/json       |
-| .pdf       | application/pdf        |
-| .js        | application/javascript |
-| .wasm      | application/wasm       |
-| .xml       | application/xml        |
-| .xhtml     | application/xhtml+xml  |
+| Extension |     MIME Type          |
+| :-------- | :--------------------- |
+| txt       | text/plain             |
+| html, htm | text/html              |
+| css       | text/css               |
+| jpeg, jpg | image/jpg              |
+| png       | image/png              |
+| gif       | image/gif              |
+| svg       | image/svg+xml          |
+| ico       | image/x-icon           |
+| json      | application/json       |
+| pdf       | application/pdf        |
+| js        | application/javascript |
+| wasm      | application/wasm       |
+| xml       | application/xml        |
+| xhtml     | application/xhtml+xml  |
+
+NOTE: These the static file server methods are not thread safe.
 
 
 ### Logging
 ### Logging
 
 

+ 1 - 1
example/simplesvr.cc

@@ -122,7 +122,7 @@ int main(int argc, const char **argv) {
   auto base_dir = "./";
   auto base_dir = "./";
   if (argc > 2) { base_dir = argv[2]; }
   if (argc > 2) { base_dir = argv[2]; }
 
 
-  if (!svr.set_base_dir(base_dir)) {
+  if (!svr.set_mount_point(base_dir, "/")) {
     cout << "The specified base directory doesn't exist...";
     cout << "The specified base directory doesn't exist...";
     return 1;
     return 1;
   }
   }

+ 17 - 1
httplib.h

@@ -465,7 +465,9 @@ public:
   Server &Delete(const char *pattern, Handler handler);
   Server &Delete(const char *pattern, Handler handler);
   Server &Options(const char *pattern, Handler handler);
   Server &Options(const char *pattern, Handler handler);
 
 
-  bool set_base_dir(const char *dir, const char *mount_point = nullptr);
+  [[deprecated]] bool set_base_dir(const char *dir, const char *mount_point = nullptr);
+  bool set_mount_point(const char *dir, const char *mount_point);
+  bool remove_mount_point(const char *mount_point);
   void set_file_extension_and_mimetype_mapping(const char *ext,
   void set_file_extension_and_mimetype_mapping(const char *ext,
                                                const char *mime);
                                                const char *mime);
   void set_file_request_handler(Handler handler);
   void set_file_request_handler(Handler handler);
@@ -2889,6 +2891,10 @@ inline Server &Server::Options(const char *pattern, Handler handler) {
 }
 }
 
 
 inline bool Server::set_base_dir(const char *dir, const char *mount_point) {
 inline bool Server::set_base_dir(const char *dir, const char *mount_point) {
+  return  set_mount_point(dir, mount_point);
+}
+
+inline bool Server::set_mount_point(const char *dir, const char *mount_point) {
   if (detail::is_dir(dir)) {
   if (detail::is_dir(dir)) {
     std::string mnt = mount_point ? mount_point : "/";
     std::string mnt = mount_point ? mount_point : "/";
     if (!mnt.empty() && mnt[0] == '/') {
     if (!mnt.empty() && mnt[0] == '/') {
@@ -2899,6 +2905,16 @@ inline bool Server::set_base_dir(const char *dir, const char *mount_point) {
   return false;
   return false;
 }
 }
 
 
+inline bool Server::remove_mount_point(const char *mount_point) {
+  for (auto it = base_dirs_.begin(); it != base_dirs_.end(); ++it) {
+      if (it->first == mount_point) {
+          base_dirs_.erase(it);
+          return true;
+      }
+  }
+  return false;
+}
+
 inline void Server::set_file_extension_and_mimetype_mapping(const char *ext,
 inline void Server::set_file_extension_and_mimetype_mapping(const char *ext,
                                                             const char *mime) {
                                                             const char *mime) {
   file_extension_and_mimetype_map_[ext] = mime;
   file_extension_and_mimetype_map_[ext] = mime;

+ 47 - 3
test/test.cc

@@ -662,8 +662,8 @@ protected:
   }
   }
 
 
   virtual void SetUp() {
   virtual void SetUp() {
-    svr_.set_base_dir("./www");
-    svr_.set_base_dir("./www2", "/mount");
+    svr_.set_mount_point("./www", "/");
+    svr_.set_mount_point("./www2", "/mount");
     svr_.set_file_extension_and_mimetype_mapping("abcde", "text/abcde");
     svr_.set_file_extension_and_mimetype_mapping("abcde", "text/abcde");
 
 
     svr_.Get("/hi",
     svr_.Get("/hi",
@@ -1245,7 +1245,7 @@ TEST_F(ServerTest, UserDefinedMIMETypeMapping) {
 }
 }
 
 
 TEST_F(ServerTest, InvalidBaseDirMount) {
 TEST_F(ServerTest, InvalidBaseDirMount) {
-  EXPECT_EQ(false, svr_.set_base_dir("./www3", "invalid_mount_point"));
+  EXPECT_EQ(false, svr_.set_mount_point("./www3", "invalid_mount_point"));
 }
 }
 
 
 TEST_F(ServerTest, EmptyRequest) {
 TEST_F(ServerTest, EmptyRequest) {
@@ -2069,6 +2069,50 @@ TEST(ServerStopTest, StopServerWithChunkedTransmission) {
   ASSERT_FALSE(svr.is_running());
   ASSERT_FALSE(svr.is_running());
 }
 }
 
 
+TEST(MountTest, Unmount) {
+  Server svr;
+
+  auto listen_thread = std::thread([&svr]() { svr.listen("localhost", PORT); });
+  while (!svr.is_running()) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(1));
+  }
+
+  // Give GET time to get a few messages.
+  std::this_thread::sleep_for(std::chrono::seconds(1));
+
+  Client cli("localhost", PORT);
+
+  svr.set_mount_point("./www2", "/mount2");
+
+  auto res = cli.Get("/");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(404, res->status);
+
+  res = cli.Get("/mount2/dir/test.html");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(200, res->status);
+
+  svr.set_mount_point("./www", "/");
+
+  res = cli.Get("/dir/");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(200, res->status);
+
+  svr.remove_mount_point("/");
+  res = cli.Get("/dir/");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(404, res->status);
+
+  svr.remove_mount_point("/mount2");
+  res = cli.Get("/mount2/dir/test.html");
+  ASSERT_TRUE(res != nullptr);
+  EXPECT_EQ(404, res->status);
+
+  svr.stop();
+  listen_thread.join();
+  ASSERT_FALSE(svr.is_running());
+}
+
 class ServerTestWithAI_PASSIVE : public ::testing::Test {
 class ServerTestWithAI_PASSIVE : public ::testing::Test {
 protected:
 protected:
   ServerTestWithAI_PASSIVE()
   ServerTestWithAI_PASSIVE()