add file index to static file handler
This commit is contained in:
parent
0ac37c6ab3
commit
cab962fde0
@ -6,11 +6,14 @@
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <chrono>
|
||||
#include <shared_mutex>
|
||||
#include <zlib.h>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
|
||||
using std::string_view;
|
||||
using std::string;
|
||||
@ -21,8 +24,31 @@ private:
|
||||
string url_prefix_;
|
||||
string root_path_;
|
||||
std::unordered_map<string, std::pair<string, std::chrono::time_point<std::chrono::file_clock>>> cache_;
|
||||
std::unordered_set<string> file_index_;
|
||||
mutable std::shared_mutex index_mutex_;
|
||||
size_t max_cache_size_ = 50 * 1024 * 1024; // 50MB cache limit
|
||||
|
||||
void build_file_index() {
|
||||
std::unique_lock lock(index_mutex_);
|
||||
file_index_.clear();
|
||||
|
||||
if (!fs::exists(root_path_) || !fs::is_directory(root_path_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& entry : fs::recursive_directory_iterator(root_path_)) {
|
||||
if (entry.is_regular_file()) {
|
||||
auto rel_path = fs::relative(entry.path(), root_path_);
|
||||
file_index_.insert(rel_path.string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool file_exists_fast(const string& relative_path) const {
|
||||
std::shared_lock lock(index_mutex_);
|
||||
return file_index_.count(relative_path) > 0;
|
||||
}
|
||||
|
||||
string compress_gzip(const string& data) const {
|
||||
z_stream zs;
|
||||
memset(&zs, 0, sizeof(zs));
|
||||
@ -79,6 +105,11 @@ public:
|
||||
if (!url_prefix_.empty() && url_prefix_.back() != '/') {
|
||||
url_prefix_ += '/';
|
||||
}
|
||||
build_file_index();
|
||||
}
|
||||
|
||||
void refresh_index() {
|
||||
build_file_index();
|
||||
}
|
||||
|
||||
bool handle(const Request& req, Response& res) {
|
||||
@ -101,19 +132,22 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
string file_path = root_path_;
|
||||
string relative_path;
|
||||
if (file_path_part.empty() || file_path_part == "/") {
|
||||
file_path += "index.html";
|
||||
relative_path = "index.html";
|
||||
} else {
|
||||
// Remove leading slash if present
|
||||
if (file_path_part[0] == '/') file_path_part = file_path_part.substr(1);
|
||||
file_path += string(file_path_part);
|
||||
relative_path = string(file_path_part);
|
||||
}
|
||||
|
||||
if (!fs::exists(file_path) || !fs::is_regular_file(file_path)) {
|
||||
// Fast file existence check
|
||||
if (!file_exists_fast(relative_path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
string file_path = root_path_ + relative_path;
|
||||
|
||||
// Get file info
|
||||
auto last_write = fs::last_write_time(file_path);
|
||||
auto file_size = fs::file_size(file_path);
|
||||
@ -163,4 +197,4 @@ public:
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user