Skip to content

Commit 45ff776

Browse files
authored
added documentation and a lot of refactoring (#21)
1 parent 7c03672 commit 45ff776

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1085
-168
lines changed

include/webframe.hpp

Lines changed: 135 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#include <unordered_map>
2929

3030
#include <webframe/application.hpp>
31+
#include <webframe/config.hpp>
32+
#include <webframe/context.hpp>
3133
#include <webframe/exception.hpp>
3234
#include <webframe/handler.hpp>
3335
#include <webframe/router.hpp>
@@ -43,8 +45,18 @@
4345
#include <windows.h>
4446
#endif
4547

48+
/**
49+
* @file webframe.hpp
50+
* @brief WebFrame API
51+
* @author John R Patek Sr <johnpatek2@gmail.com>
52+
*/
4653
namespace webframe
4754
{
55+
/**
56+
* @enum method
57+
* @brief HTTP methods supported by WebFrame
58+
* @details Basic CRUD operations via the HTTP methods GET, POST, PUT, and DELETE.
59+
*/
4860
enum class method
4961
{
5062
http_get,
@@ -53,58 +65,161 @@ namespace webframe
5365
http_delete
5466
};
5567

68+
/**
69+
* @class request
70+
* @brief abstract interface for HTTP requests
71+
* @details Common abstraction for all WebFrame runtimes to process HTTP requests.
72+
*/
5673
class request
5774
{
5875
public:
76+
/**
77+
* @brief get the HTTP method of the request
78+
* @return the HTTP method of the request
79+
*/
5980
virtual method get_method() const = 0;
81+
/**
82+
* @brief get the path of the request
83+
* @return the path of the request
84+
*/
6085
virtual std::string get_path() const = 0;
86+
87+
/**
88+
* @brief get the value of a specific header
89+
* @param key the header key
90+
* @param value reference to the header value
91+
* @return true if the header exists, false otherwise. The string reference will only
92+
* be set if the header exists.
93+
*/
6194
virtual bool get_header(const std::string &key, std::string &value) const = 0;
95+
96+
/**
97+
* @brief get the body of the request as a pointer and size
98+
* @return a pair containing a pointer to the body data and the size of the body
99+
* @details The body data is not guaranteed to be null-terminated. The pointer and size are only
100+
* valid for the duration of the request handling. If the request does not have a body, the pointer
101+
* will be null and the size will be zero.
102+
*/
62103
virtual std::pair<const uint8_t *, size_t> get_body() const = 0;
104+
105+
/**
106+
* @brief read the body of the request using a callback
107+
* @param callback a function to be called with the body data and size
108+
* @details The callback will be called with chunks of the body data. None of the runtimes are
109+
* currently capable of streaming request bodies, so the callback will be called at most once with the
110+
* entire body. If there is no request body, the callback will not be called.
111+
*/
63112
virtual void read_body(const std::function<void(const uint8_t *, size_t)> &callback) const = 0;
64113
};
65114

115+
/**
116+
* @class response
117+
* @brief abstract interface for HTTP responses
118+
* @details Common abstraction for all WebFrame runtimes to generate HTTP responses.
119+
*/
66120
class response
67121
{
68122
public:
123+
/**
124+
* @brief set the HTTP status code of the response
125+
* @param status_code the HTTP status code
126+
* @details The status code is not checked against valid HTTP status codes. It can be set to
127+
* any integer value, but there is no guarantee that the runtime implementation will accept it.
128+
*/
69129
virtual void set_status(int status_code) = 0;
130+
131+
/**
132+
* @brief set a header of the response
133+
* @param key the header key
134+
* @param value the header value
135+
* @details The headers are not validated, and there is no standard way to handle duplicate entries.
136+
*/
70137
virtual void set_header(const std::string &key, const std::string &value) = 0;
138+
139+
/**
140+
* @brief set the body of the response
141+
* @param data pointer to the body data
142+
* @param size the size of the body data
143+
* @details This must be called once after the status and headers have been set. If it is called
144+
* before, the status will be 200 and the headers will be empty. There is no standard way to handle
145+
* multiple calls.
146+
*/
71147
virtual void set_body(const uint8_t *data, size_t size) = 0;
72-
virtual void write_body(const std::function<bool(std::pair<const uint8_t *, size_t> &)> &callback) = 0 ;
73-
};
74-
75148

149+
/**
150+
* @brief write the body of the response using a callback
151+
* @param callback a function to be called with a chunk to set the body data and size.
152+
* @details The callback will be called with chunks of the body data until it returns false to indicate
153+
* end-of-stream. The callback will always be called at least once, and will only populate the chunk if
154+
* the data is not null and the size is greater than zero.
155+
*/
156+
virtual void write_body(const std::function<bool(std::pair<const uint8_t *, size_t> &)> &callback) = 0;
157+
};
76158

159+
/**
160+
* @class runtime
161+
* @brief abstract interface for WebFrame runtimes
162+
* @details Given an application and a router, the runtime is responsible for abstracting HTTP traffic from the
163+
* underlying platform. The user will rarely, if ever, interact with this interface directly.
164+
*/
77165
class runtime
78166
{
79167
public:
80168
#ifdef WEBFRAME_WIN32_APP
169+
/**
170+
* @brief dispatch the application using the Win32 API
171+
* @param hInstance the handle to the current instance of the application
172+
* @param hPrevInstance the handle to the previous instance of the application (always null)
173+
* @param lpCmdLine the command line arguments as a single string
174+
* @param nCmdShow the show state of the application window
175+
* @param a the application to dispatch
176+
* @param r the router to use for dispatching requests
177+
* @return the exit code of the application
178+
* @details This is only used for the Win32 desktop runtime. You should not call this directly. Use the WEBFRAME_MAIN macro
179+
* to define the entry point of your application, and it will call this function for you.
180+
*/
81181
virtual int dispatch(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow, application *a, router *r) = 0;
82182
#else
183+
/**
184+
* @brief dispatch the application using the standard C++ API
185+
* @param argc the number of command line arguments
186+
* @param argv the command line arguments as an array of strings
187+
* @param a the application to dispatch
188+
* @param r the router to use for dispatching requests
189+
* @return the exit code of the application
190+
* @details This is used for all non-Win32 runtimes, including Windows servers. Like the other dispatch function, it
191+
* should not be called directly.
192+
*/
83193
virtual int dispatch(int argc, const char **argv, application *a, router *r) = 0;
84194
#endif
85195
};
86196

87-
runtime *webframe_init();
197+
/**
198+
* @brief create a WebFrame runtime instance
199+
* @return a pointer to a WebFrame runtime instance
200+
* @details Stub for constructing a runtime. The actual implementation is determined by the runtime library.
201+
*/
202+
runtime *create_runtime();
88203
}
89204

