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/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() {
return _wwwroot_orig;
}
@ -69,6 +62,40 @@ void FileCache::set_cache_invalidation_time(const int &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) {
if (file_path.empty() || file_path == "/") {
return String();
@ -103,173 +130,6 @@ String FileCache::wwwroot_get_file_abspath(const String &file_path) {
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) {
//TODO ERROR MACRO body == null
@ -360,10 +220,6 @@ void FileCache::set_cached_body(const String &path, const String &body) {
}
void FileCache::clear() {
_cache_lock.write_lock();
_registered_files.clear();
_cache_lock.write_unlock();
_body_lock.write_lock();
for (RBMap<String, CacheEntry *>::Element *E = cache_map.front(); E; E++) {
@ -381,45 +237,28 @@ void FileCache::clear() {
FileCache::FileCache() {
cache_invalidation_time = 0;
_path_cache_mode = PATH_CACHE_MODE_OFF;
}
FileCache::~FileCache() {
_registered_files.clear();
}
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("set_wwwroot", "val"), &FileCache::set_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("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("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");
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_get_file_index", "file_path"), &FileCache::wwwroot_get_file_index);
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("wwwroot_get_file_abspath", "file_path"), &FileCache::wwwroot_get_file_abspath);
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("set_cached_body", "path", "body"), &FileCache::set_cached_body);
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);
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();
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
//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);
//return -1 if does not exists
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);
String wwwroot_get_file_abspath(const String &file_path);
bool get_cached_body(const String &path, String *body);
bool has_cached_body(const String &path);
@ -92,6 +73,10 @@ public:
protected:
static void _bind_methods();
String _wwwroot_orig;
String _wwwroot;
String _wwwroot_abs;
struct CacheEntry {
uint64_t timestamp;
String body;
@ -103,21 +88,6 @@ protected:
RWLock _body_lock;
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

View File

@ -45,13 +45,7 @@ String WebRoot::get_www_root_path() {
void WebRoot::set_www_root_path(const String &val) {
_www_root_path = val;
if (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() {
@ -222,10 +216,6 @@ void WebRoot::_notification(int p_what) {
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);
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) {
request->send_file(_file_cache->wwwroot_get_file_orig_path_abs(file_indx));
if (!file_path.empty()) {
request->send_file(file_path);
return;
}
@ -76,13 +75,7 @@ void FolderServeWebPage::_handle_request_main(Ref<WebServerRequest> request) {
void FolderServeWebPage::load() {
_file_cache->clear();
if (_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) {

View File

@ -125,13 +125,10 @@ void PagedArticleWebPage::_handle_request_main(Ref<WebServerRequest> request) {
if (request->get_remaining_segment_count() > 1 && rp == "files") {
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_indx != -1) {
String fp = file_cache->wwwroot_get_file_orig_path_abs(file_indx);
request->send_file(fp);
if (!file_path.empty()) {
request->send_file(file_path);
return;
}
}
@ -248,8 +245,6 @@ void PagedArticleWebPage::_load() {
} else {
file_cache->set_wwwroot(serve_folder);
}
file_cache->wwwroot_refresh_cache();
}
if (summary.empty()) {