From 0222b75e8554796548e079aa3393c512ae30ac24 Mon Sep 17 00:00:00 2001 From: Xavier Del Campo Romero Date: Tue, 10 Oct 2023 23:21:35 +0200 Subject: Rename project from slweb to libweb It was found out there was another project of the same name around (https://git.sr.ht/~strahinja/slweb/), also related to website generation. In order to avoid confusion, a new name has been chosen for this project. Surprisingly, libweb was not in use by any distributions (according to https://repology.org and AUR index), and it should reflect well the intention behind this project i.e., being a library to build web-related stuff. --- doc/man3/handler_add.3 | 10 +- doc/man3/handler_alloc.3 | 14 +- doc/man3/handler_free.3 | 6 +- doc/man3/handler_listen.3 | 8 +- doc/man3/html_node_add_attr.3 | 8 +- doc/man3/html_node_add_child.3 | 10 +- doc/man3/html_node_add_sibling.3 | 6 +- doc/man3/html_node_alloc.3 | 8 +- doc/man3/html_node_free.3 | 6 +- doc/man3/html_node_set_value.3 | 8 +- doc/man3/html_node_set_value_unescaped.3 | 8 +- doc/man3/html_serialize.3 | 6 +- doc/man3/http_alloc.3 | 16 +- doc/man3/http_cookie_create.3 | 8 +- doc/man3/http_encode_url.3 | 6 +- doc/man3/http_free.3 | 6 +- doc/man3/http_response_add_header.3 | 6 +- doc/man3/http_update.3 | 8 +- doc/man7/Makefile | 6 +- doc/man7/libweb_handler.7 | 229 +++++++++++ doc/man7/libweb_html.7 | 178 +++++++++ doc/man7/libweb_http.7 | 649 +++++++++++++++++++++++++++++++ doc/man7/slweb_handler.7 | 229 ----------- doc/man7/slweb_html.7 | 178 --------- doc/man7/slweb_http.7 | 649 ------------------------------- 25 files changed, 1133 insertions(+), 1133 deletions(-) create mode 100644 doc/man7/libweb_handler.7 create mode 100644 doc/man7/libweb_html.7 create mode 100644 doc/man7/libweb_http.7 delete mode 100644 doc/man7/slweb_handler.7 delete mode 100644 doc/man7/slweb_html.7 delete mode 100644 doc/man7/slweb_http.7 (limited to 'doc') diff --git a/doc/man3/handler_add.3 b/doc/man3/handler_add.3 index 4c93f7a..2ee404b 100644 --- a/doc/man3/handler_add.3 +++ b/doc/man3/handler_add.3 @@ -1,4 +1,4 @@ -.TH HANDLER_ADD 3 2023-09-13 0.1.0 "slweb Library Reference" +.TH HANDLER_ADD 3 2023-09-13 0.1.0 "libweb Library Reference" .SH NAME handler_add \- add an endpoint to a web server handler object @@ -6,7 +6,7 @@ handler_add \- add an endpoint to a web server handler object .SH SYNOPSIS .LP .nf -#include +#include .P int handler_add(struct handler *\fIh\fP, const char *\fIurl\fP, enum http_op \fIop\fP, handler_fn \fIf\fP, void *\fIuser\fP); .fi @@ -40,13 +40,13 @@ for an exhaustive list of supported operations. .I f is a function pointer that shall be executed by -.I slweb +.I libweb if an incoming request matches the resource and operation defined by .I url and .IR op , respectively. See -.IR slweb_handler (7) +.IR libweb_handler (7) for the definition for .IR handler_fn . @@ -77,7 +77,7 @@ for a list of possible errors. .BR handler_alloc (3), .BR handler_free (3), .BR handler_listen (3), -.BR slweb_handler (7). +.BR libweb_handler (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/handler_alloc.3 b/doc/man3/handler_alloc.3 index e71b569..3b602dc 100644 --- a/doc/man3/handler_alloc.3 +++ b/doc/man3/handler_alloc.3 @@ -1,4 +1,4 @@ -.TH HANDLER_ALLOC 3 2023-09-13 0.1.0 "slweb Library Reference" +.TH HANDLER_ALLOC 3 2023-09-13 0.1.0 "libweb Library Reference" .SH NAME handler_alloc \- allocate a web server handler object @@ -6,7 +6,7 @@ handler_alloc \- allocate a web server handler object .SH SYNOPSIS .LP .nf -#include +#include .P struct handler *handler_alloc(const struct handler_cfg *\fIcfg\fP); .fi @@ -17,17 +17,17 @@ The function allocates a .I "struct handler" object, containing the required data by -.I slweb +.I libweb to handle a web server. This object is meant to be consumed by other functions from -.IR slweb_handler (7). +.IR libweb_handler (7). .I cfg defines the initial configuration, whose structure is defined by -.IR slweb_handler (7). +.IR libweb_handler (7). .I "struct handler" is an opaque object internal to -.I slweb +.I libweb and therefore is not accessible to callers. .SH RETURN VALUE @@ -48,7 +48,7 @@ for a list of possible errors. .BR handler_free (3), .BR handler_add (3), .BR handler_listen (3), -.BR slweb_handler (7). +.BR libweb_handler (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/handler_free.3 b/doc/man3/handler_free.3 index 1a89fa9..9a46b23 100644 --- a/doc/man3/handler_free.3 +++ b/doc/man3/handler_free.3 @@ -1,4 +1,4 @@ -.TH HANDLER_FREE 3 2023-09-14 0.1.0 "slweb Library Reference" +.TH HANDLER_FREE 3 2023-09-14 0.1.0 "libweb Library Reference" .SH NAME handler_free \- free a web server handler object @@ -6,7 +6,7 @@ handler_free \- free a web server handler object .SH SYNOPSIS .LP .nf -#include +#include .P void handler_free(struct handler *\fIh\fP); .fi @@ -29,7 +29,7 @@ No errors are defined. .SH SEE ALSO .BR handler_alloc (3), -.BR slweb_handler (7). +.BR libweb_handler (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/handler_listen.3 b/doc/man3/handler_listen.3 index cc2cfbb..ce001c7 100644 --- a/doc/man3/handler_listen.3 +++ b/doc/man3/handler_listen.3 @@ -1,4 +1,4 @@ -.TH HANDLER_LISTEN 3 2023-09-14 0.1.0 "slweb Library Reference" +.TH HANDLER_LISTEN 3 2023-09-14 0.1.0 "libweb Library Reference" .SH NAME handler_listen \- listen to and handle incoming connections on a web @@ -7,7 +7,7 @@ server .SH SYNOPSIS .LP .nf -#include +#include .P int handler_listen(struct handler *\fIh\fP, unsigned short \fIport\fP); .fi @@ -46,7 +46,7 @@ No errors are defined. .SH FUTURE DIRECTIONS When no configured endpoint matches the incoming request, -.I slweb +.I libweb shall respond with a .B 404 Not Found HTTP status code with no payload. Since some library users might want @@ -61,7 +61,7 @@ similarly to its member .BR handler_alloc (3), .BR handler_free (3), .BR handler_add (3), -.BR slweb_handler (7), +.BR libweb_handler (7), .BR signal (7). .SH COPYRIGHT diff --git a/doc/man3/html_node_add_attr.3 b/doc/man3/html_node_add_attr.3 index d6d3bf0..361a2a7 100644 --- a/doc/man3/html_node_add_attr.3 +++ b/doc/man3/html_node_add_attr.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_ADD_ATTR 3 2023-09-24 0.1.0 "slweb Library Reference" +.TH HTML_NODE_ADD_ATTR 3 2023-09-24 0.1.0 "libweb Library Reference" .SH NAME html_node_add_attr \- add attribute to a HTML node @@ -6,7 +6,7 @@ html_node_add_attr \- add attribute to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P int html_node_add_attr(struct html_node *\fIn\fP, const char *\fIattr\fP, const char *\fIval\fP); .fi @@ -27,7 +27,7 @@ is a null-terminated string with the name of the attribute. .I val is a null-terminated string with the value for the attribute. -.I slweb +.I libweb allocates copies of the null-terminated strings defined by .I attr and @@ -66,7 +66,7 @@ No errors are defined. .BR html_node_free (3), .BR html_node_set_value (3), .BR html_node_set_value_unescaped (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_add_child.3 b/doc/man3/html_node_add_child.3 index 360f968..964d328 100644 --- a/doc/man3/html_node_add_child.3 +++ b/doc/man3/html_node_add_child.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_ADD_CHILD 3 2023-09-25 0.1.0 "slweb Library Reference" +.TH HTML_NODE_ADD_CHILD 3 2023-09-25 0.1.0 "libweb Library Reference" .SH NAME html_node_add_child \- add child to a HTML node @@ -6,7 +6,7 @@ html_node_add_child \- add child to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P struct html_node *html_node_add_child(struct html_node *\fIn\fP, const char *\fIelem\fP); .fi @@ -41,7 +41,7 @@ and one child node: .in +4n .EX #include -#include +#include #include #include @@ -105,7 +105,7 @@ if fails. Internally, -.I slweb +.I libweb calls .IR html_node_add_sibling (3) from a child node when a node already has one. @@ -113,7 +113,7 @@ from a child node when a node already has one. .SH SEE ALSO .BR html_node_alloc (3), .BR html_node_add_sibling (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_add_sibling.3 b/doc/man3/html_node_add_sibling.3 index 951242f..625f4dc 100644 --- a/doc/man3/html_node_add_sibling.3 +++ b/doc/man3/html_node_add_sibling.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_ADD_SIBLING 3 2023-09-25 0.1.0 "slweb Library Reference" +.TH HTML_NODE_ADD_SIBLING 3 2023-09-25 0.1.0 "libweb Library Reference" .SH NAME html_node_add_sibling \- add sibling to a HTML node @@ -6,7 +6,7 @@ html_node_add_sibling \- add sibling to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P void html_node_add_sibling(struct html_node *\fIn\fP, struct html_node *\fIsibling\fP); .fi @@ -44,7 +44,7 @@ was still made public so as to cover possibly less common use cases. .SH SEE ALSO .BR html_node_alloc (3), .BR html_node_add_child (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_alloc.3 b/doc/man3/html_node_alloc.3 index 9551bd3..260b0ee 100644 --- a/doc/man3/html_node_alloc.3 +++ b/doc/man3/html_node_alloc.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_ALLOC 3 2023-09-15 0.1.0 "slweb Library Reference" +.TH HTML_NODE_ALLOC 3 2023-09-15 0.1.0 "libweb Library Reference" .SH NAME html_node_alloc \- allocate a HTML node @@ -6,7 +6,7 @@ html_node_alloc \- allocate a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P struct html_node *html_node_alloc(const char *\fIelement\fP); .fi @@ -22,7 +22,7 @@ is the name of the HTML tag. .I "struct html_node" is an opaque object internal to -.I slweb +.I libweb and therefore is not accessible to callers. .SH RETURN VALUE @@ -64,7 +64,7 @@ it via .BR html_node_add_attr (3), .BR html_node_add_child (3), .BR html_node_add_sibling (3), -.BR slweb_html (7). +.BR libweb_html (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_free.3 b/doc/man3/html_node_free.3 index 6efc9ed..ddafb61 100644 --- a/doc/man3/html_node_free.3 +++ b/doc/man3/html_node_free.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_FREE 3 2023-09-16 0.1.0 "slweb Library Reference" +.TH HTML_NODE_FREE 3 2023-09-16 0.1.0 "libweb Library Reference" .SH NAME html_node_free \- free a HTML node and its children @@ -6,7 +6,7 @@ html_node_free \- free a HTML node and its children .SH SYNOPSIS .LP .nf -#include +#include .P void html_node_free(struct html_node *\fIn\fP); .fi @@ -37,7 +37,7 @@ for a child node. .SH SEE ALSO .BR html_node_alloc (3), -.BR slweb_html (7). +.BR libweb_html (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_set_value.3 b/doc/man3/html_node_set_value.3 index bc6dc9c..e99cba6 100644 --- a/doc/man3/html_node_set_value.3 +++ b/doc/man3/html_node_set_value.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_SET_VALUE 3 2023-09-24 0.1.0 "slweb Library Reference" +.TH HTML_NODE_SET_VALUE 3 2023-09-24 0.1.0 "libweb Library Reference" .SH NAME html_node_set_value \- set value to a HTML node @@ -6,7 +6,7 @@ html_node_set_value \- set value to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P int html_node_set_value(struct html_node *\fIn\fP, const char *\fIval\fP); .fi @@ -25,7 +25,7 @@ or .I val is a null-terminated string with the value to be assigned to the node. -.I slweb +.I libweb allocates a copy of the null-terminated string defined by .IR val . @@ -69,7 +69,7 @@ No errors are defined. .BR html_node_free (3), .BR html_node_set_value_unescaped (3), .BR html_node_add_attr (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_node_set_value_unescaped.3 b/doc/man3/html_node_set_value_unescaped.3 index 7c3a897..7f26aef 100644 --- a/doc/man3/html_node_set_value_unescaped.3 +++ b/doc/man3/html_node_set_value_unescaped.3 @@ -1,4 +1,4 @@ -.TH HTML_NODE_SET_VALUE_UNESCAPED 3 2023-09-24 0.1.0 "slweb Library Reference" +.TH HTML_NODE_SET_VALUE_UNESCAPED 3 2023-09-24 0.1.0 "libweb Library Reference" .SH NAME html_node_set_value_unescaped \- set value to a HTML node @@ -6,7 +6,7 @@ html_node_set_value_unescaped \- set value to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P int html_node_set_value_unescaped(struct html_node *\fIn\fP, const char *\fIval\fP); .fi @@ -25,7 +25,7 @@ or .I val is a null-terminated string with the value to be assigned to the node. -.I slweb +.I libweb allocates a copy of the null-terminated string defined by .IR val . @@ -70,7 +70,7 @@ No errors are defined. .BR html_node_free (3), .BR html_node_set_value (3), .BR html_node_add_attr (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/html_serialize.3 b/doc/man3/html_serialize.3 index 59700f1..0e12c11 100644 --- a/doc/man3/html_serialize.3 +++ b/doc/man3/html_serialize.3 @@ -1,4 +1,4 @@ -.TH HTML_SERIALIZE 3 2023-09-24 0.1.0 "slweb Library Reference" +.TH HTML_SERIALIZE 3 2023-09-24 0.1.0 "libweb Library Reference" .SH NAME html_serialize \- add attribute to a HTML node @@ -6,7 +6,7 @@ html_serialize \- add attribute to a HTML node .SH SYNOPSIS .LP .nf -#include +#include .P int html_serialize(const struct html_node *\fIn\fP, struct dynstr *\fId\fP); .fi @@ -41,7 +41,7 @@ No errors are defined. .BR html_node_add_attr (3), .BR html_node_set_value (3), .BR html_node_set_value_unescaped (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_alloc.3 b/doc/man3/http_alloc.3 index 4b9e19b..a54046c 100644 --- a/doc/man3/http_alloc.3 +++ b/doc/man3/http_alloc.3 @@ -1,4 +1,4 @@ -.TH HTTP_ALLOC 3 2023-09-06 0.1.0 "slweb Library Reference" +.TH HTTP_ALLOC 3 2023-09-06 0.1.0 "libweb Library Reference" .SH NAME http_alloc \- allocate a HTTP context object @@ -6,7 +6,7 @@ http_alloc \- allocate a HTTP context object .SH SYNOPSIS .LP .nf -#include +#include .P struct http *http_alloc(const struct http_cfg *\fIcfg\fP); .fi @@ -17,17 +17,17 @@ The function allocates a .I "struct http_ctx" object, containing the required data by -.I slweb +.I libweb to handle a HTTP connection. This object is meant to be consumed by other functions from -.IR slweb . +.IR libweb . .I cfg defines the configuration for the HTTP context, whose structure is defined by -.IR slweb_http (7). +.IR libweb_http (7). .I "struct http_ctx" is an opaque object internal to -.I slweb +.I libweb and therefore is not accessible to callers. .SH RETURN VALUE @@ -46,12 +46,12 @@ for a list of possible errors. .SH NOTES This function is designed for internal use by -\fIslweb\fR. +\fIlibweb\fR. .SH SEE ALSO .BR http_free (3), .BR http_update (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_cookie_create.3 b/doc/man3/http_cookie_create.3 index 6587b24..2ad4d65 100644 --- a/doc/man3/http_cookie_create.3 +++ b/doc/man3/http_cookie_create.3 @@ -1,4 +1,4 @@ -.TH HTTP_COOKIE_CREATE 3 2023-09-07 0.1.0 "slweb Library Reference" +.TH HTTP_COOKIE_CREATE 3 2023-09-07 0.1.0 "libweb Library Reference" .SH NAME http_cookie_create \- creates a HTTP/1.1 cookie @@ -6,7 +6,7 @@ http_cookie_create \- creates a HTTP/1.1 cookie .SH SYNOPSIS .LP .nf -#include +#include .P char *http_cookie_create(const char *\fIkey\fP, const char *\fIvalue\fP); .fi @@ -50,14 +50,14 @@ ExampleHeader=ExampleValue; HttpOnly; Expires Wed, 07 Sep 2023 00:00:00 GMT .SH FUTURE DIRECTIONS -.I slweb +.I libweb sets a 1-year expiration date for HTTP cookies due to arbitrary design limitations. Future versions of this library shall allow a custom expiration date as an additional parameter to .IR http_cookie_create (3). .SH SEE ALSO -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_encode_url.3 b/doc/man3/http_encode_url.3 index 94bd7f8..406b2a6 100644 --- a/doc/man3/http_encode_url.3 +++ b/doc/man3/http_encode_url.3 @@ -1,4 +1,4 @@ -.TH HTTP_ENCODE_URL 3 2023-09-07 0.1.0 "slweb Library Reference" +.TH HTTP_ENCODE_URL 3 2023-09-07 0.1.0 "libweb Library Reference" .SH NAME http_encode_url \- allocates a percent-encoded null-terminated string @@ -6,7 +6,7 @@ http_encode_url \- allocates a percent-encoded null-terminated string .SH SYNOPSIS .LP .nf -#include +#include .P char *http_encode_url(const char *\fIurl\fP); .fi @@ -27,7 +27,7 @@ No errors are defined. .SH SEE ALSO .BR http_decode_url (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_free.3 b/doc/man3/http_free.3 index 3b8b61d..a4f2079 100644 --- a/doc/man3/http_free.3 +++ b/doc/man3/http_free.3 @@ -1,4 +1,4 @@ -.TH HTTP_FREE 3 2023-09-06 0.1.0 "slweb Library Reference" +.TH HTTP_FREE 3 2023-09-06 0.1.0 "libweb Library Reference" .SH NAME http_free \- free a HTTP context object @@ -6,7 +6,7 @@ http_free \- free a HTTP context object .SH SYNOPSIS .LP .nf -#include +#include .P void http_free(struct http_ctx *\fIh\fP); .fi @@ -30,7 +30,7 @@ No errors are defined. .SH SEE ALSO .BR http_alloc (3), .BR http_update (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_response_add_header.3 b/doc/man3/http_response_add_header.3 index 4f033ea..4ce9132 100644 --- a/doc/man3/http_response_add_header.3 +++ b/doc/man3/http_response_add_header.3 @@ -1,4 +1,4 @@ -.TH HTTP_RESPONSE_ADD_HEADER 3 2023-09-07 0.1.0 "slweb Library Reference" +.TH HTTP_RESPONSE_ADD_HEADER 3 2023-09-07 0.1.0 "libweb Library Reference" .SH NAME http_response_add_header \- adds a HTTP/1.1 header to a response @@ -6,7 +6,7 @@ http_response_add_header \- adds a HTTP/1.1 header to a response .SH SYNOPSIS .LP .nf -#include +#include .P int http_response_add_header(struct http_response *\fIr\fP, const char *\fIheader\fP, const char *\fIvalue\fP); .fi @@ -42,7 +42,7 @@ and for a list of possible errors. .SH SEE ALSO -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man3/http_update.3 b/doc/man3/http_update.3 index 7f54608..c4537d9 100644 --- a/doc/man3/http_update.3 +++ b/doc/man3/http_update.3 @@ -1,4 +1,4 @@ -.TH HTTP_UPDATE 3 2023-09-06 0.1.0 "slweb Library Reference" +.TH HTTP_UPDATE 3 2023-09-06 0.1.0 "libweb Library Reference" .SH NAME http_update \- updates a HTTP context object @@ -6,7 +6,7 @@ http_update \- updates a HTTP context object .SH SYNOPSIS .LP .nf -#include +#include .P int http_update(struct http_ctx *\fIh\fP, bool *\fIwrite\fP, bool *\fIclose\fP); .fi @@ -60,12 +60,12 @@ No errors are defined. .SH NOTES This function is designed for internal use by -.IR slweb . +.IR libweb . .SH SEE ALSO .BR http_free (3), .BR http_update (3), -.BR slweb_http (7). +.BR libweb_http (7). .SH COPYRIGHT Copyright (C) 2023 Xavier Del Campo Romero. diff --git a/doc/man7/Makefile b/doc/man7/Makefile index 4945d1f..c4e1ca7 100644 --- a/doc/man7/Makefile +++ b/doc/man7/Makefile @@ -3,9 +3,9 @@ PREFIX = /usr/local DST = $(PREFIX)/share/man/man7 OBJECTS = \ - $(DST)/slweb_handler.7 \ - $(DST)/slweb_html.7 \ - $(DST)/slweb_http.7 + $(DST)/libweb_handler.7 \ + $(DST)/libweb_html.7 \ + $(DST)/libweb_http.7 all: diff --git a/doc/man7/libweb_handler.7 b/doc/man7/libweb_handler.7 new file mode 100644 index 0000000..5c910e0 --- /dev/null +++ b/doc/man7/libweb_handler.7 @@ -0,0 +1,229 @@ +.TH LIBWEB_HANDLER 7 2023-09-15 0.1.0 "libweb Library Reference" + +.SH NAME +libweb_handler \- libweb high-level website configuration + +.SH SYNOPSIS +.LP +.nf +#include +.fi + +.SH DESCRIPTION +This component provides abstractions that allow library users to +define the behaviour of a web server. Whereas +.IR libweb_http (7) +defines the HTTP/1.1 server implementation and provides a data type +(namely +.IR "struct http_ctx" ) +to handle an incoming connection, +.IR libweb_handler (7): + +.IP \(bu 2 +Defines the list of endpoints and supported operations. +.IP \(bu 2 +Defines the port +.I libweb +must listen to. +.IP \(bu 2 +Keeps track of all +.I struct http_ctx +objects. + +.IR libweb_handler (7) +provides the following functions: + +.IP \(bu 2 +.IR handler_alloc (3): +allocates a +.I "struct handler" +object, consumed by other functions from this component. + +.IP \(bu 2 +.IR handler_free (3): +frees the memory previously allocated by a call to +.IR handler_alloc (3). + +.IP \(bu 2 +.IR handler_add (3): +adds an endpoint to the server for a given HTTP/1.1 +operation. + +.IP \(bu 2 +.IR handler_listen (3): +puts a +.I "struct handler" +object to initialize the server and handle connections in a loop. + +The +.IR handler_alloc (3) +function requires some initial configuration parameters, given by +.IR "struct handler_cfg" , +defined as: + +.PP +.in +4n +.EX +struct handler_cfg +{ + const char *\fItmpdir\fP; + int (*\fIlength\fP)(unsigned long long len, const struct http_cookie *c, struct http_response *r, void *user); + void *\fIuser\fP; +}; +.EE +.in +.PP + +.IR tmpdir , +.I length +and +.I user +are passed directly to the +.I struct http_cfg +object used to initialize a +.I struct http_ctx +object. See +.IR libweb_http (7) +for further reference about these members. + +However, a +.I "struct handler" +object as returned by +.IR handler_alloc (3) +alone is not enough. One or more callbacks must be set up to define the +behaviour of the web server. Every callback must follow the signature +below, as defined by +.IR handler_fn : + +.PP +.in +4n +.EX +typedef int (*\fIhandler_fn\fP)(const struct http_payload *\fIp\fP, struct http_response *\fIr\fP, void *\fIuser\fP); +.EE +.in +.PP + +Please read +.IR libweb_http (7) +for further refence on +.I "struct http_payload" +and +.IR "struct http_response" . +.I user +is a user-defined parameter previously defined by a call to +.IR handler_add (3). + +.SH EXAMPLE + +The following source code shows how to set up a simple web server that +listens to TCP port +.I 8080 +and defines +\fI/\fP +and +\fI/index.html\fP +as its endpoints. For the sake of simplicity, a static response body is +returned, instead of using +.IR libweb_html (7) +to generate HTML data. Please read +.IR libweb_html (7) +for further reference on how to generate dynamic content. + +.PP +.in +4n +.EX +#include +#include +#include +#include + +static int hello(const struct http_payload *const pl, + struct http_response *const r, void *const user) +{ + static const char page[] = + { + "

Hello from libweb!

" + }; + + *r = (const struct http_response) + { + .status = HTTP_STATUS_OK, + .buf.ro = page, + .n = sizeof page - 1 + }; + + if (http_response_add_header(r, "Content-Type", "text/html")) + { + fprintf(stderr, "%s: http_response_add_header failed\en", __func__); + return -1; + } + + return 0; +} + +static int on_length(const unsigned long long len, + const struct http_cookie *const c, struct http_response *const r, + void *const user) +{ + *r = (const struct http_response) + { + .status = HTTP_STATUS_FORBIDDEN + }; + + return 1; +} + +int main(int argc, char *argv[]) +{ + int ret = EXIT_FAILURE; + const short port = 8080; + const struct handler_cfg cfg = + { + .length = on_length + }; + + struct handler *const h = handler_alloc(&cfg); + static const char *const urls[] = {"/", "/index.html"}; + + if (!h) + { + fprintf(stderr, "%s: handler_alloc failed\en", __func__); + goto end; + } + + for (size_t i = 0; i < sizeof urls / sizeof *urls; i++) + if (handler_add(h, urls[i], HTTP_OP_GET, hello, NULL)) + { + fprintf(stderr, "%s: handler_add failed\en", __func__); + goto end; + } + + if (handler_listen(h, port)) + { + fprintf(stderr, "%s: handler_listen failed\en", __func__); + goto end; + } + + ret = EXIT_SUCCESS; + +end: + handler_free(h); + return ret; +} +.EE +.in +.PP + +.SH SEE ALSO +.BR handler_alloc (3), +.BR handler_add (3), +.BR handler_free (3), +.BR libweb_http (7). + +.SH COPYRIGHT +Copyright (C) 2023 Xavier Del Campo Romero. +.P +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. diff --git a/doc/man7/libweb_html.7 b/doc/man7/libweb_html.7 new file mode 100644 index 0000000..c6f864a --- /dev/null +++ b/doc/man7/libweb_html.7 @@ -0,0 +1,178 @@ +.TH LIBWEB_HTML 7 2023-09-15 0.1.0 "libweb Library Reference" + +.SH NAME +libweb_html \- libweb HTML serializer + +.SH SYNOPSIS +.LP +.nf +#include +.fi + +.SH DESCRIPTION +This component allows library users to serialize HTML text from a tree +structure composed by one or more +.I struct html_node +objects. +.IR libweb_html (7) +provides the following functions: + +.IP \(bu 2 +.IR html_node_alloc (3) +allocates a +.I struct html_node +object, consumed by other functions from this component. + +.IP \(bu 2 +.IR html_node_free (3) +frees the memory from a +.I struct html_node +object previously allocated by a call to +.IR html_node_alloc (3), +plus all of the memory allocated by its children. + +.IP \(bu 2 +.IR html_node_set_value (3) +sets the HTML value for a +.I struct html_node +object, escaping characters that could case syntax errors, such as +.B < +.BR "" ( "LESS-THAN SIGN" ). + +.IP \(bu 2 +.IR html_node_set_value_unescaped (3) +sets the HTML value for a +.I struct html_node +object. As opposed to +.IR html_node_set_value (3), +no escaping is performed. + +.IP \(bu 2 +.IR html_node_add_attr (3) +adds an attribute to a +.I struct html_node +object. + +.IP \(bu 2 +.IR html_node_add_child (3) +allocates a children +.I struct html_node +object to another +.I struct html_node +object. + +.IP \(bu 2 +.IR html_node_add_sibling (3) +adds a sibling +.I struct html_node +object to another +.I struct html_node +object. + +.IP \(bu 2 +.IR html_serialize (3) +serializes a +.I struct html_node +object and all of its children into a null-terminated string with +the HTML-serialized data. + +Typically, a root +.I struct html_node +object is allocated via +.IR html_node_alloc (3), +and child nodes are appended to it via +.IR html_node_add_child (3). +Optionally, values and/or attributes can be added to nodes via +.IR html_node_set_value (3) +and +.IR html_node_add_attr (3), +respectively. +Finally, +.IR html_node_free (3) +shall free the memory used by the root node and all of its children. + +.SH EXAMPLE +The example below is a minimal showcase of some of the features +provided by +.IR libweb_html (7), +which prints a minimal HTML file to standard output: + +.PP +.in +4n +.EX +#include +#include +#include +#include + +int main() +{ + int ret = EXIT_FAILURE; + struct dynstr d; + struct html_node *const html = html_node_alloc("html"), *body; + static const char text[] = "testing libweb"; + + dynstr_init(&d); + + if (!html) + { + fprintf(stderr, "html_node_alloc_failed\en"); + goto end; + } + else if (!(body = html_node_add_child(html, "body"))) + { + fprintf(stderr, "html_node_add_child failed\en"); + goto end; + } + else if (html_node_set_value(body, text)) + { + fprintf(stderr, "html_node_set_value failed\en"); + goto end; + } + else if (html_serialize(html, &d)) + { + fprintf(stderr, "html_serialize failed\en"); + goto end; + } + + printf("%s", d.str); + ret = EXIT_SUCCESS; + +end: + dynstr_free(&d); + return ret; +} +.EE +.in +.PP + +This program should write the following data over standard output: + +.PP +.in +4n +.EX + + testing libweb + +.EE +.in +.PP + +.SH SEE ALSO +.BR html_node_alloc (3), +.BR html_node_free (3), +.BR html_node_set_value (3), +.BR html_node_set_value_unescaped (3), +.BR html_node_add_attr (3), +.BR html_node_add_child (3), +.BR html_node_add_sibling (3), +.BR html_serialize (3), +.BR libweb_html (7). + +.SH COPYRIGHT +Copyright (C) 2023 Xavier Del Campo Romero. +.P +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. diff --git a/doc/man7/libweb_http.7 b/doc/man7/libweb_http.7 new file mode 100644 index 0000000..329a616 --- /dev/null +++ b/doc/man7/libweb_http.7 @@ -0,0 +1,649 @@ +.TH LIBWEB_HTTP 7 2023-09-15 0.1.0 "libweb Library Reference" + +.SH NAME +libweb_http \- libweb HTTP connection handling and utilities + +.SH SYNOPSIS +.LP +.nf +#include +.fi + +.SH DESCRIPTION +As one of its key features, +\fIlibweb\fR +provides a HTTP/1.1-compatible server implementation that can be +embedded into applications as a library. While not a complete HTTP/1.1 +server implementation, the following features are supported: + +.IP \(bu 2 +.BR GET . +.IP \(bu 2 +.BR POST . +.IP \(bu 2 +.IR multipart/form-data -encoded +data. An optional payload size limit can be defined (see section +.BR "HTTP server configuration" ). +.IP \(bu 2 +Cookies. + +.SS Utility functions +The functions listed below are meant for library users: + +.IP \(bu 2 +.IR http_response_add_header (3). +.IP \(bu 2 +.IR http_cookie_create (3). +.IP \(bu 2 +.IR http_encode_url (3). +.IP \(bu 2 +.IR http_decode_url (3). + +.SS HTTP connection-related functions + +The functions listed below are meant for internal use by +.IR libweb : + +.IP \(bu 2 +.IR http_alloc (3). +.IP \(bu 2 +.IR http_free (3). +.IP \(bu 2 +.IR http_update (3). + +However, this component alone does not provide a working web server. +For example, a list of endpoints is required to define its behaviour, +and +.I struct http +objects must be stored somewhere as long as the connections are active. +.IR libweb_handler (7) +is the component meant to provide the missing pieces that conform a +working web server. + +.SS HTTP server configuration + +A HTTP server is contained into a +.IR "struct http_ctx" , +and can be allocated by calling +.IR http_alloc (3). +This function requires a valid pointer to a +.I "struct http_cfg" +object. This flexible configuration allows the library to run on top of +any reliable transport layer, including TCP. +.I "struct http_cfg" +is defined as: + +.PP +.in +4n +.EX +struct http_cfg +{ + int (*\fIread\fP)(void *\fIbuf\fP, size_t \fIn\fP, void *\fIuser\fP); + int (*\fIwrite\fP)(const void *\fIbuf\fP, size_t \fIn\fP, void *\fIuser\fP); + int (*\fIpayload\fP)(const struct http_payload *\fIp\fP, struct http_response *\fIr\fP, void *\fIuser\fP); + int (*\fIlength\fP)(unsigned long long \fIlen\fP, const struct http_cookie *\fIc\fP, struct http_response *\fIr\fP, void *\fIuser\fP); + const char *\fItmpdir\fP; + void *\fIuser\fP; +}; +.EE +.in +.PP + +All of the function pointers listed above define +.I user +as a parameter, an opaque pointer to user-defined data previously +defined by member +.I user +(see definition below). Unless noted otherwise, all pointers must be +valid. + +.I read +is a function pointer to a +.IR read (2)-like +function that must read up to +.I n +bytes +from the client into a buffer pointed to by +.IR buf . +The function pointed to by +.I read +returns the number of bytes that could be read from the client, +which could be from zero up to +.IR n . +On error, a negative integer is returned. + +.I write +is a function pointer to a +.IR write (2)-like +function that must write up to +.I n +bytes +to the client from a buffer pointed to by +.IR buf . +It returns the number of bytes that could be written to the client, +which could be from zero to +.IR n . +On error, a negative integer is returned. + +.I payload +is a function pointer called by +.I libweb +when a new HTTP request has been received. +.I p +is a read-only pointer to a +.I "struct http_payload" +object, which describes the HTTP request (see section +.BR "HTTP payload" ). +.I r +is a pointer to a +.I "struct http_response" +object that must be initialized by the function pointed to by +.IR payload , +which includes the HTTP response parameters to be returned to the +client. +The function pointed to by +.I read +returns the number of bytes that could be read from the client, +which could be from zero to +.IR n . +This function returns zero on success. On error, a negative integer is +returned. + +.I length +is a function pointer called by +.I libweb +when an incoming HTTP request from a client requires to store one or +more files on the server, encoded as +.IR multipart/form-data . +.I len +defines the length of the +.IR multipart/form-data +(see section +.BR "Content-Length design limitations for multipart/form-data" ). +.I c +is a read-only pointer to a +.I "struct http_cookie" +object, containing at most +.B one +(see section +.BR "Limitations on the number of HTTP cookies" ) +HTTP cookie. If no cookies are defined, its members shall contain null +pointers. +.I r +is a pointer to a +.I "struct http_response" +object that must be initialized by the function pointed to by +.I payload +only when the function returns a positive integer. +This function returns zero on success, a negative integer in case +of a fatal error or a positive integer in case of a non-fatal error +caused by a malformed request, or to indicate a lack of support for +this feature. When a positive integer is returned, the connection +against the client shall be closed. + +.I tmpdir +is a null-terminated string defining the path to a directory where +files uploaded by clients shall be stored temporarily. +.I tmpdir +can be a null pointer if this feature is not supported by the +application. + +.I user +is an opaque pointer to a user-defined object that shall be passed to +other function pointers defined by +.IR "struct http_cfg" . +.I user +can be a null pointer. + +.SS HTTP payload + +When a client submits a request to the server, +.I libweb +prepares a high-level data structure, called +.IR "struct http_payload" , +and passes it to the function pointer defined by +.I "struct http_cfg" +member +.IR payload . +.I "struct http_payload" +is defined as: + +.PP +.in +4n +.EX +struct http_payload +{ + enum http_op \fIop\fP; + const char *\fIresource\fP; + struct http_cookie \fIcookie\fP; + + union + { + struct http_post \fIpost\fP; + } \fIu\fP; + + const struct http_arg *\fIargs\fP; + size_t \fIn_args\fP; +}; +.EE +.in +.PP + +.I op +describes the HTTP/1.1 operation. See the definition for +.I "enum http_op" +for an exhaustive list of supported operations. + +.I resource +describes which resource is being requested by the client. For example: +.IR /index.html . + +.I cookie +contains at most +.B one +HTTP cookie, defined as a key-value pair. Its members shall be null +pointers if no cookie is present. Also, see section +.BR "Limitations on the number of HTTP cookies" . + +.I u +defines a tagged union with operation-specific data. For example, +.I post +refers to data sent by a client on a +.B POST +request (see section +.BR "HTTP POST payload" ). +Also, see section +.BR "Future supported HTTP/1.1 operations" . + +.I args +defines a list of key-value pairs containing URL parameters. Its length +is defined by +.IR n_args . + +.SS HTTP POST payload + +As opposed to payload-less HTTP/1.1 operations, such as +.BR GET , +.B POST +operations might or might not include payload data. Moreover, such +payload can be encoded in two different ways, which +.I slcl +handles differently: + +.IP \(bu 2 +.IR application/x-www-form-urlencoded : +suggested for smaller payloads. +.I libweb +shall store the payload in memory, limiting its maximum size to +.BR "7999 octets" . + +.IP \(bu 2 +.IR multipart/form-data : +suggested for larger and/or binary payloads. +.I libweb +shall store each non-file name-value pair in memory, limiting the value +length to +.BR "8000 octets" . +On the other hand, +.I libweb +shall store each file into the temporary directory defined by +.I struct http_cfg +member +.IR tmpdir . + +This information is contained into a +.B "struct http_post" +object, defined as: + +.PP +.in +4n +.EX +struct http_post +{ + bool \fIexpect_continue\fP; + const char *\fIdata\fP; + size_t \fInfiles\fP, \fInpairs\fP; + + const struct http_post_pair + { + const char *\fIname\fP, *\fIvalue\fP; + } *\fIpairs\fP; + + const struct http_post_file + { + const char *\fIname\fP, *\fItmpname\fP, *\fIfilename\fP; + } *\fIfiles\fP; +}; +.EE +.in +.PP + +.I expect_continue +shall be set to +.I true +if an +.B "Expect: 100-continue" +HTTP header is received, +.I false +otherwise (see +section +.B Handling of 100-continue requests +in +.BR BUGS ). + +When +.IR application/x-www-form-urlencoded -data +is included, +.I data +shall contain a null-terminated string with the user payload. Data must +be decoded by applications (see section +.BR "Handling application/x-www-form-urlencoded data" ). +Otherwise, +.I data +shall be a null pointer. + +In the case of +.IR multipart/form-data , +.I files +shall contain a list of files that were uploaded by the client, each +one stored by the server to a temporary file, defined by +.IR tmpname . +The final name for the uploaded file is defined by +.IR filename . +The key +.B name +used for each requested file is defined by +.IR name . +The length of this list is defined by +.IR nfiles . +If no files are defined, +.I files +shall be a null pointer. + +In the case of +.IR multipart/form-data , +.I pairs +shall contain a list of name-value pairs that were uploaded by the +client, defined by +.I name +and +.IR value , +respectively. The length of this list is defined by +.IR npairs . +If no name-value pairs are defined, +.I pairs +shall be a null pointer. + +.SS HTTP responses + +Some function pointers used by +.I libweb +require to initialize a +.I "struct http_response" +object that defines the response that must be sent to the client. +This structure is defined as: + +.PP +.in +4n +.EX +struct http_response +{ + enum http_status \fIstatus\fP; + + struct http_header + { + char *\fIheader\fP, *\fIvalue\fP; + } *\fIheaders\fP; + + union + { + const void *\fIro\fP; + void *\fIrw\fP; + } \fIbuf\fP; + + FILE *\fIf\fP; + unsigned long long \fIn\fP; + size_t \fIn_headers\fP; + void (*\fIfree\fP)(void *); +}; +.EE +.in +.PP + +.I status +is the response code to be returned to the client. A list of possible +values is defined by +.IR "enum http_status" . + +.I headers +is a pointer to an array of +.I "struct http_header" +whose length is defined by +.IR n_headers , +containing the HTTP headers to be included into the response. Note that +.I headers +is not meant to be modified directly by library users. Instead, the +.IR http_response_add_header (3) +utility function shall update the +.I "struct http_response" +object accordingly. + +.I buf +is a union containing two possible values, with minor semantic +differences: + +.I ro +is a read-only opaque pointer to a buffer in memory, whose length is +defined by +.I n +(see definition below). +.I libweb +shall select +.I ro +as the output payload if both +.I f +and +.I free +are null pointers, and +.I n +is non-zero. + +.I rw +is an opaque pointer to a buffer in memory, whose length is defined by +.I n +(see definition below). +.I libweb +shall select +.I rw +as the output payload if both +.I f +is a null pointer and +.I free +is a valid pointer to a function that frees the memory used by +.IR rw , +and +.I n +is non-zero. + +.I f +is a +.I FILE +pointer opened for reading that defines the payload to be sent to the +client, whose length is defined by +.IR n . +.I libweb +shall select +.I f +as the output payload if +.IR ro , +.I rw +and +.I free +are null pointers, and +.I n +is non-zero. + +.I n +is the length of the output payload, which can be either a buffer in +memory (see definitions for +.I ro +and +.IR rw ) +or a file (see definition for +.IR f ). +If +.I n +equals zero, no payload shall be sent. + +.I n_headers +defines the number of HTTP headers contained in the response. This +field is not meant to be manipulated directly. Instead, the +.IR http_response_add_header (3) +utility function shall update the +.I "struct http_response" +object accordingly. + +.I free +is a pointer to a function that frees the memory used by +.I rw +.B only if +.I rw +is a valid pointer. Otherwise, +.I free +must be a null pointer. + +.SS Transport Layer Security (TLS) +By design, +.I libweb +does +.BI not +implement TLS (Transport Layer Security). It is assumed this should +be provided by a reverse proxy instead, a kind of project that is +usually maintained by a larger community than +.I libweb +and audited for security vulnerabilities. + +.SH NOTES +.SS Comparing against other HTTP server implementations +While it is well understood that other solutions provide fully-fledged +server implementations as standalone executables, +.I libweb +strives to be as small and easy to use as possible, intentionally +limiting its scope while covering a good range of use cases. + +.SS Content-Length design limitations for multipart/form-data +HTTP/1.1 defines the Content-Length for a +.I multipart/form-data +.B POST +request as the sum of: + +.IP \(bu 2 +The length of all files. +.IP \(bu 2 +The length of all boundaries. +.IP \(bu 2 +The length of all headers included on each part. +.IP \(bu 2 +All separator tokens, such as +.B LFCR +or +.BR -- . + +This means it is not possible for +.I libweb +to determine the number of files or their lengths in a HTTP request +unless the whole request is read, which not might be possible for large +requests. Therefore, the +.B Content-Length +is the only rough estimation +.I libweb +can rely on, and therefore is the value passed to the +.I length +function pointer in +.IR "struct http_cfg" . + +.SH BUGS +.SS Handling of 100-continue requests + +The handling of +.B 100-continue +requests is not done correctly: +.I libweb +calls the function pointed to by +.I "struct http_cfg" +member +.I payload +as soon as it encounters the +.B Expected: +header. However, a response should only be sent to the client once all +headers are processed. + +.SH FUTURE DIRECTIONS +.SS Limitations on the number of HTTP cookies +So far, +.I libweb +shall only append at most +.B one +HTTP cookie to a +.I "struct http_payload" +object. This is due to arbitrary design limitations on the library. +Future versions of this library shall replace the +.I "struct http_cookie" +object inside +.I "struct http_payload" +with a pointer to an array of +.IR "struct http_cookie" , +plus a +.I size_t +object containing the number of HTTP cookies in the request. + +.SS Handling application/x-www-form-urlencoded data +Due to historical reasons, +.I libweb +treated +.IR application/x-www-form-urlencoded -data +as a binary blob. While this was changed to a null-terminated string in +order to allow applications to avoid unnecessary memory allocations, +.I libweb +still does not decode the data, instead forcing applications to do so. +Future versions of this library shall replace +.I "struct http_post" +member +.I data +with an array of structures containing key-value pairs, so that +applications no longer need to decode payload data by themselves. + +.SS Future supported HTTP/1.1 operations +So far, +.I struct http_payload +defines +.I u +as a union that only holds one possible data type. While this might +look counterintuitive, this is because +.B POST +is the only HTTP/1.1 operation +.I libweb +supports that requires to store a payload. However, future versions of +this library might extend its support for other HTTP/1.1 operations +that could require to store a payload, while keeping the memory +footprint for +.I struct http_payload +small. + +.SH SEE ALSO +.BR handler_alloc (3), +.BR http_alloc (3), +.BR http_free (3), +.BR http_update (3), +.BR http_response_add_header (3), +.BR http_cookie_create (3), +.BR http_encode_url (3), +.BR http_decode_url (3). + +.SH COPYRIGHT +Copyright (C) 2023 Xavier Del Campo Romero. +.P +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. diff --git a/doc/man7/slweb_handler.7 b/doc/man7/slweb_handler.7 deleted file mode 100644 index 53fb156..0000000 --- a/doc/man7/slweb_handler.7 +++ /dev/null @@ -1,229 +0,0 @@ -.TH SLWEB_HANDLER 7 2023-09-15 0.1.0 "slweb Library Reference" - -.SH NAME -slweb_handler \- slweb high-level website configuration - -.SH SYNOPSIS -.LP -.nf -#include -.fi - -.SH DESCRIPTION -This component provides abstractions that allow library users to -define the behaviour of a web server. Whereas -.IR slweb_http (7) -defines the HTTP/1.1 server implementation and provides a data type -(namely -.IR "struct http_ctx" ) -to handle an incoming connection, -.IR slweb_handler (7): - -.IP \(bu 2 -Defines the list of endpoints and supported operations. -.IP \(bu 2 -Defines the port -.I slweb -must listen to. -.IP \(bu 2 -Keeps track of all -.I struct http_ctx -objects. - -.IR slweb_handler (7) -provides the following functions: - -.IP \(bu 2 -.IR handler_alloc (3): -allocates a -.I "struct handler" -object, consumed by other functions from this component. - -.IP \(bu 2 -.IR handler_free (3): -frees the memory previously allocated by a call to -.IR handler_alloc (3). - -.IP \(bu 2 -.IR handler_add (3): -adds an endpoint to the server for a given HTTP/1.1 -operation. - -.IP \(bu 2 -.IR handler_listen (3): -puts a -.I "struct handler" -object to initialize the server and handle connections in a loop. - -The -.IR handler_alloc (3) -function requires some initial configuration parameters, given by -.IR "struct handler_cfg" , -defined as: - -.PP -.in +4n -.EX -struct handler_cfg -{ - const char *\fItmpdir\fP; - int (*\fIlength\fP)(unsigned long long len, const struct http_cookie *c, struct http_response *r, void *user); - void *\fIuser\fP; -}; -.EE -.in -.PP - -.IR tmpdir , -.I length -and -.I user -are passed directly to the -.I struct http_cfg -object used to initialize a -.I struct http_ctx -object. See -.IR slweb_http (7) -for further reference about these members. - -However, a -.I "struct handler" -object as returned by -.IR handler_alloc (3) -alone is not enough. One or more callbacks must be set up to define the -behaviour of the web server. Every callback must follow the signature -below, as defined by -.IR handler_fn : - -.PP -.in +4n -.EX -typedef int (*\fIhandler_fn\fP)(const struct http_payload *\fIp\fP, struct http_response *\fIr\fP, void *\fIuser\fP); -.EE -.in -.PP - -Please read -.IR slweb_http (7) -for further refence on -.I "struct http_payload" -and -.IR "struct http_response" . -.I user -is a user-defined parameter previously defined by a call to -.IR handler_add (3). - -.SH EXAMPLE - -The following source code shows how to set up a simple web server that -listens to TCP port -.I 8080 -and defines -\fI/\fP -and -\fI/index.html\fP -as its endpoints. For the sake of simplicity, a static response body is -returned, instead of using -.IR slweb_html (7) -to generate HTML data. Please read -.IR slweb_html (7) -for further reference on how to generate dynamic content. - -.PP -.in +4n -.EX -#include -#include -#include -#include - -static int hello(const struct http_payload *const pl, - struct http_response *const r, void *const user) -{ - static const char page[] = - { - "

Hello from slweb!

" - }; - - *r = (const struct http_response) - { - .status = HTTP_STATUS_OK, - .buf.ro = page, - .n = sizeof page - 1 - }; - - if (http_response_add_header(r, "Content-Type", "text/html")) - { - fprintf(stderr, "%s: http_response_add_header failed\en", __func__); - return -1; - } - - return 0; -} - -static int on_length(const unsigned long long len, - const struct http_cookie *const c, struct http_response *const r, - void *const user) -{ - *r = (const struct http_response) - { - .status = HTTP_STATUS_FORBIDDEN - }; - - return 1; -} - -int main(int argc, char *argv[]) -{ - int ret = EXIT_FAILURE; - const short port = 8080; - const struct handler_cfg cfg = - { - .length = on_length - }; - - struct handler *const h = handler_alloc(&cfg); - static const char *const urls[] = {"/", "/index.html"}; - - if (!h) - { - fprintf(stderr, "%s: handler_alloc failed\en", __func__); - goto end; - } - - for (size_t i = 0; i < sizeof urls / sizeof *urls; i++) - if (handler_add(h, urls[i], HTTP_OP_GET, hello, NULL)) - { - fprintf(stderr, "%s: handler_add failed\en", __func__); - goto end; - } - - if (handler_listen(h, port)) - { - fprintf(stderr, "%s: handler_listen failed\en", __func__); - goto end; - } - - ret = EXIT_SUCCESS; - -end: - handler_free(h); - return ret; -} -.EE -.in -.PP - -.SH SEE ALSO -.BR handler_alloc (3), -.BR handler_add (3), -.BR handler_free (3), -.BR slweb_http (7). - -.SH COPYRIGHT -Copyright (C) 2023 Xavier Del Campo Romero. -.P -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. diff --git a/doc/man7/slweb_html.7 b/doc/man7/slweb_html.7 deleted file mode 100644 index db8e224..0000000 --- a/doc/man7/slweb_html.7 +++ /dev/null @@ -1,178 +0,0 @@ -.TH SLWEB_HTML 7 2023-09-15 0.1.0 "slweb Library Reference" - -.SH NAME -slweb_html \- slweb HTML serializer - -.SH SYNOPSIS -.LP -.nf -#include -.fi - -.SH DESCRIPTION -This component allows library users to serialize HTML text from a tree -structure composed by one or more -.I struct html_node -objects. -.IR slweb_html (7) -provides the following functions: - -.IP \(bu 2 -.IR html_node_alloc (3) -allocates a -.I struct html_node -object, consumed by other functions from this component. - -.IP \(bu 2 -.IR html_node_free (3) -frees the memory from a -.I struct html_node -object previously allocated by a call to -.IR html_node_alloc (3), -plus all of the memory allocated by its children. - -.IP \(bu 2 -.IR html_node_set_value (3) -sets the HTML value for a -.I struct html_node -object, escaping characters that could case syntax errors, such as -.B < -.BR "" ( "LESS-THAN SIGN" ). - -.IP \(bu 2 -.IR html_node_set_value_unescaped (3) -sets the HTML value for a -.I struct html_node -object. As opposed to -.IR html_node_set_value (3), -no escaping is performed. - -.IP \(bu 2 -.IR html_node_add_attr (3) -adds an attribute to a -.I struct html_node -object. - -.IP \(bu 2 -.IR html_node_add_child (3) -allocates a children -.I struct html_node -object to another -.I struct html_node -object. - -.IP \(bu 2 -.IR html_node_add_sibling (3) -adds a sibling -.I struct html_node -object to another -.I struct html_node -object. - -.IP \(bu 2 -.IR html_serialize (3) -serializes a -.I struct html_node -object and all of its children into a null-terminated string with -the HTML-serialized data. - -Typically, a root -.I struct html_node -object is allocated via -.IR html_node_alloc (3), -and child nodes are appended to it via -.IR html_node_add_child (3). -Optionally, values and/or attributes can be added to nodes via -.IR html_node_set_value (3) -and -.IR html_node_add_attr (3), -respectively. -Finally, -.IR html_node_free (3) -shall free the memory used by the root node and all of its children. - -.SH EXAMPLE -The example below is a minimal showcase of some of the features -provided by -.IR slweb_html (7), -which prints a minimal HTML file to standard output: - -.PP -.in +4n -.EX -#include -#include -#include -#include - -int main() -{ - int ret = EXIT_FAILURE; - struct dynstr d; - struct html_node *const html = html_node_alloc("html"), *body; - static const char text[] = "testing slweb"; - - dynstr_init(&d); - - if (!html) - { - fprintf(stderr, "html_node_alloc_failed\en"); - goto end; - } - else if (!(body = html_node_add_child(html, "body"))) - { - fprintf(stderr, "html_node_add_child failed\en"); - goto end; - } - else if (html_node_set_value(body, text)) - { - fprintf(stderr, "html_node_set_value failed\en"); - goto end; - } - else if (html_serialize(html, &d)) - { - fprintf(stderr, "html_serialize failed\en"); - goto end; - } - - printf("%s", d.str); - ret = EXIT_SUCCESS; - -end: - dynstr_free(&d); - return ret; -} -.EE -.in -.PP - -This program should write the following data over standard output: - -.PP -.in +4n -.EX - - testing slweb - -.EE -.in -.PP - -.SH SEE ALSO -.BR html_node_alloc (3), -.BR html_node_free (3), -.BR html_node_set_value (3), -.BR html_node_set_value_unescaped (3), -.BR html_node_add_attr (3), -.BR html_node_add_child (3), -.BR html_node_add_sibling (3), -.BR html_serialize (3), -.BR slweb_html (7). - -.SH COPYRIGHT -Copyright (C) 2023 Xavier Del Campo Romero. -.P -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. diff --git a/doc/man7/slweb_http.7 b/doc/man7/slweb_http.7 deleted file mode 100644 index 682c378..0000000 --- a/doc/man7/slweb_http.7 +++ /dev/null @@ -1,649 +0,0 @@ -.TH SLWEB_HTTP 7 2023-09-15 0.1.0 "slweb Library Reference" - -.SH NAME -slweb_http \- slweb HTTP connection handling and utilities - -.SH SYNOPSIS -.LP -.nf -#include -.fi - -.SH DESCRIPTION -As one of its key features, -\fIslweb\fR -provides a HTTP/1.1-compatible server implementation that can be -embedded into applications as a library. While not a complete HTTP/1.1 -server implementation, the following features are supported: - -.IP \(bu 2 -.BR GET . -.IP \(bu 2 -.BR POST . -.IP \(bu 2 -.IR multipart/form-data -encoded -data. An optional payload size limit can be defined (see section -.BR "HTTP server configuration" ). -.IP \(bu 2 -Cookies. - -.SS Utility functions -The functions listed below are meant for library users: - -.IP \(bu 2 -.IR http_response_add_header (3). -.IP \(bu 2 -.IR http_cookie_create (3). -.IP \(bu 2 -.IR http_encode_url (3). -.IP \(bu 2 -.IR http_decode_url (3). - -.SS HTTP connection-related functions - -The functions listed below are meant for internal use by -.IR slweb : - -.IP \(bu 2 -.IR http_alloc (3). -.IP \(bu 2 -.IR http_free (3). -.IP \(bu 2 -.IR http_update (3). - -However, this component alone does not provide a working web server. -For example, a list of endpoints is required to define its behaviour, -and -.I struct http -objects must be stored somewhere as long as the connections are active. -.IR slweb_handler (7) -is the component meant to provide the missing pieces that conform a -working web server. - -.SS HTTP server configuration - -A HTTP server is contained into a -.IR "struct http_ctx" , -and can be allocated by calling -.IR http_alloc (3). -This function requires a valid pointer to a -.I "struct http_cfg" -object. This flexible configuration allows the library to run on top of -any reliable transport layer, including TCP. -.I "struct http_cfg" -is defined as: - -.PP -.in +4n -.EX -struct http_cfg -{ - int (*\fIread\fP)(void *\fIbuf\fP, size_t \fIn\fP, void *\fIuser\fP); - int (*\fIwrite\fP)(const void *\fIbuf\fP, size_t \fIn\fP, void *\fIuser\fP); - int (*\fIpayload\fP)(const struct http_payload *\fIp\fP, struct http_response *\fIr\fP, void *\fIuser\fP); - int (*\fIlength\fP)(unsigned long long \fIlen\fP, const struct http_cookie *\fIc\fP, struct http_response *\fIr\fP, void *\fIuser\fP); - const char *\fItmpdir\fP; - void *\fIuser\fP; -}; -.EE -.in -.PP - -All of the function pointers listed above define -.I user -as a parameter, an opaque pointer to user-defined data previously -defined by member -.I user -(see definition below). Unless noted otherwise, all pointers must be -valid. - -.I read -is a function pointer to a -.IR read (2)-like -function that must read up to -.I n -bytes -from the client into a buffer pointed to by -.IR buf . -The function pointed to by -.I read -returns the number of bytes that could be read from the client, -which could be from zero up to -.IR n . -On error, a negative integer is returned. - -.I write -is a function pointer to a -.IR write (2)-like -function that must write up to -.I n -bytes -to the client from a buffer pointed to by -.IR buf . -It returns the number of bytes that could be written to the client, -which could be from zero to -.IR n . -On error, a negative integer is returned. - -.I payload -is a function pointer called by -.I slweb -when a new HTTP request has been received. -.I p -is a read-only pointer to a -.I "struct http_payload" -object, which describes the HTTP request (see section -.BR "HTTP payload" ). -.I r -is a pointer to a -.I "struct http_response" -object that must be initialized by the function pointed to by -.IR payload , -which includes the HTTP response parameters to be returned to the -client. -The function pointed to by -.I read -returns the number of bytes that could be read from the client, -which could be from zero to -.IR n . -This function returns zero on success. On error, a negative integer is -returned. - -.I length -is a function pointer called by -.I slweb -when an incoming HTTP request from a client requires to store one or -more files on the server, encoded as -.IR multipart/form-data . -.I len -defines the length of the -.IR multipart/form-data -(see section -.BR "Content-Length design limitations for multipart/form-data" ). -.I c -is a read-only pointer to a -.I "struct http_cookie" -object, containing at most -.B one -(see section -.BR "Limitations on the number of HTTP cookies" ) -HTTP cookie. If no cookies are defined, its members shall contain null -pointers. -.I r -is a pointer to a -.I "struct http_response" -object that must be initialized by the function pointed to by -.I payload -only when the function returns a positive integer. -This function returns zero on success, a negative integer in case -of a fatal error or a positive integer in case of a non-fatal error -caused by a malformed request, or to indicate a lack of support for -this feature. When a positive integer is returned, the connection -against the client shall be closed. - -.I tmpdir -is a null-terminated string defining the path to a directory where -files uploaded by clients shall be stored temporarily. -.I tmpdir -can be a null pointer if this feature is not supported by the -application. - -.I user -is an opaque pointer to a user-defined object that shall be passed to -other function pointers defined by -.IR "struct http_cfg" . -.I user -can be a null pointer. - -.SS HTTP payload - -When a client submits a request to the server, -.I slweb -prepares a high-level data structure, called -.IR "struct http_payload" , -and passes it to the function pointer defined by -.I "struct http_cfg" -member -.IR payload . -.I "struct http_payload" -is defined as: - -.PP -.in +4n -.EX -struct http_payload -{ - enum http_op \fIop\fP; - const char *\fIresource\fP; - struct http_cookie \fIcookie\fP; - - union - { - struct http_post \fIpost\fP; - } \fIu\fP; - - const struct http_arg *\fIargs\fP; - size_t \fIn_args\fP; -}; -.EE -.in -.PP - -.I op -describes the HTTP/1.1 operation. See the definition for -.I "enum http_op" -for an exhaustive list of supported operations. - -.I resource -describes which resource is being requested by the client. For example: -.IR /index.html . - -.I cookie -contains at most -.B one -HTTP cookie, defined as a key-value pair. Its members shall be null -pointers if no cookie is present. Also, see section -.BR "Limitations on the number of HTTP cookies" . - -.I u -defines a tagged union with operation-specific data. For example, -.I post -refers to data sent by a client on a -.B POST -request (see section -.BR "HTTP POST payload" ). -Also, see section -.BR "Future supported HTTP/1.1 operations" . - -.I args -defines a list of key-value pairs containing URL parameters. Its length -is defined by -.IR n_args . - -.SS HTTP POST payload - -As opposed to payload-less HTTP/1.1 operations, such as -.BR GET , -.B POST -operations might or might not include payload data. Moreover, such -payload can be encoded in two different ways, which -.I slcl -handles differently: - -.IP \(bu 2 -.IR application/x-www-form-urlencoded : -suggested for smaller payloads. -.I slweb -shall store the payload in memory, limiting its maximum size to -.BR "7999 octets" . - -.IP \(bu 2 -.IR multipart/form-data : -suggested for larger and/or binary payloads. -.I slweb -shall store each non-file name-value pair in memory, limiting the value -length to -.BR "8000 octets" . -On the other hand, -.I slweb -shall store each file into the temporary directory defined by -.I struct http_cfg -member -.IR tmpdir . - -This information is contained into a -.B "struct http_post" -object, defined as: - -.PP -.in +4n -.EX -struct http_post -{ - bool \fIexpect_continue\fP; - const char *\fIdata\fP; - size_t \fInfiles\fP, \fInpairs\fP; - - const struct http_post_pair - { - const char *\fIname\fP, *\fIvalue\fP; - } *\fIpairs\fP; - - const struct http_post_file - { - const char *\fIname\fP, *\fItmpname\fP, *\fIfilename\fP; - } *\fIfiles\fP; -}; -.EE -.in -.PP - -.I expect_continue -shall be set to -.I true -if an -.B "Expect: 100-continue" -HTTP header is received, -.I false -otherwise (see -section -.B Handling of 100-continue requests -in -.BR BUGS ). - -When -.IR application/x-www-form-urlencoded -data -is included, -.I data -shall contain a null-terminated string with the user payload. Data must -be decoded by applications (see section -.BR "Handling application/x-www-form-urlencoded data" ). -Otherwise, -.I data -shall be a null pointer. - -In the case of -.IR multipart/form-data , -.I files -shall contain a list of files that were uploaded by the client, each -one stored by the server to a temporary file, defined by -.IR tmpname . -The final name for the uploaded file is defined by -.IR filename . -The key -.B name -used for each requested file is defined by -.IR name . -The length of this list is defined by -.IR nfiles . -If no files are defined, -.I files -shall be a null pointer. - -In the case of -.IR multipart/form-data , -.I pairs -shall contain a list of name-value pairs that were uploaded by the -client, defined by -.I name -and -.IR value , -respectively. The length of this list is defined by -.IR npairs . -If no name-value pairs are defined, -.I pairs -shall be a null pointer. - -.SS HTTP responses - -Some function pointers used by -.I slweb -require to initialize a -.I "struct http_response" -object that defines the response that must be sent to the client. -This structure is defined as: - -.PP -.in +4n -.EX -struct http_response -{ - enum http_status \fIstatus\fP; - - struct http_header - { - char *\fIheader\fP, *\fIvalue\fP; - } *\fIheaders\fP; - - union - { - const void *\fIro\fP; - void *\fIrw\fP; - } \fIbuf\fP; - - FILE *\fIf\fP; - unsigned long long \fIn\fP; - size_t \fIn_headers\fP; - void (*\fIfree\fP)(void *); -}; -.EE -.in -.PP - -.I status -is the response code to be returned to the client. A list of possible -values is defined by -.IR "enum http_status" . - -.I headers -is a pointer to an array of -.I "struct http_header" -whose length is defined by -.IR n_headers , -containing the HTTP headers to be included into the response. Note that -.I headers -is not meant to be modified directly by library users. Instead, the -.IR http_response_add_header (3) -utility function shall update the -.I "struct http_response" -object accordingly. - -.I buf -is a union containing two possible values, with minor semantic -differences: - -.I ro -is a read-only opaque pointer to a buffer in memory, whose length is -defined by -.I n -(see definition below). -.I slweb -shall select -.I ro -as the output payload if both -.I f -and -.I free -are null pointers, and -.I n -is non-zero. - -.I rw -is an opaque pointer to a buffer in memory, whose length is defined by -.I n -(see definition below). -.I slweb -shall select -.I rw -as the output payload if both -.I f -is a null pointer and -.I free -is a valid pointer to a function that frees the memory used by -.IR rw , -and -.I n -is non-zero. - -.I f -is a -.I FILE -pointer opened for reading that defines the payload to be sent to the -client, whose length is defined by -.IR n . -.I slweb -shall select -.I f -as the output payload if -.IR ro , -.I rw -and -.I free -are null pointers, and -.I n -is non-zero. - -.I n -is the length of the output payload, which can be either a buffer in -memory (see definitions for -.I ro -and -.IR rw ) -or a file (see definition for -.IR f ). -If -.I n -equals zero, no payload shall be sent. - -.I n_headers -defines the number of HTTP headers contained in the response. This -field is not meant to be manipulated directly. Instead, the -.IR http_response_add_header (3) -utility function shall update the -.I "struct http_response" -object accordingly. - -.I free -is a pointer to a function that frees the memory used by -.I rw -.B only if -.I rw -is a valid pointer. Otherwise, -.I free -must be a null pointer. - -.SS Transport Layer Security (TLS) -By design, -.I slweb -does -.BI not -implement TLS (Transport Layer Security). It is assumed this should -be provided by a reverse proxy instead, a kind of project that is -usually maintained by a larger community than -.I slweb -and audited for security vulnerabilities. - -.SH NOTES -.SS Comparing against other HTTP server implementations -While it is well understood that other solutions provide fully-fledged -server implementations as standalone executables, -.I slweb -strives to be as small and easy to use as possible, intentionally -limiting its scope while covering a good range of use cases. - -.SS Content-Length design limitations for multipart/form-data -HTTP/1.1 defines the Content-Length for a -.I multipart/form-data -.B POST -request as the sum of: - -.IP \(bu 2 -The length of all files. -.IP \(bu 2 -The length of all boundaries. -.IP \(bu 2 -The length of all headers included on each part. -.IP \(bu 2 -All separator tokens, such as -.B LFCR -or -.BR -- . - -This means it is not possible for -.I slweb -to determine the number of files or their lengths in a HTTP request -unless the whole request is read, which not might be possible for large -requests. Therefore, the -.B Content-Length -is the only rough estimation -.I slweb -can rely on, and therefore is the value passed to the -.I length -function pointer in -.IR "struct http_cfg" . - -.SH BUGS -.SS Handling of 100-continue requests - -The handling of -.B 100-continue -requests is not done correctly: -.I slweb -calls the function pointed to by -.I "struct http_cfg" -member -.I payload -as soon as it encounters the -.B Expected: -header. However, a response should only be sent to the client once all -headers are processed. - -.SH FUTURE DIRECTIONS -.SS Limitations on the number of HTTP cookies -So far, -.I slweb -shall only append at most -.B one -HTTP cookie to a -.I "struct http_payload" -object. This is due to arbitrary design limitations on the library. -Future versions of this library shall replace the -.I "struct http_cookie" -object inside -.I "struct http_payload" -with a pointer to an array of -.IR "struct http_cookie" , -plus a -.I size_t -object containing the number of HTTP cookies in the request. - -.SS Handling application/x-www-form-urlencoded data -Due to historical reasons, -.I slweb -treated -.IR application/x-www-form-urlencoded -data -as a binary blob. While this was changed to a null-terminated string in -order to allow applications to avoid unnecessary memory allocations, -.I slweb -still does not decode the data, instead forcing applications to do so. -Future versions of this library shall replace -.I "struct http_post" -member -.I data -with an array of structures containing key-value pairs, so that -applications no longer need to decode payload data by themselves. - -.SS Future supported HTTP/1.1 operations -So far, -.I struct http_payload -defines -.I u -as a union that only holds one possible data type. While this might -look counterintuitive, this is because -.B POST -is the only HTTP/1.1 operation -.I slweb -supports that requires to store a payload. However, future versions of -this library might extend its support for other HTTP/1.1 operations -that could require to store a payload, while keeping the memory -footprint for -.I struct http_payload -small. - -.SH SEE ALSO -.BR handler_alloc (3), -.BR http_alloc (3), -.BR http_free (3), -.BR http_update (3), -.BR http_response_add_header (3), -.BR http_cookie_create (3), -.BR http_encode_url (3), -.BR http_decode_url (3). - -.SH COPYRIGHT -Copyright (C) 2023 Xavier Del Campo Romero. -.P -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. -- cgit v1.2.3