Completely removed the cached path api from FileCache.

This commit is contained in:
Relintai 2023-12-22 19:37:23 +01:00
parent ca9249b5cf
commit cd34883d79
5 changed files with 48 additions and 261 deletions

View File

@ -37,13 +37,6 @@
#include "core/os/os.h" #include "core/os/os.h"
#include "core/string/print_string.h" #include "core/string/print_string.h"
FileCache::PathCacheMode FileCache::get_path_cache_mode() const {
return _path_cache_mode;
}
void FileCache::set_path_cache_mode(const PathCacheMode p_mode) {
_path_cache_mode = p_mode;
}
String FileCache::get_wwwroot() { String FileCache::get_wwwroot() {
return _wwwroot_orig; return _wwwroot_orig;
} }
@ -69,6 +62,40 @@ void FileCache::set_cache_invalidation_time(const int &val) {
cache_invalidation_time = static_cast<uint64_t>(val); cache_invalidation_time = static_cast<uint64_t>(val);
} }
bool FileCache::wwwroot_has_file(const String &file_path) {
if (file_path.empty() || file_path == "/") {
return false;
}
String fp = _wwwroot_abs + file_path;
if (!FileAccess::exists(fp)) {
return false;
}
Error err;
FileAccess *f = FileAccess::open(fp, FileAccess::READ, &err);
if (!f) {
return false;
}
if (err != OK) {
memdelete(f);
return false;
}
String absp = f->get_path_absolute();
memdelete(f);
//likely a directory walking attempt. e.g. ../../../../../etc/passwd
if (!absp.begins_with(_wwwroot_abs)) {
return false;
}
return true;
}
String FileCache::wwwroot_get_file_abspath(const String &file_path) { String FileCache::wwwroot_get_file_abspath(const String &file_path) {
if (file_path.empty() || file_path == "/") { if (file_path.empty() || file_path == "/") {
return String(); return String();
@ -103,173 +130,6 @@ String FileCache::wwwroot_get_file_abspath(const String &file_path) {
return absp; return absp;
} }
void FileCache::wwwroot_register_file(const String &file_path) {
_cache_lock.write_lock();
RegisteredFileEntry e;
e.orig_path = file_path;
e.lowercase_path = file_path.to_lower();
_registered_files.push_back(e);
_cache_lock.write_unlock();
}
void FileCache::wwwroot_deregister_file(const String &file_path) {
_cache_lock.write_lock();
for (int i = 0; i < _registered_files.size(); ++i) {
const RegisteredFileEntry &e = _registered_files[i];
if (file_path == e.orig_path) {
_registered_files.remove(i);
_cache_lock.write_unlock();
return;
}
}
_cache_lock.write_unlock();
}
bool FileCache::wwwroot_has_file(const String &file_path) {
//return registered_files.has(file_path);
if (_path_cache_mode == PATH_CACHE_MODE_OFF) {
String absp = DirAccess::get_filesystem_abspath_for(_wwwroot + file_path);
//likely a directory walking attempt. e.g. ../../../../../etc/passwd
if (!absp.begins_with(_wwwroot_abs)) {
return false;
}
return FileAccess::exists(absp);
} else if (_path_cache_mode == PATH_CACHE_MODE_STATIC) {
_cache_lock.read_lock();
for (int i = 0; i < _registered_files.size(); ++i) {
const RegisteredFileEntry &e = _registered_files[i];
if (file_path == e.lowercase_path) {
_cache_lock.read_unlock();
return true;
}
}
_cache_lock.read_unlock();
}
return false;
}
int FileCache::wwwroot_get_file_index(const String &file_path) {
_cache_lock.read_lock();
for (int i = 0; i < _registered_files.size(); ++i) {
const RegisteredFileEntry &e = _registered_files[i];
if (file_path == e.lowercase_path) {
_cache_lock.read_unlock();
return i;
}
}
_cache_lock.read_unlock();
if (_path_cache_mode == PATH_CACHE_MODE_OFF) {
String np = _wwwroot;
np.append_path(file_path);
String absp = DirAccess::get_filesystem_abspath_for(np);
//likely a directory walking attempt. e.g. ../../../../../etc/passwd
if (!absp.begins_with(_wwwroot_abs)) {
return -1;
}
if (!FileAccess::exists(absp)) {
return -1;
}
RegisteredFileEntry e;
e.orig_path = file_path;
e.lowercase_path = file_path.to_lower();
_cache_lock.write_lock();
_registered_files.push_back(e);
int s = _registered_files.size() - 1;
_cache_lock.write_unlock();
return s;
}
return -1;
}
String FileCache::wwwroot_get_file_orig_path(const int index) {
_cache_lock.read_lock();
if (index < 0 || index >= _registered_files.size()) {
_cache_lock.read_unlock();
ERR_FAIL_V("");
}
String s = _registered_files[index].orig_path;
_cache_lock.read_unlock();
return s;
}
String FileCache::wwwroot_get_file_orig_path_abs(const int index) {
return get_wwwroot_abs() + wwwroot_get_file_orig_path(index);
}
void FileCache::wwwroot_refresh_cache() {
_cache_lock.write_lock();
_registered_files.clear();
_cache_lock.write_unlock();
if (_path_cache_mode == PATH_CACHE_MODE_STATIC) {
if (_wwwroot != "") {
wwwroot_evaluate_dir(_wwwroot);
}
}
}
void FileCache::wwwroot_evaluate_dir(const String &path, const bool should_exist) {
DirAccess *da = DirAccess::open(path);
ERR_FAIL_COND_MSG(!da, "Error opening wwwroot! folder: " + path);
da->list_dir_begin();
String f = da->get_next();
while (f != String()) {
if (f == "." || f == "..") {
f = da->get_next();
continue;
}
if (!da->current_is_dir()) {
String np = path + "/" + f;
np = np.substr(_wwwroot.size() - 1, np.size() - _wwwroot.size());
wwwroot_register_file(np);
} else {
wwwroot_evaluate_dir(path + "/" + f);
}
f = da->get_next();
}
da->list_dir_end();
memdelete(da);
}
bool FileCache::get_cached_body(const String &path, String *body) { bool FileCache::get_cached_body(const String &path, String *body) {
//TODO ERROR MACRO body == null //TODO ERROR MACRO body == null
@ -360,10 +220,6 @@ void FileCache::set_cached_body(const String &path, const String &body) {
} }
void FileCache::clear() { void FileCache::clear() {
_cache_lock.write_lock();
_registered_files.clear();
_cache_lock.write_unlock();
_body_lock.write_lock(); _body_lock.write_lock();
for (RBMap<String, CacheEntry *>::Element *E = cache_map.front(); E; E++) { for (RBMap<String, CacheEntry *>::Element *E = cache_map.front(); E; E++) {
@ -381,45 +237,28 @@ void FileCache::clear() {
FileCache::FileCache() { FileCache::FileCache() {
cache_invalidation_time = 0; cache_invalidation_time = 0;
_path_cache_mode = PATH_CACHE_MODE_OFF;
} }
FileCache::~FileCache() { FileCache::~FileCache() {
_registered_files.clear();
} }
void FileCache::_bind_methods() { void FileCache::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_path_cache_mode"), &FileCache::get_path_cache_mode);
ClassDB::bind_method(D_METHOD("set_path_cache_mode", "mode"), &FileCache::set_path_cache_mode);
ADD_PROPERTY(PropertyInfo(Variant::INT, "path_cache_mode", PROPERTY_HINT_ENUM, "Off,Static"), "set_path_cache_mode", "get_path_cache_mode");
ClassDB::bind_method(D_METHOD("get_wwwroot"), &FileCache::get_wwwroot); ClassDB::bind_method(D_METHOD("get_wwwroot"), &FileCache::get_wwwroot);
ClassDB::bind_method(D_METHOD("set_wwwroot", "val"), &FileCache::set_wwwroot); ClassDB::bind_method(D_METHOD("set_wwwroot", "val"), &FileCache::set_wwwroot);
ADD_PROPERTY(PropertyInfo(Variant::STRING, "wwwroot"), "set_wwwroot", "get_wwwroot"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "wwwroot"), "set_wwwroot", "get_wwwroot");
ClassDB::bind_method(D_METHOD("get_wwwroot_abs"), &FileCache::get_wwwroot_abs); ClassDB::bind_method(D_METHOD("get_wwwroot_abs"), &FileCache::get_wwwroot_abs);
ClassDB::bind_method(D_METHOD("wwwroot_get_file_abspath", "file_path"), &FileCache::wwwroot_get_file_abspath);
ClassDB::bind_method(D_METHOD("get_cache_invalidation_time"), &FileCache::get_cache_invalidation_time); ClassDB::bind_method(D_METHOD("get_cache_invalidation_time"), &FileCache::get_cache_invalidation_time);
ClassDB::bind_method(D_METHOD("set_cache_invalidation_time", "val"), &FileCache::set_cache_invalidation_time); ClassDB::bind_method(D_METHOD("set_cache_invalidation_time", "val"), &FileCache::set_cache_invalidation_time);
ADD_PROPERTY(PropertyInfo(Variant::INT, "cache_invalidation_time"), "set_cache_invalidation_time", "get_cache_invalidation_time"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cache_invalidation_time"), "set_cache_invalidation_time", "get_cache_invalidation_time");
ClassDB::bind_method(D_METHOD("wwwroot_register_file", "file_path"), &FileCache::wwwroot_register_file);
ClassDB::bind_method(D_METHOD("wwwroot_deregister_file", "file_path"), &FileCache::wwwroot_deregister_file);
ClassDB::bind_method(D_METHOD("wwwroot_has_file", "file_path"), &FileCache::wwwroot_has_file); ClassDB::bind_method(D_METHOD("wwwroot_has_file", "file_path"), &FileCache::wwwroot_has_file);
ClassDB::bind_method(D_METHOD("wwwroot_get_file_index", "file_path"), &FileCache::wwwroot_get_file_index); ClassDB::bind_method(D_METHOD("wwwroot_get_file_abspath", "file_path"), &FileCache::wwwroot_get_file_abspath);
ClassDB::bind_method(D_METHOD("wwwroot_get_file_orig_path", "index"), &FileCache::wwwroot_get_file_orig_path);
ClassDB::bind_method(D_METHOD("wwwroot_get_file_orig_path_abs", "index"), &FileCache::wwwroot_get_file_orig_path_abs);
ClassDB::bind_method(D_METHOD("wwwroot_refresh_cache"), &FileCache::wwwroot_refresh_cache);
ClassDB::bind_method(D_METHOD("wwwroot_evaluate_dir", "file_path", "should_exist "), &FileCache::wwwroot_evaluate_dir, true);
ClassDB::bind_method(D_METHOD("get_cached_body", "path"), &FileCache::get_cached_body_bind); ClassDB::bind_method(D_METHOD("get_cached_body", "path"), &FileCache::get_cached_body_bind);
ClassDB::bind_method(D_METHOD("has_cached_body", "path"), &FileCache::has_cached_body); ClassDB::bind_method(D_METHOD("has_cached_body", "path"), &FileCache::has_cached_body);
ClassDB::bind_method(D_METHOD("set_cached_body", "path", "body"), &FileCache::set_cached_body); ClassDB::bind_method(D_METHOD("set_cached_body", "path", "body"), &FileCache::set_cached_body);
ClassDB::bind_method(D_METHOD("clear"), &FileCache::clear); ClassDB::bind_method(D_METHOD("clear"), &FileCache::clear);
BIND_ENUM_CONSTANT(PATH_CACHE_MODE_OFF);
BIND_ENUM_CONSTANT(PATH_CACHE_MODE_STATIC);
} }

View File

@ -45,15 +45,6 @@ class FileCache : public Reference {
GDCLASS(FileCache, Reference); GDCLASS(FileCache, Reference);
public: public:
enum PathCacheMode {
PATH_CACHE_MODE_OFF,
PATH_CACHE_MODE_STATIC,
//TIMED?
};
PathCacheMode get_path_cache_mode() const;
void set_path_cache_mode(const PathCacheMode p_mode);
String get_wwwroot(); String get_wwwroot();
void set_wwwroot(const String &val); void set_wwwroot(const String &val);
@ -64,18 +55,8 @@ public:
//Note: file path should be the url you want to access the file with, including lead slash //Note: file path should be the url you want to access the file with, including lead slash
//e.g. http://127.0.0.1/a/b/d.jpg -> /a/b/d.jpg //e.g. http://127.0.0.1/a/b/d.jpg -> /a/b/d.jpg
String wwwroot_get_file_abspath(const String &file_path);
void wwwroot_register_file(const String &file_path);
void wwwroot_deregister_file(const String &file_path);
bool wwwroot_has_file(const String &file_path); bool wwwroot_has_file(const String &file_path);
//return -1 if does not exists String wwwroot_get_file_abspath(const String &file_path);
int wwwroot_get_file_index(const String &file_path);
String wwwroot_get_file_orig_path(const int index);
String wwwroot_get_file_orig_path_abs(const int index);
void wwwroot_refresh_cache();
void wwwroot_evaluate_dir(const String &path, const bool should_exist = true);
bool get_cached_body(const String &path, String *body); bool get_cached_body(const String &path, String *body);
bool has_cached_body(const String &path); bool has_cached_body(const String &path);
@ -92,6 +73,10 @@ public:
protected: protected:
static void _bind_methods(); static void _bind_methods();
String _wwwroot_orig;
String _wwwroot;
String _wwwroot_abs;
struct CacheEntry { struct CacheEntry {
uint64_t timestamp; uint64_t timestamp;
String body; String body;
@ -103,21 +88,6 @@ protected:
RWLock _body_lock; RWLock _body_lock;
RBMap<String, CacheEntry *> cache_map; RBMap<String, CacheEntry *> cache_map;
RWLock _cache_lock;
PathCacheMode _path_cache_mode;
String _wwwroot_orig;
String _wwwroot;
String _wwwroot_abs;
struct RegisteredFileEntry {
String orig_path;
String lowercase_path;
};
Vector<RegisteredFileEntry> _registered_files;
}; };
VARIANT_ENUM_CAST(FileCache::PathCacheMode);
#endif #endif

View File

@ -45,13 +45,7 @@ String WebRoot::get_www_root_path() {
void WebRoot::set_www_root_path(const String &val) { void WebRoot::set_www_root_path(const String &val) {
_www_root_path = val; _www_root_path = val;
if (val == "") {
_www_root_file_cache->set_wwwroot(val); _www_root_file_cache->set_wwwroot(val);
_www_root_file_cache->clear();
} else {
_www_root_file_cache->set_wwwroot(val);
_www_root_file_cache->wwwroot_refresh_cache();
}
} }
Ref<FileCache> WebRoot::get_www_root_file_cache() { Ref<FileCache> WebRoot::get_www_root_file_cache() {
@ -222,10 +216,6 @@ void WebRoot::_notification(int p_what) {
r->update(); r->update();
} }
} else if (p_what == NOTIFICATION_READY) {
if (!_www_root_path.empty()) {
_www_root_file_cache->wwwroot_refresh_cache();
}
} }
} }

View File

@ -59,12 +59,11 @@ void FolderServeWebPage::_handle_request_main(Ref<WebServerRequest> request) {
} }
String file_name = request->get_path(true, false); String file_name = request->get_path(true, false);
file_name = file_name.to_lower();
int file_indx = _file_cache->wwwroot_get_file_index(file_name); String file_path = _file_cache->wwwroot_get_file_abspath(file_name);
if (file_indx != -1) { if (!file_path.empty()) {
request->send_file(_file_cache->wwwroot_get_file_orig_path_abs(file_indx)); request->send_file(file_path);
return; return;
} }
@ -76,13 +75,7 @@ void FolderServeWebPage::_handle_request_main(Ref<WebServerRequest> request) {
void FolderServeWebPage::load() { void FolderServeWebPage::load() {
_file_cache->clear(); _file_cache->clear();
if (_serve_folder == "") {
_file_cache->set_wwwroot(_serve_folder); _file_cache->set_wwwroot(_serve_folder);
_file_cache->clear();
} else {
_file_cache->set_wwwroot(_serve_folder);
_file_cache->wwwroot_refresh_cache();
}
} }
void FolderServeWebPage::_notification(const int what) { void FolderServeWebPage::_notification(const int what) {

View File

@ -125,13 +125,10 @@ void PagedArticleWebPage::_handle_request_main(Ref<WebServerRequest> request) {
if (request->get_remaining_segment_count() > 1 && rp == "files") { if (request->get_remaining_segment_count() > 1 && rp == "files") {
String file_name = "/" + request->get_path_segment(request->get_current_segment_index() + 1); String file_name = "/" + request->get_path_segment(request->get_current_segment_index() + 1);
String file_path = file_cache->wwwroot_get_file_abspath(file_name);
int file_indx = file_cache->wwwroot_get_file_index(file_name); if (!file_path.empty()) {
request->send_file(file_path);
if (file_indx != -1) {
String fp = file_cache->wwwroot_get_file_orig_path_abs(file_indx);
request->send_file(fp);
return; return;
} }
} }
@ -248,8 +245,6 @@ void PagedArticleWebPage::_load() {
} else { } else {
file_cache->set_wwwroot(serve_folder); file_cache->set_wwwroot(serve_folder);
} }
file_cache->wwwroot_refresh_cache();
} }
if (summary.empty()) { if (summary.empty()) {