add file index to static file handler
This commit is contained in:
parent
0ac37c6ab3
commit
cab962fde0
@ -6,11 +6,14 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <zlib.h>
|
#include <zlib.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
using std::string_view;
|
using std::string_view;
|
||||||
using std::string;
|
using std::string;
|
||||||
@ -21,8 +24,31 @@ private:
|
|||||||
string url_prefix_;
|
string url_prefix_;
|
||||||
string root_path_;
|
string root_path_;
|
||||||
std::unordered_map<string, std::pair<string, std::chrono::time_point<std::chrono::file_clock>>> cache_;
|
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
|
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 {
|
string compress_gzip(const string& data) const {
|
||||||
z_stream zs;
|
z_stream zs;
|
||||||
memset(&zs, 0, sizeof(zs));
|
memset(&zs, 0, sizeof(zs));
|
||||||
@ -79,6 +105,11 @@ public:
|
|||||||
if (!url_prefix_.empty() && url_prefix_.back() != '/') {
|
if (!url_prefix_.empty() && url_prefix_.back() != '/') {
|
||||||
url_prefix_ += '/';
|
url_prefix_ += '/';
|
||||||
}
|
}
|
||||||
|
build_file_index();
|
||||||
|
}
|
||||||
|
|
||||||
|
void refresh_index() {
|
||||||
|
build_file_index();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle(const Request& req, Response& res) {
|
bool handle(const Request& req, Response& res) {
|
||||||
@ -101,19 +132,22 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string file_path = root_path_;
|
string relative_path;
|
||||||
if (file_path_part.empty() || file_path_part == "/") {
|
if (file_path_part.empty() || file_path_part == "/") {
|
||||||
file_path += "index.html";
|
relative_path = "index.html";
|
||||||
} else {
|
} else {
|
||||||
// Remove leading slash if present
|
// Remove leading slash if present
|
||||||
if (file_path_part[0] == '/') file_path_part = file_path_part.substr(1);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string file_path = root_path_ + relative_path;
|
||||||
|
|
||||||
// Get file info
|
// Get file info
|
||||||
auto last_write = fs::last_write_time(file_path);
|
auto last_write = fs::last_write_time(file_path);
|
||||||
auto file_size = fs::file_size(file_path);
|
auto file_size = fs::file_size(file_path);
|
||||||
@ -163,4 +197,4 @@ public:
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
Loading…
x
Reference in New Issue
Block a user