Merge pull request #342 from yhirose/remove_mount_point

Fix #341
This commit is contained in:
yhirose 2020-01-31 20:41:39 -05:00 committed by GitHub
commit 82c11168c1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 25 deletions

View File

@ -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_mount_point("./www1", "/public"); // 1st order to search
ret = svr.set_base_dir("./www2", "/public"); // 2nd order to search ret = svr.set_mount_point("./www2", "/public"); // 2nd order to search
// Remove mount /
ret = svr.remove_mount_point("/");
``` ```
```cpp ```cpp
@ -73,21 +77,23 @@ 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 | | Extension | MIME Type |
| :--------- | :--------------------- | | :-------- | :--------------------- |
| .txt | text/plain | | txt | text/plain |
| .html .htm | text/html | | html, htm | text/html |
| .css | text/css | | css | text/css |
| .jpeg .jpg | image/jpg | | jpeg, jpg | image/jpg |
| .png | image/png | | png | image/png |
| .gif | image/gif | | gif | image/gif |
| .svg | image/svg+xml | | svg | image/svg+xml |
| .ico | image/x-icon | | ico | image/x-icon |
| .json | application/json | | json | application/json |
| .pdf | application/pdf | | pdf | application/pdf |
| .js | application/javascript | | js | application/javascript |
| .wasm | application/wasm | | wasm | application/wasm |
| .xml | application/xml | | xml | application/xml |
| .xhtml | application/xhtml+xml | | xhtml | application/xhtml+xml |
NOTE: These the static file server methods are not thread safe.
### Logging ### Logging

View File

@ -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;
} }

View File

@ -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;

View File

@ -662,8 +662,8 @@ protected:
} }
virtual void SetUp() { virtual void SetUp() {
svr_.set_base_dir("./www"); svr_.set_mount_point("./www", "/");
svr_.set_base_dir("./www2", "/mount"); 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()