90205
#if defined(WEBFRAME_WIN32_APP)
91-
#define WEBFRAME_MAIN(AppType) \
92-
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) \
93-
{ \
94-
std::unique_ptr<webframe::runtime> runtime(webframe::webframe_init()); \
95-
AppType app; \
96-
webframe::router router; \
97-
return runtime->dispatch(hInstance, hPrevInstance, lpCmdLine, nCmdShow, &app, &router); \
98-
}
206+
#define WEBFRAME_MAIN(AppType) \
207+
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) \
208+
{ \
209+
std::unique_ptr<webframe::runtime> runtime(webframe::create_runtime()); \
210+
AppType app; \
211+
webframe::router router; \
212+
return runtime->dispatch(hInstance, hPrevInstance, lpCmdLine, nCmdShow, &app, &router); \
213+
}
99214
#else
100-
#define WEBFRAME_MAIN(AppType) \
101-
int main(int argc, const char **argv) \
102-
{ \
103-
std::unique_ptr<webframe::runtime> runtime(webframe::webframe_init()); \
104-
AppType app; \
105-
webframe::router router; \
106-
return runtime->dispatch(argc, argv, &app, &router); \
107-
}
215+
#define WEBFRAME_MAIN(AppType) \
216+
int main(int argc, const char **argv) \
217+
{ \
218+
std::unique_ptr<webframe::runtime> runtime(webframe::create_runtime()); \
219+
AppType app; \
220+
webframe::router router; \
221+
return runtime->dispatch(argc, argv, &app, &router); \
222+
}
108223
#endif
109224

110225
#endif

include/webframe/application.hpp

