From cab962fde0bed98aa69a7fd7a457dcdd348c2262 Mon Sep 17 00:00:00 2001 From: Sky Johnson Date: Sat, 14 Jun 2025 18:58:31 -0500 Subject: [PATCH] add file index to static file handler --- static_file_handler.hpp | 44 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/static_file_handler.hpp b/static_file_handler.hpp index 0ab95ec..d7bbe7f 100644 --- a/static_file_handler.hpp +++ b/static_file_handler.hpp @@ -6,11 +6,14 @@ #include #include #include +#include #include #include #include +#include #include #include +#include using std::string_view; using std::string; @@ -21,8 +24,31 @@ private: string url_prefix_; string root_path_; std::unordered_map>> cache_; + std::unordered_set 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; } -}; +}; \ No newline at end of file