From 60828a463f24ccf431372e933bfecd05ae242e0f Mon Sep 17 00:00:00 2001 From: "John R. Patek" Date: Wed, 25 Mar 2026 23:14:20 -0500 Subject: [PATCH] added documentation and a lot of refactoring --- include/webframe.hpp | 155 +++++++++++++++--- include/webframe/application.hpp | 80 ++++++++- include/webframe/config.hpp | 67 ++++++++ include/webframe/context.hpp | 60 +++++++ include/webframe/controller.hpp | 0 include/webframe/exception.hpp | 18 ++ include/webframe/handler.hpp | 18 ++ include/webframe/router.hpp | 18 ++ src/CMakeLists.txt | 2 +- src/application.cpp | 30 +++- src/config.cpp | 49 ++++++ src/context.cpp | 28 ++++ src/exception.cpp | 18 ++ src/handler.cpp | 18 ++ src/router.cpp | 18 ++ src/runtimes/desktop/context.cpp | 40 +++++ src/runtimes/desktop/desktop.hpp | 67 -------- src/runtimes/desktop/include/desktop.hpp | 15 ++ .../desktop/include/desktop/context.hpp | 24 +++ .../desktop/include/desktop/request.hpp | 25 +++ .../desktop/include/desktop/response.hpp | 24 +++ .../desktop/include/desktop/runtime.hpp | 33 ++++ .../desktop/include/desktop/webview.hpp | 23 +++ .../desktop/include/desktop/window.hpp | 31 ++++ .../desktop/include/desktop/wxwidgets.hpp | 11 ++ src/runtimes/desktop/runtime.cpp | 43 ++--- src/runtimes/desktop/webview.cpp | 55 +++++++ src/runtimes/desktop/webview_handler.cpp | 25 --- src/runtimes/desktop/window.cpp | 53 ++++++ src/runtimes/mock/runtime.cpp | 11 +- src/runtimes/server/context.cpp | 13 ++ src/runtimes/server/runtime.cpp | 8 +- src/runtimes/server/server.hpp | 11 ++ tests/include/test.hpp | 21 ++- tests/include/test/application.hpp | 19 ++- tests/include/test/client.hpp | 18 ++ tests/include/test/message.hpp | 18 ++ tests/src/application.cpp | 23 ++- tests/src/client.cpp | 18 ++ tests/src/main.cpp | 18 ++ tests/src/message.cpp | 27 ++- 41 files changed, 1085 insertions(+), 168 deletions(-) create mode 100644 include/webframe/config.hpp create mode 100644 include/webframe/context.hpp delete mode 100644 include/webframe/controller.hpp create mode 100644 src/config.cpp create mode 100644 src/context.cpp create mode 100644 src/runtimes/desktop/context.cpp delete mode 100644 src/runtimes/desktop/desktop.hpp create mode 100644 src/runtimes/desktop/include/desktop.hpp create mode 100644 src/runtimes/desktop/include/desktop/context.hpp create mode 100644 src/runtimes/desktop/include/desktop/request.hpp create mode 100644 src/runtimes/desktop/include/desktop/response.hpp create mode 100644 src/runtimes/desktop/include/desktop/runtime.hpp create mode 100644 src/runtimes/desktop/include/desktop/webview.hpp create mode 100644 src/runtimes/desktop/include/desktop/window.hpp create mode 100644 src/runtimes/desktop/include/desktop/wxwidgets.hpp create mode 100644 src/runtimes/desktop/webview.cpp delete mode 100644 src/runtimes/desktop/webview_handler.cpp create mode 100644 src/runtimes/desktop/window.cpp create mode 100644 src/runtimes/server/context.cpp diff --git a/include/webframe.hpp b/include/webframe.hpp index 70b38e7..fbe1ce9 100644 --- a/include/webframe.hpp +++ b/include/webframe.hpp @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include #include @@ -43,8 +45,18 @@ #include #endif +/** + * @file webframe.hpp + * @brief WebFrame API + * @author John R Patek Sr + */ namespace webframe { + /** + * @enum method + * @brief HTTP methods supported by WebFrame + * @details Basic CRUD operations via the HTTP methods GET, POST, PUT, and DELETE. + */ enum class method { http_get, @@ -53,58 +65,161 @@ namespace webframe http_delete }; + /** + * @class request + * @brief abstract interface for HTTP requests + * @details Common abstraction for all WebFrame runtimes to process HTTP requests. + */ class request { public: + /** + * @brief get the HTTP method of the request + * @return the HTTP method of the request + */ virtual method get_method() const = 0; + /** + * @brief get the path of the request + * @return the path of the request + */ virtual std::string get_path() const = 0; + + /** + * @brief get the value of a specific header + * @param key the header key + * @param value reference to the header value + * @return true if the header exists, false otherwise. The string reference will only + * be set if the header exists. + */ virtual bool get_header(const std::string &key, std::string &value) const = 0; + + /** + * @brief get the body of the request as a pointer and size + * @return a pair containing a pointer to the body data and the size of the body + * @details The body data is not guaranteed to be null-terminated. The pointer and size are only + * valid for the duration of the request handling. If the request does not have a body, the pointer + * will be null and the size will be zero. + */ virtual std::pair get_body() const = 0; + + /** + * @brief read the body of the request using a callback + * @param callback a function to be called with the body data and size + * @details The callback will be called with chunks of the body data. None of the runtimes are + * currently capable of streaming request bodies, so the callback will be called at most once with the + * entire body. If there is no request body, the callback will not be called. + */ virtual void read_body(const std::function &callback) const = 0; }; + /** + * @class response + * @brief abstract interface for HTTP responses + * @details Common abstraction for all WebFrame runtimes to generate HTTP responses. + */ class response { public: + /** + * @brief set the HTTP status code of the response + * @param status_code the HTTP status code + * @details The status code is not checked against valid HTTP status codes. It can be set to + * any integer value, but there is no guarantee that the runtime implementation will accept it. + */ virtual void set_status(int status_code) = 0; + + /** + * @brief set a header of the response + * @param key the header key + * @param value the header value + * @details The headers are not validated, and there is no standard way to handle duplicate entries. + */ virtual void set_header(const std::string &key, const std::string &value) = 0; + + /** + * @brief set the body of the response + * @param data pointer to the body data + * @param size the size of the body data + * @details This must be called once after the status and headers have been set. If it is called + * before, the status will be 200 and the headers will be empty. There is no standard way to handle + * multiple calls. + */ virtual void set_body(const uint8_t *data, size_t size) = 0; - virtual void write_body(const std::function &)> &callback) = 0 ; - }; - + /** + * @brief write the body of the response using a callback + * @param callback a function to be called with a chunk to set the body data and size. + * @details The callback will be called with chunks of the body data until it returns false to indicate + * end-of-stream. The callback will always be called at least once, and will only populate the chunk if + * the data is not null and the size is greater than zero. + */ + virtual void write_body(const std::function &)> &callback) = 0; + }; + /** + * @class runtime + * @brief abstract interface for WebFrame runtimes + * @details Given an application and a router, the runtime is responsible for abstracting HTTP traffic from the + * underlying platform. The user will rarely, if ever, interact with this interface directly. + */ class runtime { public: #ifdef WEBFRAME_WIN32_APP + /** + * @brief dispatch the application using the Win32 API + * @param hInstance the handle to the current instance of the application + * @param hPrevInstance the handle to the previous instance of the application (always null) + * @param lpCmdLine the command line arguments as a single string + * @param nCmdShow the show state of the application window + * @param a the application to dispatch + * @param r the router to use for dispatching requests + * @return the exit code of the application + * @details This is only used for the Win32 desktop runtime. You should not call this directly. Use the WEBFRAME_MAIN macro + * to define the entry point of your application, and it will call this function for you. + */ virtual int dispatch(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, application *a, router *r) = 0; #else + /** + * @brief dispatch the application using the standard C++ API + * @param argc the number of command line arguments + * @param argv the command line arguments as an array of strings + * @param a the application to dispatch + * @param r the router to use for dispatching requests + * @return the exit code of the application + * @details This is used for all non-Win32 runtimes, including Windows servers. Like the other dispatch function, it + * should not be called directly. + */ virtual int dispatch(int argc, const char **argv, application *a, router *r) = 0; #endif }; - runtime *webframe_init(); + /** + * @brief create a WebFrame runtime instance + * @return a pointer to a WebFrame runtime instance + * @details Stub for constructing a runtime. The actual implementation is determined by the runtime library. + */ + runtime *create_runtime(); } #if defined(WEBFRAME_WIN32_APP) - #define WEBFRAME_MAIN(AppType) \ - int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) \ - { \ - std::unique_ptr runtime(webframe::webframe_init()); \ - AppType app; \ - webframe::router router; \ - return runtime->dispatch(hInstance, hPrevInstance, lpCmdLine, nCmdShow, &app, &router); \ - } +#define WEBFRAME_MAIN(AppType) \ + int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) \ + { \ + std::unique_ptr runtime(webframe::create_runtime()); \ + AppType app; \ + webframe::router router; \ + return runtime->dispatch(hInstance, hPrevInstance, lpCmdLine, nCmdShow, &app, &router); \ + } #else - #define WEBFRAME_MAIN(AppType) \ - int main(int argc, const char **argv) \ - { \ - std::unique_ptr runtime(webframe::webframe_init()); \ - AppType app; \ - webframe::router router; \ - return runtime->dispatch(argc, argv, &app, &router); \ - } +#define WEBFRAME_MAIN(AppType) \ + int main(int argc, const char **argv) \ + { \ + std::unique_ptr runtime(webframe::create_runtime()); \ + AppType app; \ + webframe::router router; \ + return runtime->dispatch(argc, argv, &app, &router); \ + } #endif #endif diff --git a/include/webframe/application.hpp b/include/webframe/application.hpp index d0d013d..beab897 100644 --- a/include/webframe/application.hpp +++ b/include/webframe/application.hpp @@ -1,19 +1,93 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_APPLICATION_HPP #define WEBFRAME_APPLICATION_HPP +/** + * @file webframe/application.hpp + * @brief WebFrame application API + * @author John R Patek Sr + */ namespace webframe { + class desktop_config; + class desktop_context; + class server_config; + class server_context; class router; + /** + * @class application + * @brief abstract interface for WebFrame applications + * @details Represents a single interface for all WebFrame runtimes. + */ class application { public: application() = default; virtual ~application() = default; - virtual void configure_desktop(); - virtual void configure_server(int argc, const char **argv); + + /** + * @brief configure the application for a desktop runtime + * @param config the desktop configuration for the application + * @details This is only used for desktop runtimes. Does not need to + * be implemented for server-only applications. + */ + virtual void configure_desktop(desktop_config *config); + + /** + * @brief configure the application for a server runtime + * @param config the server configuration for the application + * @param argc the number of command-line arguments + * @param argv the command-line arguments + * @details This is only used for server runtimes. Does not need to + * be implemented for desktop-only applications. + */ + virtual void configure_server(server_config *config, int argc, const char **argv); + + /** + * @brief configure the router for the application + * @param router the router to configure + * @details This is used to set handlers for HTTP traffic. This method + * should always be implemented, or the application will be unable to + * handle requests. + */ virtual void configure_router(router *ctrl); - virtual void on_dispatch(); + + /** + * @brief launch the application in a desktop runtime + * @param context the desktop context to use for launching the application + * @details This is only used for desktop runtimes. The base implmentation will + * create a single window with the default size and load /index.html from the + * router. The context pointer will remain valid while the application is running, + * so it can be used to create additional windows or perform other operations. + */ + virtual void launch_desktop(desktop_context *context); + + /** + * @brief launch the application in a server runtime + * @param context the server context to use for launching the application + * @details This is only used for server runtimes. The base implementation will + * register SIGINT as the kill signal. The context pointer will remain valid while + * the application is running. + */ + virtual void launch_server(server_context *context); }; } diff --git a/include/webframe/config.hpp b/include/webframe/config.hpp new file mode 100644 index 0000000..b7a4416 --- /dev/null +++ b/include/webframe/config.hpp @@ -0,0 +1,67 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef WEBFRAME_CONFIG_HPP +#define WEBFRAME_CONFIG_HPP + +#include +#include + +/** + * @file webframe/config.hpp + * @brief WebFrame configuration API + * @author John R Patek Sr + */ +namespace webframe +{ + class desktop_config + { + public: + desktop_config() = default; + ~desktop_config() = default; + + void set_dark_mode(bool dark_mode); + void set_default_window_size(int width, int height); + + bool get_dark_mode(bool &dark_mode) const; + std::pair get_default_window_size() const; + + private: + std::optional _force_dark_mode; + std::pair _default_window_size = {800, 600}; + }; + + class server_config + { + public: + server_config() = default; + ~server_config() = default; + + void set_host(const std::string &host); + void set_port(uint16_t port); + + std::string get_host() const; + uint16_t get_port() const; + + private: + std::string _host; + uint16_t _port; + }; +} + +#endif \ No newline at end of file diff --git a/include/webframe/context.hpp b/include/webframe/context.hpp new file mode 100644 index 0000000..156f95f --- /dev/null +++ b/include/webframe/context.hpp @@ -0,0 +1,60 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#ifndef WEBFRAME_CONTEXT_HPP +#define WEBFRAME_CONTEXT_HPP + +/** + * @file webframe/context.hpp + * @brief WebFrame context API + * @author John R Patek Sr + */ + +#include +#include + +namespace webframe +{ + class window + { + public: + virtual void load_url(const std::string& url) = 0; + virtual void load_path(const std::string& path) = 0; + virtual std::string get_id() const = 0; + }; + + class desktop_context + { + public: + desktop_context() = default; + ~desktop_context() = default; + virtual window* create_window(window *parent, int width = -1, int height = -1); + virtual window* find_window(const std::string& id); + virtual void destroy_window(window* handle); + }; + + class server_context + { + public: + server_context() = default; + ~server_context() = default; + virtual void sighandle(int signum); + }; +} + +#endif \ No newline at end of file diff --git a/include/webframe/controller.hpp b/include/webframe/controller.hpp deleted file mode 100644 index e69de29..0000000 diff --git a/include/webframe/exception.hpp b/include/webframe/exception.hpp index 36361b6..3de07d0 100644 --- a/include/webframe/exception.hpp +++ b/include/webframe/exception.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_EXCEPTION_HPP #define WEBFRAME_EXCEPTION_HPP diff --git a/include/webframe/handler.hpp b/include/webframe/handler.hpp index 99aabb7..dadc8aa 100644 --- a/include/webframe/handler.hpp +++ b/include/webframe/handler.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_HANDLER_HPP #define WEBFRAME_HANDLER_HPP diff --git a/include/webframe/router.hpp b/include/webframe/router.hpp index d10f0d9..18be3a6 100644 --- a/include/webframe/router.hpp +++ b/include/webframe/router.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_ROUTER_HPP #define WEBFRAME_ROUTER_HPP diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 851ee36..6a2d5ae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,7 +7,7 @@ if(BUILD_RUNTIME) webframe_add_runtime(NAME desktop SOURCES ${WEBFRAME_SOURCES} ${WEBFRAME_DESKTOP_SOURCES} PUBLIC_INCLUDE_DIRS ${WEBFRAME_INCLUDE_DIR} - PRIVATE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/runtimes/desktop + PRIVATE_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/runtimes/desktop/include PUBLIC_LINK_LIBRARIES wx::core wx::webview) target_compile_definitions(webframe_desktop PUBLIC WEBFRAME_DESKTOP_RUNTIME=1) endif() diff --git a/src/application.cpp b/src/application.cpp index 0a6829f..a3b091b 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -1,13 +1,31 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe { - void application::configure_desktop() + void application::configure_desktop(desktop_config *config) { } - void application::configure_server(int argc, const char **argv) + void application::configure_server(server_config *config, int argc, const char **argv) { } @@ -17,8 +35,14 @@ namespace webframe } - void application::on_dispatch() + void application::launch_desktop(desktop_context *context) { + window *handle = context->create_window(nullptr); + handle->load_path("index.html"); + } + void application::launch_server(server_context *context) + { + context->sighandle(SIGINT); } } \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp new file mode 100644 index 0000000..99266d3 --- /dev/null +++ b/src/config.cpp @@ -0,0 +1,49 @@ +#include + +namespace webframe +{ + void desktop_config::set_dark_mode(bool dark_mode) + { + _force_dark_mode = dark_mode; + } + + bool desktop_config::get_dark_mode(bool &dark_mode) const + { + const bool result(_force_dark_mode.has_value()); + if (result) + { + dark_mode = _force_dark_mode.value(); + } + return result; + } + + std::pair desktop_config::get_default_window_size() const + { + return _default_window_size; + } + + void desktop_config::set_default_window_size(int width, int height) + { + _default_window_size = {width, height}; + } + + void server_config::set_host(const std::string &host) + { + _host = host; + } + + std::string server_config::get_host() const + { + return _host; + } + + void server_config::set_port(uint16_t port) + { + _port = port; + } + + uint16_t server_config::get_port() const + { + return _port; + } +} \ No newline at end of file diff --git a/src/context.cpp b/src/context.cpp new file mode 100644 index 0000000..8d39b41 --- /dev/null +++ b/src/context.cpp @@ -0,0 +1,28 @@ +#include + +namespace webframe +{ + webframe::window* desktop_context::create_window(window *parent, int width, int height) + { + (void)parent; + (void)width; + (void)height; + return nullptr; + } + + webframe::window* desktop_context::find_window(const std::string& id) + { + (void)id; + return nullptr; + } + + void desktop_context::destroy_window(window* handle) + { + (void)handle; + } + + void server_context::sighandle(int signum) + { + (void)signum; + } +} \ No newline at end of file diff --git a/src/exception.cpp b/src/exception.cpp index 7cd9ab6..1f02ed8 100644 --- a/src/exception.cpp +++ b/src/exception.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe diff --git a/src/handler.cpp b/src/handler.cpp index 14a09f4..b669409 100644 --- a/src/handler.cpp +++ b/src/handler.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe diff --git a/src/router.cpp b/src/router.cpp index 7cc2953..1bb0d21 100644 --- a/src/router.cpp +++ b/src/router.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include class global_default_handler : public webframe::handler diff --git a/src/runtimes/desktop/context.cpp b/src/runtimes/desktop/context.cpp new file mode 100644 index 0000000..e93ae93 --- /dev/null +++ b/src/runtimes/desktop/context.cpp @@ -0,0 +1,40 @@ +#include + +namespace webframe::desktop +{ + context::context(webframe::desktop_config *config, webframe::router *router) : _webview_handler(wxSharedPtr(new webframe::desktop::webview_handler(router))) + { + auto const &[default_width, default_height] = config->get_default_window_size(); + _default_width = default_width; + _default_height = default_height; + } + + webframe::window *context::create_window(webframe::window *parent, int width, int height) + { + // TODO: do something with window ID to avoid the reinterpret_cast + webframe::desktop::window *parent_window = reinterpret_cast(parent); + wxFrame *frame = new wxFrame( + parent_window ? parent_window->get_frame() : nullptr, + wxID_ANY, + "WebFrame", + wxDefaultPosition, + wxSize(width > 0 ? width : _default_width, height > 0 ? height : _default_height)); + return new webframe::desktop::window(frame, _webview_handler); + } + + webframe::window *context::find_window(const std::string &id) + { + webframe::window *result(nullptr); + auto it = _windows.find(id); + if (it != _windows.end()) + { + result = it->second.get(); + } + return result; + } + + void context::destroy_window(webframe::window *handle) + { + _windows.erase(handle->get_id()); + } +} \ No newline at end of file diff --git a/src/runtimes/desktop/desktop.hpp b/src/runtimes/desktop/desktop.hpp deleted file mode 100644 index d5edc36..0000000 --- a/src/runtimes/desktop/desktop.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef WEBFRAME_DESKTOP_HPP -#define WEBFRAME_DESKTOP_HPP - -#include - -#include -#include -#include -#include - -class wfApp; - -namespace webframe::desktop -{ - class request : public webframe::request - { - public: - request(const wxWebViewHandlerRequest *request); - ~request() = default; - webframe::method get_method() const override; - std::string get_path() const override; - bool get_header(const std::string &key, std::string &value) const override; - std::pair get_body() const override; - void read_body(const std::function &callback) const override; - private: - const wxWebViewHandlerRequest *_request; - wxString _body; - }; - - class response : public webframe::response - { - public: - response(wxWebViewHandlerResponse *response, bool &sent); - ~response() = default; - void set_status(int status) override; - void set_header(const std::string &key, const std::string &value) override; - void set_body(const uint8_t *data, size_t size) override; - void write_body(const std::function &)> &callback) override; - private: - wxWebViewHandlerResponse *_response; - bool &_sent; - }; - - class webview_handler : public wxWebViewHandler - { - public: - webview_handler(webframe::router *router); - ~webview_handler() = default; - void StartRequest(const wxWebViewHandlerRequest& request, wxSharedPtr response) override; - private: - webframe::router *_router; - }; - - class runtime : public webframe::runtime - { - public: -#ifdef WEBFRAME_WIN32_APP - int dispatch(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, webframe::application *a, webframe::router *r) override; -#else - int dispatch(int argc, const char **argv, webframe::application *a, webframe::router *r) override; -#endif - private: - int launch_wx_app(wfApp *app, webframe::application *a, webframe::router *r); - }; -} - -#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop.hpp b/src/runtimes/desktop/include/desktop.hpp new file mode 100644 index 0000000..381e519 --- /dev/null +++ b/src/runtimes/desktop/include/desktop.hpp @@ -0,0 +1,15 @@ +#ifndef WEBFRAME_DESKTOP_HPP +#define WEBFRAME_DESKTOP_HPP + +#include + +#include +#include +#include +#include +#include +#include + + + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/context.hpp b/src/runtimes/desktop/include/desktop/context.hpp new file mode 100644 index 0000000..59e49a7 --- /dev/null +++ b/src/runtimes/desktop/include/desktop/context.hpp @@ -0,0 +1,24 @@ +#ifndef WEBFRAME_DESKTOP_CONTEXT_HPP +#define WEBFRAME_DESKTOP_CONTEXT_HPP + +#include "wxwidgets.hpp" + +namespace webframe::desktop +{ + class context : public webframe::desktop_context + { + public: + context(webframe::desktop_config *config, webframe::router *router); + ~context() = default; + webframe::window *create_window(webframe::window *parent, int width, int height) override; + webframe::window *find_window(const std::string &id) override; + void destroy_window(webframe::window *handle) override; + + private: + int _default_width; + int _default_height; + std::unordered_map> _windows; + wxSharedPtr _webview_handler; + }; +} +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/request.hpp b/src/runtimes/desktop/include/desktop/request.hpp new file mode 100644 index 0000000..e27e677 --- /dev/null +++ b/src/runtimes/desktop/include/desktop/request.hpp @@ -0,0 +1,25 @@ +#ifndef WEBFRAME_DESKTOP_REQUEST_HPP +#define WEBFRAME_DESKTOP_REQUEST_HPP + +#include "wxwidgets.hpp" + +namespace webframe::desktop +{ + class request : public webframe::request + { + public: + request(const wxWebViewHandlerRequest *request); + ~request() = default; + webframe::method get_method() const override; + std::string get_path() const override; + bool get_header(const std::string &key, std::string &value) const override; + std::pair get_body() const override; + void read_body(const std::function &callback) const override; + + private: + const wxWebViewHandlerRequest *_request; + wxString _body; + }; +} + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/response.hpp b/src/runtimes/desktop/include/desktop/response.hpp new file mode 100644 index 0000000..678ec26 --- /dev/null +++ b/src/runtimes/desktop/include/desktop/response.hpp @@ -0,0 +1,24 @@ +#ifndef WEBFRAME_DESKTOP_RESPONSE_HPP +#define WEBFRAME_DESKTOP_RESPONSE_HPP + +#include "wxwidgets.hpp" + +namespace webframe::desktop +{ + class response : public webframe::response + { + public: + response(wxWebViewHandlerResponse *response, bool &sent); + ~response() = default; + void set_status(int status) override; + void set_header(const std::string &key, const std::string &value) override; + void set_body(const uint8_t *data, size_t size) override; + void write_body(const std::function &)> &callback) override; + + private: + wxWebViewHandlerResponse *_response; + bool &_sent; + }; +} + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/runtime.hpp b/src/runtimes/desktop/include/desktop/runtime.hpp new file mode 100644 index 0000000..048827e --- /dev/null +++ b/src/runtimes/desktop/include/desktop/runtime.hpp @@ -0,0 +1,33 @@ +#ifndef WEBFRAME_DESKTOP_RUNTIME_HPP +#define WEBFRAME_DESKTOP_RUNTIME_HPP + +#include "wxwidgets.hpp" + +class wfApp; + +namespace webframe::desktop +{ + class context; + + struct runtime_data + { + webframe::application *application; + webframe::router *router; + std::unique_ptr context; + }; + + class runtime : public webframe::runtime + { + public: +#ifdef WEBFRAME_WIN32_APP + int dispatch(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, webframe::application *a, webframe::router *r) override; +#else + int dispatch(int argc, const char **argv, webframe::application *a, webframe::router *r) override; +#endif + private: + int launch_wx_app(wfApp *app, webframe::application *a, webframe::router *r); + runtime_data _runtime_data; + }; +} + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/webview.hpp b/src/runtimes/desktop/include/desktop/webview.hpp new file mode 100644 index 0000000..997ee3c --- /dev/null +++ b/src/runtimes/desktop/include/desktop/webview.hpp @@ -0,0 +1,23 @@ +#ifndef WEBFRAME_DESKTOP_WEBVIEW_HPP +#define WEBFRAME_DESKTOP_WEBVIEW_HPP + +#include "wxwidgets.hpp" + +namespace webframe::desktop +{ + class webview_handler : public wxWebViewHandler + { + public: + webview_handler(webframe::router *router); + ~webview_handler() = default; + void StartRequest(const wxWebViewHandlerRequest &request, wxSharedPtr response) override; + + private: + webframe::router *_router; + }; + + wxSharedPtr create_webview_handler(webframe::router *router); + wxWebView *create_webview(wxFrame *frame, wxSharedPtr webview_handler); +} + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/window.hpp b/src/runtimes/desktop/include/desktop/window.hpp new file mode 100644 index 0000000..9cf4830 --- /dev/null +++ b/src/runtimes/desktop/include/desktop/window.hpp @@ -0,0 +1,31 @@ +#ifndef WEBFRAME_DESKTOP_WINDOW_HPP +#define WEBFRAME_DESKTOP_WINDOW_HPP + +#include "wxwidgets.hpp" + +namespace webframe::desktop +{ + class window : public webframe::window + { + public: + window(wxFrame *frame, wxSharedPtr webview_handler); + ~window() = default; + void load_path(const std::string &path) override; + void load_url(const std::string &url) override; + std::string get_id() const override; + + wxFrame *get_frame() const; + + private: + std::unique_ptr _frame; + wxWebView *_webview; + struct webview_data + { + std::atomic created{false}; + std::string initial_url; + wxSharedPtr webview_handler; + } _webview_data; + }; +} + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/include/desktop/wxwidgets.hpp b/src/runtimes/desktop/include/desktop/wxwidgets.hpp new file mode 100644 index 0000000..b7add10 --- /dev/null +++ b/src/runtimes/desktop/include/desktop/wxwidgets.hpp @@ -0,0 +1,11 @@ +#ifndef WEBFRAME_DESKTOP_WXWIDGETS_HPP +#define WEBFRAME_DESKTOP_WXWIDGETS_HPP + +#include + +#include +#include +#include +#include + +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/runtime.cpp b/src/runtimes/desktop/runtime.cpp index d4f60df..c178b36 100644 --- a/src/runtimes/desktop/runtime.cpp +++ b/src/runtimes/desktop/runtime.cpp @@ -3,41 +3,23 @@ class wfApp : public wxApp { public: - void Init(webframe::application *application, webframe::router *router) + void Init(webframe::desktop::runtime_data *runtime_data) { - _application = application; - _router = router; + _runtime_data = runtime_data; } + bool OnInit() override { - _application->configure_desktop(); - _application->configure_router(_router); - _frame = std::make_unique(nullptr, wxID_ANY, "WebFrame"); - _webview = wxWebView::New(_frame.get(), wxID_ANY, "about:blank", wxDefaultPosition, wxDefaultSize, wxWebViewBackendEdge); -#ifdef __WXMSW__ - _webview->Bind(wxEVT_WEBVIEW_NAVIGATING, [](wxWebViewEvent &event) - { - const wxString url = event.GetURL(); - if (!url.StartsWith("https://webframe.ipc")) - { - event.Skip(); - } }); -#endif - _webview->Bind(wxEVT_WEBVIEW_CREATED, [this](wxWebViewEvent &event) - { - wxWebView *webview = reinterpret_cast(event.GetEventObject()); - webview->RegisterHandler(wxSharedPtr(new webframe::desktop::webview_handler(_router))); - webview->LoadURL("https://webframe.ipc/index.html"); - }); - _frame->Show(); + webframe::desktop_config config; + _runtime_data->application->configure_desktop(&config); + _runtime_data->application->configure_router(_runtime_data->router); + _runtime_data->context = std::make_unique(&config, _runtime_data->router); + _runtime_data->application->launch_desktop(_runtime_data->context.get()); return true; } private: - std::unique_ptr _frame; - wxWebView *_webview; - webframe::application *_application; - webframe::router *_router; + webframe::desktop::runtime_data *_runtime_data; }; namespace webframe @@ -47,10 +29,11 @@ namespace webframe int runtime::launch_wx_app(wfApp *app, webframe::application *a, webframe::router *r) { int result(0); - app->Init(a, r); + _runtime_data.application = a; + _runtime_data.router = r; + app->Init(&_runtime_data); if (app->CallOnInit()) { - a->on_dispatch(); result = app->OnRun(); } else @@ -62,7 +45,7 @@ namespace webframe } } - runtime *webframe_init() + runtime *create_runtime() { return new desktop::runtime(); } diff --git a/src/runtimes/desktop/webview.cpp b/src/runtimes/desktop/webview.cpp new file mode 100644 index 0000000..f815372 --- /dev/null +++ b/src/runtimes/desktop/webview.cpp @@ -0,0 +1,55 @@ +#include + +#ifdef __WXMSW__ +static void OnWebViewNavigating(wxWebViewEvent &event); +#endif + +namespace webframe +{ + namespace desktop + { + webview_handler::webview_handler(webframe::router *router) : wxWebViewHandler("https"), _router(router) + { + SetVirtualHost("webframe.ipc"); + } + + void webview_handler::StartRequest(const wxWebViewHandlerRequest& request, wxSharedPtr response) + { + bool sent(false); + webframe::desktop::request req(&request); + webframe::desktop::response res(response.get(), sent); + webframe::handler *handler = _router->find_route(req.get_path()); + handler->handle_request(&req, &res); + if (!sent) + { + response->Finish(""); + } + } + + wxSharedPtr create_webview_handler(webframe::router *router) + { + return wxSharedPtr(new webview_handler(router)); + } + + wxWebView *create_webview(wxFrame *frame, wxSharedPtr webview_handler) + { + wxWebView *webview = wxWebView::New(frame, wxID_ANY, "about:blank", wxDefaultPosition, wxDefaultSize, wxWebViewBackendEdge, wxBORDER_NONE); +#ifdef __WXMSW__ + webview->Bind(wxEVT_WEBVIEW_NAVIGATING, OnWebViewNavigating); +#endif + webview->RegisterHandler(webview_handler); + return webview; + } + } +} + +#ifdef __WXMSW__ +void OnWebViewNavigating(wxWebViewEvent &event) +{ + const wxString url = event.GetURL(); + if (!url.StartsWith("https://webframe.ipc")) + { + event.Skip(); + } +} +#endif \ No newline at end of file diff --git a/src/runtimes/desktop/webview_handler.cpp b/src/runtimes/desktop/webview_handler.cpp deleted file mode 100644 index f85667e..0000000 --- a/src/runtimes/desktop/webview_handler.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - -namespace webframe -{ - namespace desktop - { - webview_handler::webview_handler(webframe::router *router) : wxWebViewHandler("https"), _router(router) - { - SetVirtualHost("webframe.ipc"); - } - - void webview_handler::StartRequest(const wxWebViewHandlerRequest& request, wxSharedPtr response) - { - bool sent(false); - webframe::desktop::request req(&request); - webframe::desktop::response res(response.get(), sent); - webframe::handler *handler = _router->find_route(req.get_path()); - handler->handle_request(&req, &res); - if (!sent) - { - response->Finish(""); - } - } - } -} \ No newline at end of file diff --git a/src/runtimes/desktop/window.cpp b/src/runtimes/desktop/window.cpp new file mode 100644 index 0000000..4f409ab --- /dev/null +++ b/src/runtimes/desktop/window.cpp @@ -0,0 +1,53 @@ +#include + +namespace webframe::desktop +{ + window::window(wxFrame *frame, wxSharedPtr webview_handler) : _frame(frame) + { + _webview = webframe::desktop::create_webview(frame, webview_handler); + _webview_data.webview_handler = webview_handler; + _webview->Bind( + wxEVT_WEBVIEW_CREATED, + [this](wxWebViewEvent &event) + { + wxWebView *webview = reinterpret_cast(event.GetEventObject()); + webview->RegisterHandler(_webview_data.webview_handler); + if (!_webview_data.initial_url.empty()) + { + wxString wx_url = wxString(_webview_data.initial_url.c_str()); + webview->LoadURL(wx_url); + } + _webview_data.created = true; + }); + _frame->Show(); + } + + void window::load_path(const std::string &path) + { + const std::string url = "https://webframe.ipc/" + path; + load_url(url); + } + + void window::load_url(const std::string &url) + { + if (_webview_data.created) + { + wxString wx_url = wxString(url.c_str()); + _webview->LoadURL(wx_url); + } + else + { + _webview_data.initial_url = url; + } + } + + std::string window::get_id() const + { + return std::to_string(_frame->GetId()); + } + + wxFrame *window::get_frame() const + { + return _frame.get(); + } +} diff --git a/src/runtimes/mock/runtime.cpp b/src/runtimes/mock/runtime.cpp index 28868a6..43cbbd3 100644 --- a/src/runtimes/mock/runtime.cpp +++ b/src/runtimes/mock/runtime.cpp @@ -14,10 +14,13 @@ namespace webframe int result(0); try { - a->configure_desktop(); - a->configure_server(argc, argv); + webframe::desktop_config desktop_config; + webframe::server_config server_config; + a->configure_desktop(&desktop_config); + a->configure_server(&server_config, argc, argv); a->configure_router(r); - a->on_dispatch(); + a->launch_desktop(nullptr); + a->launch_server(nullptr); } catch(const std::exception& e) { @@ -29,7 +32,7 @@ namespace webframe }; } - runtime *webframe_init() + runtime *create_runtime() { return new mock::runtime(); } diff --git a/src/runtimes/server/context.cpp b/src/runtimes/server/context.cpp new file mode 100644 index 0000000..6a5ce26 --- /dev/null +++ b/src/runtimes/server/context.cpp @@ -0,0 +1,13 @@ +#include + +namespace webframe::server +{ + context::context(event_base *base) : _base(base) + { + } + + void context::sighandle(int signum) + { + + } +} \ No newline at end of file diff --git a/src/runtimes/server/runtime.cpp b/src/runtimes/server/runtime.cpp index bcca62c..28950db 100644 --- a/src/runtimes/server/runtime.cpp +++ b/src/runtimes/server/runtime.cpp @@ -56,13 +56,15 @@ namespace webframe #ifdef _WIN32 winsock_session winsock; #endif - a->configure_server(argc, argv); + webframe::server_config config; + a->configure_server(&config, argc, argv); a->configure_router(r); _event_base.reset(event_base_new()); _http.reset(evhttp_new(_event_base.get())); + _context = std::make_unique(_event_base.get()); evhttp_set_gencb(_http.get(), evhttp_callback, r); listen("0.0.0.0", 8080); - a->on_dispatch(); + a->launch_server(_context.get()); serve(); return 0; } @@ -79,7 +81,7 @@ namespace webframe event_base_loopbreak(_event_base.get()); } } - runtime *webframe_init() + runtime *create_runtime() { return new server::runtime(); } diff --git a/src/runtimes/server/server.hpp b/src/runtimes/server/server.hpp index fc68852..1be501a 100644 --- a/src/runtimes/server/server.hpp +++ b/src/runtimes/server/server.hpp @@ -42,6 +42,16 @@ namespace webframe::server int &_status; }; + class context : public webframe::server_context + { + public: + context(event_base *base); + ~context() = default; + void sighandle(int signum) override; + private: + event_base *_base; + }; + class runtime : public webframe::runtime { public: @@ -53,6 +63,7 @@ namespace webframe::server std::unique_ptr _event_base{nullptr, &event_base_free}; std::unique_ptr _http{nullptr, &evhttp_free}; + std::unique_ptr _context; }; } diff --git a/tests/include/test.hpp b/tests/include/test.hpp index 0946006..a014234 100644 --- a/tests/include/test.hpp +++ b/tests/include/test.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_TEST_HPP #define WEBFRAME_TEST_HPP @@ -14,7 +32,7 @@ namespace webframe::test { static inline void run() { - std::unique_ptr runtime(webframe::webframe_init()); + std::unique_ptr runtime(webframe::create_runtime()); ApplicationType app; webframe::router router; const int actual_result = runtime->dispatch(0, nullptr, &app, &router); @@ -30,7 +48,6 @@ namespace webframe::test #define WEBFRAME_TEST_CASE(TestName) \ MAXTEST_TEST_CASE(webframe::TestName) \ { \ - webframe::test::TestName::run(); \ } #endif \ No newline at end of file diff --git a/tests/include/test/application.hpp b/tests/include/test/application.hpp index 47d595a..3a2ae4e 100644 --- a/tests/include/test/application.hpp +++ b/tests/include/test/application.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_TEST_APPLICATION_HPP #define WEBFRAME_TEST_APPLICATION_HPP @@ -11,7 +29,6 @@ namespace webframe::test { public: void configure_router(webframe::router *router) override; - void on_dispatch() override; protected: virtual void setup_router(webframe::router *router); diff --git a/tests/include/test/client.hpp b/tests/include/test/client.hpp index 12368d4..6ae15dd 100644 --- a/tests/include/test/client.hpp +++ b/tests/include/test/client.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_TEST_CLIENT_HPP #define WEBFRAME_TEST_CLIENT_HPP diff --git a/tests/include/test/message.hpp b/tests/include/test/message.hpp index 50621e4..50d3cc1 100644 --- a/tests/include/test/message.hpp +++ b/tests/include/test/message.hpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #ifndef WEBFRAME_TEST_MESSAGE_HPP #define WEBFRAME_TEST_MESSAGE_HPP diff --git a/tests/src/application.cpp b/tests/src/application.cpp index dd042e5..5e0337b 100644 --- a/tests/src/application.cpp +++ b/tests/src/application.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe::test @@ -13,11 +31,6 @@ namespace webframe::test (void)router; } - void application::on_dispatch() - { - run_tests(_client.get()); - } - void dispatch_error::run_tests(client *c) { (void)c; diff --git a/tests/src/client.cpp b/tests/src/client.cpp index 803996f..c940c9e 100644 --- a/tests/src/client.cpp +++ b/tests/src/client.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe::test diff --git a/tests/src/main.cpp b/tests/src/main.cpp index f99833c..2c349fe 100644 --- a/tests/src/main.cpp +++ b/tests/src/main.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include MAXTEST_MAIN diff --git a/tests/src/message.cpp b/tests/src/message.cpp index 8bbcf6d..827a467 100644 --- a/tests/src/message.cpp +++ b/tests/src/message.cpp @@ -1,3 +1,21 @@ +/* WebFrame + * + * Copyright (C) 2026 Maxtek Consulting + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + #include namespace webframe::test @@ -14,13 +32,14 @@ namespace webframe::test bool request::get_header(const std::string &key, std::string &value) const { + bool result(false); auto it = headers.find(key); - if (it == headers.end()) + if (it != headers.end()) { - return false; + result = true; + value = it->second; } - value = it->second; - return true; + return result; } std::pair request::get_body() const