Lines changed: 77 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,93 @@
1+
/* WebFrame
2+
*
3+
* Copyright (C) 2026 Maxtek Consulting
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
119
#ifndef WEBFRAME_APPLICATION_HPP
220
#define WEBFRAME_APPLICATION_HPP
321

22+
/**
23+
* @file webframe/application.hpp
24+
* @brief WebFrame application API
25+
* @author John R Patek Sr <johnpatek2@gmail.com>
26+
*/
427
namespace webframe
528
{
29+
class desktop_config;
30+
class desktop_context;
31+
class server_config;
32+
class server_context;
633
class router;
734

35+
/**
36+
* @class application
37+
* @brief abstract interface for WebFrame applications
38+
* @details Represents a single interface for all WebFrame runtimes.
39+
*/
840
class application
941
{
1042
public:
1143
application() = default;
1244
virtual ~application() = default;
13-
virtual void configure_desktop();
14-
virtual void configure_server(int argc, const char **argv);
45+
46+
/**
47+
* @brief configure the application for a desktop runtime
48+
* @param config the desktop configuration for the application
49+
* @details This is only used for desktop runtimes. Does not need to
50+
* be implemented for server-only applications.
51+
*/
52+
virtual void configure_desktop(desktop_config *config);
53+
54+
/**
55+
* @brief configure the application for a server runtime
56+
* @param config the server configuration for the application
57+
* @param argc the number of command-line arguments
58+
* @param argv the command-line arguments
59+
* @details This is only used for server runtimes. Does not need to
60+
* be implemented for desktop-only applications.
61+
*/
62+
virtual void configure_server(server_config *config, int argc, const char **argv);
63+
64+
/**
65+
* @brief configure the router for the application
66+
* @param router the router to configure
67+
* @details This is used to set handlers for HTTP traffic. This method
68+
* should always be implemented, or the application will be unable to
69+
* handle requests.
70+
*/
1571
virtual void configure_router(router *ctrl);
16-
virtual void on_dispatch();
72+
73+
/**
74+
* @brief launch the application in a desktop runtime
75+
* @param context the desktop context to use for launching the application
76+
* @details This is only used for desktop runtimes. The base implmentation will
77+
* create a single window with the default size and load /index.html from the
78+
* router. The context pointer will remain valid while the application is running,
79+
* so it can be used to create additional windows or perform other operations.
80+
*/
81+
virtual void launch_desktop(desktop_context *context);
82+
83+
/**
84+
* @brief launch the application in a server runtime
85+
* @param context the server context to use for launching the application
86+
* @details This is only used for server runtimes. The base implementation will
87+
* register SIGINT as the kill signal. The context pointer will remain valid while
88+
* the application is running.
89+
*/
90+
virtual void launch_server(server_context *context);
1791
};
1892
}
1993

include/webframe/config.hpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* WebFrame
2+
*
3+
* Copyright (C) 2026 Maxtek Consulting
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU Lesser General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public License
16+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef WEBFRAME_CONFIG_HPP
20+
#define WEBFRAME_CONFIG_HPP
21+
22+
#include <optional>
23+
#include <string>
24+
25+
/**
26+
* @file webframe/config.hpp
27+
* @brief WebFrame configuration API
28+
* @author John R Patek Sr <johnpatek2@gmail.com>
29+
*/
30+
namespace webframe
31+
{
32+
class desktop_config
33+
{
34+
public:
35+
desktop_config() = default;
36+
~desktop_config() = default;
37+
38+
void set_dark_mode(bool dark_mode);
39+
void set_default_window_size(int width, int height);
40+
41+
bool get_dark_mode(bool &dark_mode) const;
42+
std::pair<int, int> get_default_window_size() const;
43+
44+
private:
45+
std::optional<bool> _force_dark_mode;
46+
std::pair<int, int> _default_window_size = {800, 600};
47+
};
48+
49+
class server_config
50+
{
51+
public:
52+
server_config() = default;
53+
~server_config() = default;
54+
55+
void set_host(const std::string &host);
56+
void set_port(uint16_t port);
57+
58+
std::string get_host() const;
59+
uint16_t get_port() const;
60+
61+
private:
62+
std::string _host;
63+
uint16_t _port;
64+
};
65+
}
66+
67+
#endif

0 commit comments

Comments
 (0)