mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2024-11-23 01:19:20 +01:00
Initial cleanup of the folder serve nodes, also added them and HTMLBuilder to the build.
This commit is contained in:
parent
56d2ccbb26
commit
f81018f712
@ -22,8 +22,8 @@ sources = [
|
||||
"http/web_server_middleware.cpp",
|
||||
"http/web_server_request.cpp",
|
||||
|
||||
|
||||
"html/html_builder_bind.cpp",
|
||||
"html/html_builder.cpp",
|
||||
|
||||
"http_server_simple/http_server_simple.cpp",
|
||||
"http_server_simple/web_server_simple.cpp",
|
||||
@ -35,6 +35,9 @@ sources = [
|
||||
"nodes/static_pages/static_page.cpp",
|
||||
"nodes/static_pages/static_page_file.cpp",
|
||||
"nodes/static_pages/static_page_folder_files.cpp",
|
||||
|
||||
"nodes/folder_serve_nodes/browsable_folder_serve_node.cpp",
|
||||
"nodes/folder_serve_nodes/folder_serve_node.cpp",
|
||||
]
|
||||
|
||||
if ARGUMENTS.get('custom_modules_shared', 'no') == 'yes':
|
||||
|
@ -38,6 +38,9 @@ def get_doc_classes():
|
||||
"StaticPage",
|
||||
"StaticPageFile",
|
||||
"StaticPageFolderFiles",
|
||||
|
||||
"FolderServeNode",
|
||||
"BrowsableFolderServeNode",
|
||||
]
|
||||
|
||||
|
||||
|
@ -1,7 +1,4 @@
|
||||
#include "html_builder.h"
|
||||
#include "core/string.h"
|
||||
|
||||
#include "web/http/request.h"
|
||||
|
||||
HTMLTag *HTMLTag::str(const String &str) {
|
||||
result += " " + str;
|
||||
@ -826,10 +823,11 @@ HTMLTag *HTMLTag::reset() {
|
||||
}
|
||||
|
||||
HTMLTag *HTMLTag::close() {
|
||||
if (simple)
|
||||
if (simple) {
|
||||
result += "/>";
|
||||
else
|
||||
} else {
|
||||
result += ">";
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -2575,12 +2573,14 @@ HTMLBuilder *HTMLBuilder::form_post(const String &action, const String &cls, con
|
||||
return this;
|
||||
}
|
||||
|
||||
/*
|
||||
HTMLBuilder *HTMLBuilder::form_post(const String &action, Request *request, const String &cls, const String &id) {
|
||||
form_post(action, cls, id);
|
||||
csrf_token(request);
|
||||
|
||||
return this;
|
||||
}
|
||||
*/
|
||||
|
||||
HTMLTag *HTMLBuilder::input_button() {
|
||||
write_tag();
|
||||
@ -3326,9 +3326,11 @@ HTMLBuilder *HTMLBuilder::csrf_token(const String &token) {
|
||||
|
||||
return this;
|
||||
}
|
||||
/*
|
||||
HTMLBuilder *HTMLBuilder::csrf_token(Request *request) {
|
||||
return csrf_token(request->get_csrf_token());
|
||||
}
|
||||
*/
|
||||
|
||||
void HTMLBuilder::f() {
|
||||
write_tag();
|
||||
@ -3359,7 +3361,8 @@ HTMLBuilder *HTMLBuilder::wns(const double val) {
|
||||
HTMLBuilder *HTMLBuilder::wr(const double val, const bool p_trailing) {
|
||||
write_tag();
|
||||
|
||||
result += String::num_real(val, p_trailing);
|
||||
//TODO
|
||||
//result += String::num_real(val, p_trailing);
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -3393,13 +3396,10 @@ HTMLBuilder *HTMLBuilder::wbs(const bool val) {
|
||||
return this;
|
||||
}
|
||||
|
||||
// TODO!
|
||||
HTMLBuilder *HTMLBuilder::we(const String &val) {
|
||||
printf("HTMLBuilder::write_excaped NYI!");
|
||||
|
||||
write_tag();
|
||||
|
||||
result += val;
|
||||
result += val.http_escape();
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -3419,4 +3419,4 @@ HTMLBuilder::HTMLBuilder() {
|
||||
}
|
||||
|
||||
HTMLBuilder::~HTMLBuilder() {
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef HTML_BUILDER_H
|
||||
#define HTML_BUILDER_H
|
||||
|
||||
#include "core/string.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
class Request;
|
||||
class HTMLBuilder;
|
||||
@ -470,7 +470,7 @@ public:
|
||||
HTMLBuilder *form_get(const String &action, const String &cls = "", const String &id = "");
|
||||
HTMLBuilder *form_post(const String &action, const String &cls = "", const String &id = "");
|
||||
// will add a csrf token from request
|
||||
HTMLBuilder *form_post(const String &action, Request *request, const String &cls = "", const String &id = "");
|
||||
//HTMLBuilder *form_post(const String &action, Request *request, const String &cls = "", const String &id = "");
|
||||
|
||||
HTMLTag *input_button();
|
||||
HTMLTag *input_checkbox();
|
||||
@ -521,7 +521,7 @@ public:
|
||||
HTMLBuilder *input_hidden(const String &name, const String &value);
|
||||
|
||||
HTMLBuilder *csrf_token(const String &token);
|
||||
HTMLBuilder *csrf_token(Request *request);
|
||||
//HTMLBuilder *csrf_token(Request *request);
|
||||
|
||||
void f();
|
||||
|
||||
@ -548,4 +548,4 @@ protected:
|
||||
HTMLTag tag;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,21 +1,33 @@
|
||||
#include "browsable_folder_serve_node.h"
|
||||
|
||||
#include "core/os/directory.h"
|
||||
#include "web/file_cache.h"
|
||||
#include "web/html/html_builder.h"
|
||||
#include "web/http/request.h"
|
||||
#include "core/os/dir_access.h"
|
||||
|
||||
void BrowsableFolderServeNode::_handle_request_main(Request *request) {
|
||||
#include "../../html/html_builder.h"
|
||||
|
||||
#include "../../file_cache.h"
|
||||
#include "../../http/web_permission.h"
|
||||
#include "../../http/web_server_request.h"
|
||||
|
||||
#include "../../http/http_server_enums.h"
|
||||
|
||||
bool BrowsableFolderServeNode::get_should_render_menu() {
|
||||
return _should_render_menu;
|
||||
}
|
||||
void BrowsableFolderServeNode::set_should_render_menu(const bool &val) {
|
||||
_should_render_menu = val;
|
||||
}
|
||||
|
||||
void BrowsableFolderServeNode::_handle_request_main(Ref<WebServerRequest> request) {
|
||||
String file_name = request->get_path(true, false);
|
||||
|
||||
String *s = _folder_indexes[file_name];
|
||||
|
||||
if (!s) {
|
||||
request->send_error(HTTP_STATUS_CODE_404_NOT_FOUND);
|
||||
request->send_error(HTTPServerEnums::HTTP_STATUS_CODE_404_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
if (should_render_menu) {
|
||||
if (_should_render_menu) {
|
||||
render_menu(request);
|
||||
}
|
||||
|
||||
@ -23,7 +35,7 @@ void BrowsableFolderServeNode::_handle_request_main(Request *request) {
|
||||
request->compile_and_send_body();
|
||||
}
|
||||
|
||||
void BrowsableFolderServeNode::render_index(Request *request) {
|
||||
void BrowsableFolderServeNode::render_index(Ref<WebServerRequest> request) {
|
||||
String *s = _folder_indexes["/"];
|
||||
|
||||
if (!s) {
|
||||
@ -32,29 +44,28 @@ void BrowsableFolderServeNode::render_index(Request *request) {
|
||||
|
||||
request->body += (*s);
|
||||
}
|
||||
void BrowsableFolderServeNode::render_preview(Request *request) {
|
||||
void BrowsableFolderServeNode::render_preview(Ref<WebServerRequest> request) {
|
||||
}
|
||||
|
||||
void BrowsableFolderServeNode::load() {
|
||||
if (serve_folder == "") {
|
||||
if (_serve_folder == "") {
|
||||
return;
|
||||
}
|
||||
|
||||
FolderServeNode::load();
|
||||
|
||||
evaluate_dir(serve_folder, true);
|
||||
evaluate_dir(_serve_folder, true);
|
||||
}
|
||||
|
||||
void BrowsableFolderServeNode::evaluate_dir(const String &path, const bool top_level) {
|
||||
Ref<Directory> dir;
|
||||
dir.instance();
|
||||
DirAccess *dir = DirAccess::open(path);
|
||||
|
||||
ERR_FAIL_COND_MSG(dir->open_dir(path) != OK, "Error opening folde!r: " + String(path));
|
||||
ERR_FAIL_COND_MSG(!dir, "Error opening folde!r: " + String(path));
|
||||
|
||||
String dir_uri;
|
||||
|
||||
if (!top_level) {
|
||||
dir_uri = path.substr(serve_folder.size(), path.size() - serve_folder.size());
|
||||
dir_uri = path.substr(_serve_folder.size(), path.size() - _serve_folder.size());
|
||||
} else {
|
||||
dir_uri = "/";
|
||||
}
|
||||
@ -62,23 +73,34 @@ void BrowsableFolderServeNode::evaluate_dir(const String &path, const bool top_l
|
||||
Vector<String> folders;
|
||||
Vector<String> files;
|
||||
|
||||
while (dir->next()) {
|
||||
String np = dir->current_get_path();
|
||||
np = np.substr(serve_folder.size(), np.size() - serve_folder.size());
|
||||
dir->list_dir_begin();
|
||||
|
||||
if (dir->current_is_file()) {
|
||||
files.push_back(np);
|
||||
String file = dir->get_next();
|
||||
|
||||
while (file != "") {
|
||||
String np = path.append_path(file);
|
||||
String nnp = np.substr(_serve_folder.size(), np.size() - _serve_folder.size());
|
||||
|
||||
if (dir->current_is_dir() && file != "." && file != "..") {
|
||||
folders.push_back(nnp);
|
||||
|
||||
evaluate_dir(np);
|
||||
} else {
|
||||
folders.push_back(np);
|
||||
evaluate_dir(dir->current_get_path());
|
||||
files.push_back(nnp);
|
||||
}
|
||||
|
||||
file = dir->get_next();
|
||||
}
|
||||
|
||||
dir->close_dir();
|
||||
dir->list_dir_end();
|
||||
|
||||
folders.sort_inc();
|
||||
files.sort_inc();
|
||||
memdelete(dir);
|
||||
|
||||
folders.sort();
|
||||
files.sort();
|
||||
|
||||
//folders.sort_inc();
|
||||
//files.sort_inc();
|
||||
|
||||
render_dir_page(dir_uri, folders, files, top_level);
|
||||
}
|
||||
@ -101,7 +123,7 @@ void BrowsableFolderServeNode::render_dir_page(const String &dir_uri, const Vect
|
||||
for (int i = 0; i < folders.size(); ++i) {
|
||||
b.div("file_list_entry");
|
||||
{
|
||||
b.a(uri + folders[i])->w("(Folder) ")->w(folders[i].path_get_basename())->ca();
|
||||
b.a(uri + folders[i])->w("(Folder) ")->w(folders[i].get_basename())->ca();
|
||||
}
|
||||
b.cdiv();
|
||||
}
|
||||
@ -109,29 +131,32 @@ void BrowsableFolderServeNode::render_dir_page(const String &dir_uri, const Vect
|
||||
for (int i = 0; i < files.size(); ++i) {
|
||||
b.div("file_list_entry");
|
||||
{
|
||||
b.a(uri + files[i])->w("(File) ")->w(files[i].path_get_basename())->ca();
|
||||
b.a(uri + files[i])->w("(File) ")->w(files[i].get_basename())->ca();
|
||||
}
|
||||
b.cdiv();
|
||||
}
|
||||
}
|
||||
b.cdiv();
|
||||
|
||||
String *s = new String();
|
||||
s->append_str(b.result);
|
||||
String *s = memnew(String);
|
||||
s->operator+=(b.result);
|
||||
|
||||
_folder_indexes[dir_uri] = s;
|
||||
}
|
||||
|
||||
BrowsableFolderServeNode::BrowsableFolderServeNode() :
|
||||
FolderServeNode() {
|
||||
|
||||
should_render_menu = true;
|
||||
BrowsableFolderServeNode::BrowsableFolderServeNode() {
|
||||
_should_render_menu = true;
|
||||
}
|
||||
|
||||
BrowsableFolderServeNode::~BrowsableFolderServeNode() {
|
||||
for (std::map<String, String *>::iterator E = _folder_indexes.begin(); E != _folder_indexes.end(); E++) {
|
||||
if (E->second) {
|
||||
delete E->second;
|
||||
const String *key = nullptr;
|
||||
while ((key = _folder_indexes.next(key))) {
|
||||
String k = *key;
|
||||
|
||||
String *v = _folder_indexes[k];
|
||||
|
||||
if (v) {
|
||||
memdelete(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
#ifndef BROWSABLE_FOLDER_SERVE_NODE_H
|
||||
#define BROWSABLE_FOLDER_SERVE_NODE_H
|
||||
|
||||
#include "core/string.h"
|
||||
#include <map>
|
||||
#include "core/hash_map.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#include "folder_serve_node.h"
|
||||
|
||||
// On top of serving the files from the folder set to it's serve_folder property,
|
||||
class WebServerRequest;
|
||||
|
||||
// On top of serving the files from the folder set to it's serve_folder property,
|
||||
// this class also generates HTML directory lists. (Similar to apache's directory listing)
|
||||
// It caches folder contents on ENTER_TREE, it does not watch for folder changes yet.
|
||||
|
||||
@ -19,26 +21,28 @@
|
||||
// </div>
|
||||
|
||||
class BrowsableFolderServeNode : public FolderServeNode {
|
||||
RCPP_OBJECT(BrowsableFolderServeNode, FolderServeNode);
|
||||
GDCLASS(BrowsableFolderServeNode, FolderServeNode);
|
||||
|
||||
public:
|
||||
void _handle_request_main(Request *request);
|
||||
bool get_should_render_menu();
|
||||
void set_should_render_menu(const bool &val);
|
||||
|
||||
void render_index(Request *request);
|
||||
void render_preview(Request *request);
|
||||
void _handle_request_main(Ref<WebServerRequest> request);
|
||||
|
||||
virtual void load();
|
||||
void render_index(Ref<WebServerRequest> request);
|
||||
void render_preview(Ref<WebServerRequest> request);
|
||||
|
||||
void load();
|
||||
|
||||
void evaluate_dir(const String &path, const bool top_level = false);
|
||||
virtual void render_dir_page(const String &dir_uri, const Vector<String> &folders, const Vector<String> &files, const bool top_level);
|
||||
|
||||
bool should_render_menu;
|
||||
|
||||
BrowsableFolderServeNode();
|
||||
~BrowsableFolderServeNode();
|
||||
|
||||
protected:
|
||||
std::map<String, String *> _folder_indexes;
|
||||
bool _should_render_menu;
|
||||
HashMap<String, String *> _folder_indexes;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1,9 +1,17 @@
|
||||
#include "folder_serve_node.h"
|
||||
|
||||
#include "web/http/request.h"
|
||||
#include "web/http/web_permission.h"
|
||||
#include "../../file_cache.h"
|
||||
#include "../../http/web_permission.h"
|
||||
#include "../../http/web_server_request.h"
|
||||
|
||||
void FolderServeNode::handle_request_main(Request *request) {
|
||||
String FolderServeNode::get_serve_folder() {
|
||||
return _serve_folder;
|
||||
}
|
||||
void FolderServeNode::set_serve_folder(const String &val) {
|
||||
_serve_folder = val;
|
||||
}
|
||||
|
||||
void FolderServeNode::_handle_request_main(Ref<WebServerRequest> request) {
|
||||
if (_web_permission.is_valid()) {
|
||||
if (_web_permission->activate(request)) {
|
||||
return;
|
||||
@ -20,12 +28,16 @@ void FolderServeNode::handle_request_main(Request *request) {
|
||||
}
|
||||
|
||||
String file_name = request->get_path(true, false);
|
||||
file_name = file_name.to_lower();
|
||||
|
||||
if (file_cache->wwwroot_has_file(file_name)) {
|
||||
String fp = file_cache->wwwroot;
|
||||
fp.append_path(file_name);
|
||||
int file_indx = _file_cache->wwwroot_get_file_index(file_name);
|
||||
|
||||
if (file_indx != -1) {
|
||||
String fp = _file_cache->get_wwwroot_abs();
|
||||
fp = fp.append_path(file_name);
|
||||
|
||||
request->send_file(_file_cache->wwwroot_get_file_orig_path(file_indx));
|
||||
|
||||
request->send_file(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -35,16 +47,15 @@ void FolderServeNode::handle_request_main(Request *request) {
|
||||
}
|
||||
|
||||
void FolderServeNode::load() {
|
||||
file_cache->clear();
|
||||
_file_cache->clear();
|
||||
|
||||
if (serve_folder == "") {
|
||||
return;
|
||||
if (_serve_folder == "") {
|
||||
_file_cache->set_wwwroot(_serve_folder);
|
||||
_file_cache->clear();
|
||||
} else {
|
||||
_file_cache->set_wwwroot(_serve_folder);
|
||||
_file_cache->wwwroot_refresh_cache();
|
||||
}
|
||||
|
||||
serve_folder.path_clean_end_slash();
|
||||
|
||||
file_cache->wwwroot = serve_folder;
|
||||
file_cache->wwwroot_refresh_cache();
|
||||
}
|
||||
|
||||
void FolderServeNode::_notification(const int what) {
|
||||
@ -57,11 +68,17 @@ void FolderServeNode::_notification(const int what) {
|
||||
}
|
||||
}
|
||||
|
||||
FolderServeNode::FolderServeNode() :
|
||||
WebNode() {
|
||||
|
||||
file_cache = new FileCache();
|
||||
FolderServeNode::FolderServeNode() {
|
||||
_file_cache.instance();
|
||||
}
|
||||
|
||||
FolderServeNode::~FolderServeNode() {
|
||||
}
|
||||
|
||||
void FolderServeNode::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("get_serve_folder"), &FolderServeNode::get_serve_folder);
|
||||
ClassDB::bind_method(D_METHOD("set_serve_folder", "val"), &FolderServeNode::set_serve_folder);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "serve_folder"), "set_serve_folder", "get_serve_folder");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("load"), &FolderServeNode::load);
|
||||
}
|
||||
|
@ -1,33 +1,40 @@
|
||||
#ifndef FOLDER_SERVE_NODE_H
|
||||
#define FOLDER_SERVE_NODE_H
|
||||
|
||||
#include "core/string.h"
|
||||
#include "core/reference.h"
|
||||
#include "core/ustring.h"
|
||||
|
||||
#include "web/file_cache.h"
|
||||
#include "web/http/web_node.h"
|
||||
#include "../../http/web_node.h"
|
||||
|
||||
class WebServerRequest;
|
||||
class FileCache;
|
||||
|
||||
// This class will serve the files from the folder set to it's serve_folder property.
|
||||
// It will cache the folder's contents on ENTER_TREE, and will match against the cached list,
|
||||
// this means directory walking (for example sending http://webapp.com/files/../../../etc/passwd),
|
||||
// this means directory walking (for example sending http://webapp.com/files/../../../etc/passwd),
|
||||
// and other techniques like it should not be possible.
|
||||
|
||||
class FolderServeNode : public WebNode {
|
||||
RCPP_OBJECT(FolderServeNode, WebNode);
|
||||
GDCLASS(FolderServeNode, WebNode);
|
||||
|
||||
public:
|
||||
void handle_request_main(Request *request);
|
||||
String get_serve_folder();
|
||||
void set_serve_folder(const String &val);
|
||||
|
||||
void _handle_request_main(Ref<WebServerRequest> request);
|
||||
|
||||
virtual void load();
|
||||
|
||||
void _notification(const int what);
|
||||
|
||||
String serve_folder;
|
||||
|
||||
FolderServeNode();
|
||||
~FolderServeNode();
|
||||
|
||||
protected:
|
||||
FileCache *file_cache;
|
||||
void _notification(const int what);
|
||||
static void _bind_methods();
|
||||
|
||||
String _serve_folder;
|
||||
|
||||
Ref<FileCache> _file_cache;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -46,6 +46,9 @@ SOFTWARE.
|
||||
#include "nodes/static_pages/static_page_file.h"
|
||||
#include "nodes/static_pages/static_page_folder_files.h"
|
||||
|
||||
#include "nodes/folder_serve_nodes/browsable_folder_serve_node.h"
|
||||
#include "nodes/folder_serve_nodes/folder_serve_node.h"
|
||||
|
||||
void register_web_types() {
|
||||
ClassDB::register_class<_HTMLBuilder>();
|
||||
ClassDB::register_class<_HTMLTag>();
|
||||
@ -71,6 +74,9 @@ void register_web_types() {
|
||||
ClassDB::register_class<StaticPage>();
|
||||
ClassDB::register_class<StaticPageFile>();
|
||||
ClassDB::register_class<StaticPageFolderFiles>();
|
||||
|
||||
ClassDB::register_class<FolderServeNode>();
|
||||
ClassDB::register_class<BrowsableFolderServeNode>();
|
||||
}
|
||||
|
||||
void unregister_web_types() {
|
||||
|
Loading…
Reference in New Issue
Block a user