diff --git a/.gitignore b/.gitignore
index 1d36f897..f02f7e97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -49,3 +49,4 @@ CMakeUserPresets.json
.DS_Store
node_modules
/CMakeSettings.json
+!cmake/build.cmake
diff --git a/README.md b/README.md
index fd6cfb3e..b7bc5538 100644
--- a/README.md
+++ b/README.md
@@ -246,6 +246,20 @@ cinatra目前支持了multipart和octet-stream格式的上传。
//chunked download
//cinatra will send you the file, if the file is big file(more than 5M) the file will be downloaded by chunked. support continues download
+ 同时可以使用set_http_file_server(std::string path);函数来将cinatra转换为一个http文件下载服务器,path为该文件服务器的路径。示例如下:
+
+ #include "cinatra.hpp"
+ using namespace cinatra;
+
+ int main() {
+ http_server server(std::thread::hardware_concurrency());
+ server.set_http_file_server("http_file_server");
+ server.listen("0.0.0.0", "8080");
+ // 略
+ }
+
+ 此时访问当前服务器的`http_file_server`路径时会在浏览器展示所有可下载文件,点击即可下载。
+
## 示例6:websocket
#include "cinatra.hpp"
diff --git a/example/main.cpp b/example/main.cpp
index 87f85ad6..741497c9 100644
--- a/example/main.cpp
+++ b/example/main.cpp
@@ -242,6 +242,7 @@ int main() {
// test_ssl_server();
// test_download();
http_server server(std::thread::hardware_concurrency());
+ server.set_http_file_server("http_download_file_server");
bool r = server.listen("0.0.0.0", "8090");
if (!r) {
// LOG_INFO << "listen failed";
diff --git a/include/cinatra/http_server.hpp b/include/cinatra/http_server.hpp
index ce9ea845..35b50429 100644
--- a/include/cinatra/http_server.hpp
+++ b/include/cinatra/http_server.hpp
@@ -174,6 +174,10 @@ class http_server_ : private noncopyable {
set_file_dir(std::move(path), upload_dir_);
}
+ void set_http_file_server(std::string path) {
+ download_display_file_dir_ = path;
+ }
+
const std::string &static_dir() const { return static_dir_; }
// xM
@@ -346,6 +350,16 @@ class http_server_ : private noncopyable {
}
}
+ if (!download_display_file_dir_.empty()) {
+ std::string ret = "";
+ bool is_need_download_lists_response =
+ build_http_download_lists_response(req, std::move(ret));
+ if (is_need_download_lists_response) {
+ res.set_status_and_content(status_type::ok, std::move(ret));
+ return;
+ }
+ }
+
auto state = req.get_state();
switch (state) {
case cinatra::data_proc_state::data_begin: {
@@ -587,6 +601,35 @@ class http_server_ : private noncopyable {
}
}
+ bool build_http_download_lists_response(request &req,
+ std::string &&resp_str) {
+ std::string res_str = "";
+ std::string href_of_head = "
";
+ if (req.get_res_path() == download_display_file_dir_) {
+ std::string file_dir_str = static_dir_;
+ std::filesystem::path dir_path(file_dir_str);
+
+ for (const auto &entry : std::filesystem::directory_iterator(dir_path)) {
+ if (!entry.is_directory()) {
+ auto u8_file_name = entry.path().filename().u8string();
+ std::string file_name_str(u8_file_name.begin(), u8_file_name.end());
+ std::string full_href = href_of_head + file_name_str + href_of_tail +
+ file_name_str + "";
+ res_str += full_href;
+ }
+ }
+ std::string ret =
+ download_dir_response_head_ + res_str + download_dir_response_tail_;
+ resp_str = std::move(ret);
+ return true;
+ }
+ else {
+ return false;
+ }
+ }
+
service_pool_policy io_service_pool_;
std::size_t max_req_buf_size_ =
@@ -596,6 +639,7 @@ class http_server_ : private noncopyable {
http_router http_router_;
std::string static_dir_ = fs::absolute("www").string(); // default
std::string upload_dir_ = fs::absolute("www").string(); // default
+ std::string download_display_file_dir_ = "";
std::time_t static_res_cache_max_age_ = 0;
bool enable_timeout_ = true;
@@ -620,6 +664,15 @@ class http_server_ : private noncopyable {
uint64_t conn_id_ = 0;
std::unordered_map>> conns_;
std::mutex conns_mtx_;
+
+ std::string download_dir_response_head_ =
+ ""
+ "http file download "
+ "server"
+ "";
+ std::string download_dir_response_tail_ =
+ ""
+ "";
};
template
diff --git a/lang/english/README.md b/lang/english/README.md
index dc2146a0..744f830a 100644
--- a/lang/english/README.md
+++ b/lang/english/README.md
@@ -248,6 +248,22 @@ http://127.0.0.1:8080/purecpp/static/show.jpg
//cinatra will send you the file, if the file is big file(more than 5M) the file will be downloaded by chunked. support continues download
```
+At the same time, you can use the `set_http_file_server(std::string path);` function to build an http file download server. The parameter path is the path of all downloadable files. Examples are as follows:
+
+```cpp
+#include "cinatra.hpp"
+using namespace cinatra;
+
+int main() {
+ http_server server(std::thread::hardware_concurrency());
+ server.set_http_file_server("http_file_server");
+ server.listen("0.0.0.0", "8080");
+ // ......
+}
+```
+
+In this time, when accessing the `http_file_server` path of the current server, all downloadable files will be displayed in the browser, and you can download them by clicking on them.
+
### Example 6: WebSocket
```cpp