From a1afe210d1f253edbf6cc2ab8435699c53d64d9e Mon Sep 17 00:00:00 2001 From: Relintai Date: Fri, 7 Jan 2022 20:11:06 +0100 Subject: [PATCH] Split WebApplication into WebServer and WebRoot. WebServer inherits from NodeTree, and WebRoot inherits from WebNode. Also removed some of the brynet classes. --- core/bry_http/bry_request.cpp | 157 ------------------ core/bry_http/bry_request.h | 50 ------ core/bry_http/http_server.cpp | 133 --------------- core/bry_http/http_server.h | 50 ------ core/http/request.cpp | 7 +- core/http/request.h | 5 +- .../{web_application.cpp => web_root.cpp} | 49 +++--- core/http/{web_application.h => web_root.h} | 19 ++- core/http/web_server.cpp | 31 ++++ core/http/web_server.h | 27 +++ modules/drogon/web_application.cpp | 25 +-- modules/drogon/web_application.h | 15 +- modules/paged_article/paged_article.cpp | 2 - 13 files changed, 112 insertions(+), 458 deletions(-) delete mode 100644 core/bry_http/bry_request.cpp delete mode 100644 core/bry_http/bry_request.h delete mode 100644 core/bry_http/http_server.cpp delete mode 100644 core/bry_http/http_server.h rename core/http/{web_application.cpp => web_root.cpp} (64%) rename core/http/{web_application.h => web_root.h} (82%) create mode 100644 core/http/web_server.cpp create mode 100644 core/http/web_server.h diff --git a/core/bry_http/bry_request.cpp b/core/bry_http/bry_request.cpp deleted file mode 100644 index c7e6931..0000000 --- a/core/bry_http/bry_request.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "bry_request.h" - -#include "web_application.h" - -void BryRequest::send() { - //if (connection_closed) { - // RequestPool::return_request(this); - // return; - //} - - if (http_parser->isKeepAlive()) { - response->setBody(compiled_body); - - response->addHeadValue("Connection", "Keep-Alive"); - - String result = response->getResult(); - - session->send(result.c_str(), result.size()); - } else { - response->setBody(compiled_body); - - response->addHeadValue("Connection", "Close"); - - String result = response->getResult(); - - HttpSession::Ptr lsession = session; - - session->send(result.c_str(), result.size(), [lsession]() { lsession->postShutdown(); }); - } - - pool(); -} - -void BryRequest::send_file(const String &p_file_path) { - //if (connection_closed) { - // RequestPool::return_request(this); - // return; - //} - - file_path = p_file_path; - - FILE *f = fopen(file_path.c_str(), "rb"); - - if (!f) { - printf("send_file: Error: Download: file doesn't exists! %s\n", file_path.c_str()); - - return; - } - - fseek(f, 0, SEEK_END); - file_size = ftell(f); - fclose(f); - - response->addHeadValue("Connection", "Close"); - String result = "HTTP/1.1 200 OK\r\nConnection: Close\r\n\r\n"; - - application->register_request_update(this); - - session->send(result.c_str(), result.size(), [this]() { this->_file_chunk_sent(); }); -} - -void BryRequest::reset() { - Request::reset(); - - http_parser = nullptr; - session = nullptr; - - if (response) - delete response; - - response = new ::HttpResponse(); -} - -String BryRequest::parser_get_path() { - return http_parser->getPath(); -} - -void BryRequest::update() { - if (file_next) { - file_next = false; - _progress_send_file(); - } -} - -BryRequest *BryRequest::get() { - return _request_pool.get_request(); -} -void BryRequest::pool(BryRequest *request) { - return _request_pool.return_request(request); -} -void BryRequest::pool() { - BryRequest::pool(this); -} - -BryRequest::BryRequest() : - Request() { - response = nullptr; - - reset(); -} - -BryRequest::~BryRequest() { - delete response; -} - -void BryRequest::_progress_send_file() { - if (connection_closed) { - pool(); - return; - } - - if (current_file_progress >= file_size) { - session->postShutdown(); - - pool(); - - return; - } - - FILE *f = fopen(file_path.c_str(), "rb"); - - if (!f) { - printf("Error: Download: In progress file doesn't exists anymore! %s\n", file_path.c_str()); - - application->unregister_request_update(this); - - session->postShutdown(); - - pool(); - - return; - } - - fseek(f, current_file_progress, SEEK_SET); - - long nfp = current_file_progress + file_chunk_size; - - long csize = file_chunk_size; - if (nfp >= file_size) { - csize = (file_size - current_file_progress); - } - - body.resize(csize); - - fread(&body[0], 1, csize, f); - fclose(f); - - current_file_progress = nfp; - - session->send(body.c_str(), body.size(), [this]() { this->_file_chunk_sent(); }); -} - -void BryRequest::_file_chunk_sent() { - file_next = true; -} - -RequestPool BryRequest::_request_pool; \ No newline at end of file diff --git a/core/bry_http/bry_request.h b/core/bry_http/bry_request.h deleted file mode 100644 index 447e372..0000000 --- a/core/bry_http/bry_request.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef BRY_REQUEST_H -#define BRY_REQUEST_H - -#include "core/string.h" - -#include "core/http/request.h" - -#include -#include - -#include -#include - -#include "core/http/handler_instance.h" - -class WebApplication; - -class BryRequest : public Request { -public: - HTTPParser::Ptr http_parser; - HttpSession::Ptr session; - HttpResponse *response; - - void send(); - void send_file(const String &p_file_path); - void reset(); - String parser_get_path(); - - void update(); - - static BryRequest *get(); - static void pool(BryRequest *request); - void pool(); - - BryRequest(); - ~BryRequest(); - -protected: - void _progress_send_file(); - void _file_chunk_sent(); - - std::vector _path_stack; - uint32_t _path_stack_pointer; - -private: - static RequestPool _request_pool; -}; - - -#endif \ No newline at end of file diff --git a/core/bry_http/http_server.cpp b/core/bry_http/http_server.cpp deleted file mode 100644 index 19b13be..0000000 --- a/core/bry_http/http_server.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include "http_server.h" - -#include "core/http/web_application.h" -#include "bry_request.h" - -#define LOG_VERBOSE 0 - -void HTTPServer::http_callback_handler(Request *request) { - application->handle_request(request); -} - -void HTTPServer::httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session) { - std::unique_lock lock(_request_map_mutex, std::defer_lock); - - BryRequest *request = BryRequest::get(); - - HttpSession *s = session.get(); - - lock.lock(); - _request_map[s] = request; - lock.unlock(); - - request->application = application; - request->http_parser = std::make_shared(httpParser); - request->session = session; - - request->setup_url_stack(); - -#if LOG_VERBOSE - std::cout << "method:" << http_method_str(static_cast(httpParser.method())) << std::endl; -#endif - - http_callback_handler(request); -} - -void HTTPServer::wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload) { - - std::cout << "frame enter of type:" << int(opcode) << std::endl; - std::cout << "payload is:" << payload << std::endl; - // echo frame - //auto frame = std::make_shared(); - - //WebSocketFormat::wsFrameBuild(payload.c_str(), payload.size(), *frame, WebSocketFormat::WebSocketFrameType::TEXT_FRAME, true, false); - - //httpSession->send(frame); -} - -void HTTPServer::closedCallbackDefault(const HttpSession::Ptr &session) { - HttpSession *s = session.get(); - - std::unique_lock lock(_request_map_mutex, std::defer_lock); - - lock.lock(); - Request *r = _request_map[s]; - - if (r == nullptr) { - lock.unlock(); - //printf("Error HTTPServer::closedCallbackDefault: r == nullptr!\n"); - - return; - } - - _request_map.erase(s); - lock.unlock(); - - r->connection_closed = true; -} - -void HTTPServer::configure() { -} - -void HTTPServer::initialize() { - if (service) - return; - - configure(); - - service = TcpService::Create(); - service->startWorkerThread(threads); - - int p_port = port; - - //! - if (listenBuilder) - delete listenBuilder; - - listenBuilder = new HttpListenerBuilder(); - listenBuilder->WithService(service); - - listenBuilder->AddSocketProcess([](TcpSocket &socket) { - socket.setNodelay(); - socket.setNonblock(); - }); - - listenBuilder->WithAddr(false, "0.0.0.0", p_port); - - listenBuilder->WithEnterCallback([this](const HttpSession::Ptr &httpSession, HttpSessionHandlers &handlers) { - handlers.setHttpCallback([this](const HTTPParser &httpParser, const HttpSession::Ptr &session){ this->httpEnterCallbackDefault(httpParser, session); }); - handlers.setWSCallback([this](const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload){ this->wsEnterCallbackDefault(httpSession, opcode, payload); }); - handlers.setClosedCallback([this](const HttpSession::Ptr &session){ this->closedCallbackDefault(session); }); - }); - - listenBuilder->asyncRun(); -} - -void HTTPServer::loop_once() { - application->update(); -} - -void HTTPServer::main_loop() { - while (true) { - //std::this_thread::sleep_for(std::chrono::seconds(1)); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - - if (app_kbhit()) { - break; - } - - application->update(); - } -} - -HTTPServer::HTTPServer() { - port = 80; - threads = 4; - listenBuilder = nullptr; - - application = nullptr; -} - -HTTPServer::~HTTPServer() { - delete listenBuilder; -} diff --git a/core/bry_http/http_server.h b/core/bry_http/http_server.h deleted file mode 100644 index 45972a2..0000000 --- a/core/bry_http/http_server.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef HTTP_SERVER_H -#define HTTP_SERVER_H - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -class Request; -class WebApplication; - -class HTTPServer { -public: - int port; - int threads; - std::shared_ptr service; - HttpListenerBuilder *listenBuilder; - - void http_callback_handler(Request *response); - - void httpEnterCallbackDefault(const HTTPParser &httpParser, const HttpSession::Ptr &session); - void wsEnterCallbackDefault(const HttpSession::Ptr &httpSession, WebSocketFormat::WebSocketFrameType opcode, const std::string &payload); - void closedCallbackDefault(const HttpSession::Ptr &session); - - virtual void configure(); - virtual void initialize(); - - void loop_once(); - void main_loop(); - - HTTPServer(); - virtual ~HTTPServer(); - - //move this to a sublcass - WebApplication *application; - -protected: - std::map _request_map; - std::mutex _request_map_mutex; -}; - -#endif \ No newline at end of file diff --git a/core/http/request.cpp b/core/http/request.cpp index 21d601c..403a226 100644 --- a/core/http/request.cpp +++ b/core/http/request.cpp @@ -1,11 +1,12 @@ #include "request.h" #include "core/http/cookie.h" -#include "web_application.h" +#include "web_server.h" #include "http_session.h" #include "session_manager.h" +#include "core/http/web_root.h" HTTPSession *Request::get_or_create_session() { if (session) { @@ -100,12 +101,12 @@ void Request::send_file(const String &p_file_path) { } void Request::send_error(int error_code) { - application->send_error(error_code, this); + server->get_web_root()->send_error(error_code, this); } void Request::reset() { session = nullptr; - application = nullptr; + server = nullptr; current_middleware_index = 0; middleware_stack = nullptr; _path_stack.clear(); diff --git a/core/http/request.h b/core/http/request.h index 2aaa599..0942bda 100644 --- a/core/http/request.h +++ b/core/http/request.h @@ -4,6 +4,7 @@ #include "core/containers/vector.h" #include "core/string.h" +#include #include #include @@ -14,13 +15,13 @@ #include "http_enums.h" -class WebApplication; +class WebServer; class Cookie; class HTTPSession; class Request { public: - WebApplication *application; + WebServer *server; uint32_t current_middleware_index; HandlerInstance handler_instance; diff --git a/core/http/web_application.cpp b/core/http/web_root.cpp similarity index 64% rename from core/http/web_application.cpp rename to core/http/web_root.cpp index a095df0..fd52228 100644 --- a/core/http/web_application.cpp +++ b/core/http/web_root.cpp @@ -1,4 +1,4 @@ -#include "web_application.h" +#include "web_root.h" #include #include @@ -12,23 +12,25 @@ #include #include -void WebApplication::load_settings() { +#include "core/http/web_server.h" + +void WebRoot::load_settings() { } -void WebApplication::setup_routes() { - default_error_handler_func = WebApplication::default_fallback_error_handler; +void WebRoot::setup_routes() { + default_error_handler_func = WebRoot::default_fallback_error_handler; - error_handler_map[404] = WebApplication::default_404_error_handler; + error_handler_map[404] = WebRoot::default_404_error_handler; } -void WebApplication::setup_middleware() { +void WebRoot::setup_middleware() { //If you want sessions add this to your inherited class. Should probably be the first one. //middlewares.push_back(HandlerInstance(::SessionManager::session_setup_middleware)); middlewares.push_back(HandlerInstance([this](Object *instance, Request *request){ this->default_routing_middleware(instance, request); })); } -void WebApplication::default_routing_middleware(Object *instance, Request *request) { +void WebRoot::default_routing_middleware(Object *instance, Request *request) { std::string path = request->get_path_full(); if (FileCache::get_singleton()->wwwroot_has_file(path)) { @@ -63,25 +65,25 @@ void WebApplication::default_routing_middleware(Object *instance, Request *reque request->next_stage(); } -void WebApplication::default_fallback_error_handler(int error_code, Request *request) { +void WebRoot::default_fallback_error_handler(int error_code, Request *request) { request->compiled_body = default_generic_error_body; request->send(); } -void WebApplication::default_404_error_handler(int error_code, Request *request) { +void WebRoot::default_404_error_handler(int error_code, Request *request) { request->compiled_body = default_error_404_body; request->send(); } -void WebApplication::handle_request(Request *request) { +void WebRoot::handle_request_main(Request *request) { request->middleware_stack = &middlewares; - //note that middlewares handle the routing -> WebApplication::default_routing_middleware by default + //note that middlewares handle the routing -> WebRoot::default_routing_middleware by default request->next_stage(); } -void WebApplication::send_error(int error_code, Request *request) { +void WebRoot::send_error(int error_code, Request *request) { std::function func = error_handler_map[error_code]; if (!func) { @@ -92,21 +94,21 @@ void WebApplication::send_error(int error_code, Request *request) { func(error_code, request); } -void WebApplication::send_file(const std::string &path, Request *request) { +void WebRoot::send_file(const std::string &path, Request *request) { std::string fp = FileCache::get_singleton()->wwwroot + path; request->send_file(fp); } -void WebApplication::migrate() { +void WebRoot::migrate() { } -void WebApplication::register_request_update(Request *request) { +void WebRoot::register_request_update(Request *request) { std::lock_guard lock(_update_registered_requests_mutex); _update_registered_requests.push_back(request); } -void WebApplication::unregister_request_update(Request *request) { +void WebRoot::unregister_request_update(Request *request) { std::lock_guard lock(_update_registered_requests_mutex); std::size_t s = _update_registered_requests.size(); @@ -123,7 +125,7 @@ void WebApplication::unregister_request_update(Request *request) { } } -void WebApplication::update() { +void WebRoot::update() { for (std::size_t i = 0; i < _update_registered_requests.size(); ++i) { Request *r = _update_registered_requests[i]; @@ -131,14 +133,19 @@ void WebApplication::update() { } } -WebApplication::WebApplication() { +WebServer *WebRoot::get_server() { + //todo this shoult probably be cached + return Object::cast_to(get_tree()); } -WebApplication::~WebApplication() { +WebRoot::WebRoot() : WebNode() { +} + +WebRoot::~WebRoot() { main_route_map.clear(); error_handler_map.clear(); middlewares.clear(); } -std::string WebApplication::default_error_404_body = "404 :("; -std::string WebApplication::default_generic_error_body = "Internal server error! :("; +std::string WebRoot::default_error_404_body = "404 :("; +std::string WebRoot::default_generic_error_body = "Internal server error! :("; diff --git a/core/http/web_application.h b/core/http/web_root.h similarity index 82% rename from core/http/web_application.h rename to core/http/web_root.h index f8b1c80..7de459a 100644 --- a/core/http/web_application.h +++ b/core/http/web_root.h @@ -1,7 +1,7 @@ -#ifndef WEB_APPLICATION_H -#define WEB_APPLICATION_H +#ifndef WEB_ROOT_H +#define WEB_ROOT_H -#include "core/object.h" +#include "core/http/web_node.h" #include #include #include @@ -12,15 +12,16 @@ #include "handler_instance.h" class Request; +class WebServer; -class WebApplication : public Object { - RCPP_OBJECT(WebApplication, Object); +class WebRoot : public WebNode { + RCPP_OBJECT(WebRoot, WebNode); public: static std::string default_error_404_body; static std::string default_generic_error_body; - void handle_request(Request *request); + void handle_request_main(Request *request); void send_error(int error_code, Request *request); void send_file(const std::string &path, Request *request); @@ -39,8 +40,10 @@ public: void unregister_request_update(Request *request); void update(); - WebApplication(); - virtual ~WebApplication(); + WebServer *get_server(); + + WebRoot(); + virtual ~WebRoot(); public: HandlerInstance index_func; diff --git a/core/http/web_server.cpp b/core/http/web_server.cpp new file mode 100644 index 0000000..ca81382 --- /dev/null +++ b/core/http/web_server.cpp @@ -0,0 +1,31 @@ +#include "web_server.h" + +#include "request.h" +#include "core/http/web_root.h" + +WebRoot *WebServer::get_web_root() { + return _web_root; +} + +void WebServer::set_root(Node *root) { + WebRoot *web_root = Object::cast_to(root); + + ERR_FAIL_COND(!web_root); + + _web_root = web_root; + + NodeTree::set_root(root); +} + +void WebServer::handle_request(Request *request) { + ERR_FAIL_COND(!_web_root); + + _web_root->handle_request_main(request); +} + + +WebServer::WebServer() { +} + +WebServer::~WebServer() { +} diff --git a/core/http/web_server.h b/core/http/web_server.h new file mode 100644 index 0000000..48f4379 --- /dev/null +++ b/core/http/web_server.h @@ -0,0 +1,27 @@ +#ifndef WEB_SERVER_H +#define WEB_SERVER_H + +#include "core/nodes/node_tree.h" + +class Request; +class WebRoot; + +class WebServer : public NodeTree { + RCPP_OBJECT(WebServer, NodeTree); + +public: + WebRoot *get_web_root(); + + void set_root(Node *root); + + void handle_request(Request *request); + + WebServer(); + virtual ~WebServer(); + +protected: + WebRoot *_web_root; + +}; + +#endif \ No newline at end of file diff --git a/modules/drogon/web_application.cpp b/modules/drogon/web_application.cpp index 432038f..fd2ed49 100644 --- a/modules/drogon/web_application.cpp +++ b/modules/drogon/web_application.cpp @@ -27,22 +27,6 @@ #include #endif -void DWebApplication::load_settings() { -} - -void DWebApplication::setup_routes() { - default_error_handler_func = WebApplication::default_fallback_error_handler; - - error_handler_map[404] = WebApplication::default_404_error_handler; -} - -void DWebApplication::setup_middleware() { - middlewares.push_back(HandlerInstance([this](Object *instance, Request *request) { this->default_routing_middleware(instance, request); })); -} - -void DWebApplication::migrate() { -} - void DWebApplication::add_listener(const std::string &ip, uint16_t port, bool useSSL, const std::string &certFile, const std::string &keyFile, bool useOldTLS, const std::vector > &sslConfCmds) { assert(!_running); @@ -540,7 +524,7 @@ void DWebApplication::on_async_request(const HttpRequestImplPtr &req, std::funct //callback(resp); DRequest *request = DRequest::get(); - request->application = this; + request->server = this; request->request = std::shared_ptr(req); request->callback = callback; //std::move(callback); @@ -656,8 +640,8 @@ void DWebApplication::find_session_for_request(const HttpRequestImplPtr &req) { //void forward(const HttpRequestPtr &req, std::function &&callback,const std::string &hostString,double timeout); //void forward(const HttpRequestImplPtr &req,std::function &&callback,const std::string &hostString,double timeout = 0); -DWebApplication::DWebApplication() : - _listener_manager(new ListenerManager()) { +DWebApplication::DWebApplication() : + _listener_manager(new ListenerManager()), WebServer() { //staticFileRouterPtr_(new StaticFileRouter{}), /* httpCtrlsRouterPtr_(new HttpControllersRouter(*staticFileRouterPtr_, @@ -687,7 +671,4 @@ DWebApplication::DWebApplication() : } DWebApplication::~DWebApplication() { - main_route_map.clear(); - error_handler_map.clear(); - middlewares.clear(); } diff --git a/modules/drogon/web_application.h b/modules/drogon/web_application.h index 71507b9..1bd2330 100644 --- a/modules/drogon/web_application.h +++ b/modules/drogon/web_application.h @@ -1,7 +1,7 @@ #ifndef DWEB_APPLICATION_H #define DWEB_APPLICATION_H -#include "core/http/web_application.h" +#include "core/http/web_server.h" #include "core/object.h" #include @@ -9,6 +9,7 @@ #include #include +#include #include #include "core/http/handler_instance.h" @@ -29,16 +30,10 @@ using namespace drogon; class Request; -class DWebApplication : public WebApplication { - RCPP_OBJECT(DWebApplication, WebApplication); +class DWebApplication : public WebServer { + RCPP_OBJECT(DWebApplication, WebServer); public: - void load_settings(); - void setup_routes(); - void setup_middleware(); - - void migrate(); - void add_listener(const std::string &ip, uint16_t port, bool useSSL = false, const std::string &certFile = "", const std::string &keyFile = "", bool useOldTLS = false, const std::vector > &sslConfCmds = {}); @@ -198,7 +193,7 @@ protected: std::string _home_page_file{ "index.html" }; const std::unique_ptr _listener_manager; - std::unique_ptr _session_manager; + std::unique_ptr _session_manager; bool _enable_server_header{ true }; bool _enable_date_header{ true }; diff --git a/modules/paged_article/paged_article.cpp b/modules/paged_article/paged_article.cpp index 55cedf7..2e157c7 100644 --- a/modules/paged_article/paged_article.cpp +++ b/modules/paged_article/paged_article.cpp @@ -8,8 +8,6 @@ #include #include -#include "core/http/web_application.h" - void PagedArticle::index(Request *request) { const String r = request->get_current_path_segment();