#include "web_root.h" #include "core/object.h" #include "modules/web/http/http_server_enums.h" #include "web_server_request.h" #include "../file_cache.h" #include "web_permission.h" String WebRoot::get_www_root_path() { return _www_root_path; } void WebRoot::set_www_root_path(const String &val) { _www_root_path = val; if (val == "") { _www_root_file_cache->clear(); } else { _www_root_file_cache->wwwroot_evaluate_dir(val); } } Ref WebRoot::get_www_root_file_cache() { return _www_root_file_cache; } Vector WebRoot::get_middlewares() { Vector r; for (int i = 0; i < _middlewares.size(); i++) { r.push_back(_middlewares[i].get_ref_ptr()); } return r; } void WebRoot::set_middlewares(const Vector &data) { _middlewares.clear(); for (int i = 0; i < data.size(); i++) { Ref e = Ref(data[i]); _middlewares.push_back(e); } } //void WebRoot::setup_middleware() { // WebServerMiddlewares get processed in the order they are in the _middlewares array // ------- Built in middleware selection ------- // --- SessionSetupWebServerMiddleware --- // If you want sessions add this to your inherited class. // (#include "web/http/session_manager.h") // _middlewares.push_back(Ref(new SessionSetupWebServerMiddleware())); // --- UserSessionSetupWebServerMiddleware --- // This one looks up users based on sessions // (#include "web_modules/users/user_controller.h") // _middlewares.push_back(Ref(new UserSessionSetupWebServerMiddleware())); // --- RBACUserSessionSetupWebServerMiddleware / RBACDefaultUserSessionSetupWebServerMiddleware --- // Same as the previous, but if you want the RBAC system to work use one of these // UserSessionSetupWebServerMiddleware is not needed if you need these // (#include "web_modules/rbac_users/rbac_user_controller.h") // _middlewares.push_back(Ref(new RBACUserSessionSetupWebServerMiddleware())); // _middlewares.push_back(Ref(new RBACDefaultUserSessionSetupWebServerMiddleware())); // --- CSRF Token Middlweare --- // (#include "web/http/csrf_token.h") // Ref csrf_middleware; // csrf_middleware.instance(); // csrf_middleware->ignored_urls.push_back("/user/login"); // csrf_middleware->ignored_urls.push_back("/user/register"); // _middlewares.push_back(csrf_middleware); //} void WebRoot::_handle_request_main(Ref request) { if (process_middlewares(request)) { return; } if (_web_permission.is_valid()) { if (_web_permission->activate(request)) { return; } } // handle files first if (try_send_wwwroot_file(request)) { return; } // normal routing if (!_routing_enabled) { handle_request(request); return; } if (!try_route_request_to_children(request)) { handle_request(request); } } void WebRoot::_handle_error_send_request(Ref request, const int error_code) { if (error_code == HTTPServerEnums::HTTP_STATUS_CODE_404_NOT_FOUND) { request->compiled_body = "404 :("; request->send(); return; } request->compiled_body = "Internal server error! :("; request->send(); } bool WebRoot::process_middlewares(Ref request) { for (int i = 0; i < _middlewares.size(); ++i) { Ref m = _middlewares[i]; if (!m.is_valid()) { continue; } if (m->on_before_handle_request_main(request)) { // handled return true; } } return false; } bool WebRoot::try_send_wwwroot_file(Ref request) { String path = request->get_path_full(); if (_www_root_file_cache->wwwroot_has_file(path)) { send_file(path, request); return true; } return false; } void WebRoot::send_file(const String &path, Ref request) { String fp = _www_root_file_cache->wwwroot + path; request->send_file(fp); } void WebRoot::register_request_update(Ref request) { _update_registered_requests_mutex.lock(); _update_registered_requests.push_back(request); _update_registered_requests_mutex.unlock(); } void WebRoot::unregister_request_update(Ref request) { _update_registered_requests_mutex.lock(); std::size_t s = _update_registered_requests.size(); for (std::size_t i = 0; i < s; ++i) { Ref r = _update_registered_requests[i]; if (r == request) { _update_registered_requests.remove(i); _update_registered_requests_mutex.unlock(); return; } } _update_registered_requests_mutex.unlock(); } WebRoot::WebRoot() { _www_root_file_cache.instance(); set_process_internal(true); } WebRoot::~WebRoot() { } void WebRoot::_notification(int p_what) { if (p_what == NOTIFICATION_INTERNAL_PROCESS) { for (int i = 0; i < _update_registered_requests.size(); ++i) { Ref r = _update_registered_requests[i]; r->update(); } } } void WebRoot::_bind_methods() { ClassDB::bind_method(D_METHOD("get_www_root_path"), &WebRoot::get_www_root_path); ClassDB::bind_method(D_METHOD("set_www_root_path", "val"), &WebRoot::set_www_root_path); ADD_PROPERTY(PropertyInfo(Variant::STRING, "www_root_path"), "set_www_root_path", "get_www_root_path"); ClassDB::bind_method(D_METHOD("get_www_root_file_cache"), &WebRoot::get_www_root_file_cache); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "www_root_file_cache", PROPERTY_HINT_RESOURCE_TYPE, "FileCache", 0), "", "get_www_root_file_cache"); ClassDB::bind_method(D_METHOD("get_middlewares"), &WebRoot::get_middlewares); ClassDB::bind_method(D_METHOD("set_middlewares", "data"), &WebRoot::set_middlewares); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "middlewares", PROPERTY_HINT_NONE, "17/17:WebServerMiddleware ", PROPERTY_USAGE_DEFAULT, "WebServerMiddleware "), "set_middlewares", "get_middlewares"); ClassDB::bind_method(D_METHOD("process_middlewares", "request"), &WebRoot::process_middlewares); ClassDB::bind_method(D_METHOD("try_send_wwwroot_file", "request"), &WebRoot::try_send_wwwroot_file); ClassDB::bind_method(D_METHOD("send_file", "path", "request"), &WebRoot::send_file); ClassDB::bind_method(D_METHOD("register_request_update", "request"), &WebRoot::register_request_update); ClassDB::bind_method(D_METHOD("unregister_request_update", "request"), &WebRoot::unregister_request_update); }