diff options
| author | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-09-27 01:09:04 +0200 |
|---|---|---|
| committer | Xavier Del Campo Romero <xavi.dcr@tutanota.com> | 2023-09-27 21:55:58 +0200 |
| commit | adb0973bb355b9f7eb27d9842116e43c7f77d261 (patch) | |
| tree | 295eba8a1f2fde6e6d500fbe7b32ac5330d0bbbe | |
| parent | 0d54bbf08674174c1e7b91ce39984c29b78cf0ba (diff) | |
Add man pages
| -rw-r--r-- | doc/man3/handler_add.3 | 88 | ||||
| -rw-r--r-- | doc/man3/handler_alloc.3 | 59 | ||||
| -rw-r--r-- | doc/man3/handler_free.3 | 40 | ||||
| -rw-r--r-- | doc/man3/handler_listen.3 | 73 | ||||
| -rw-r--r-- | doc/man3/html_node_add_attr.3 | 77 | ||||
| -rw-r--r-- | doc/man3/html_node_add_child.3 | 124 | ||||
| -rw-r--r-- | doc/man3/html_node_add_sibling.3 | 55 | ||||
| -rw-r--r-- | doc/man3/html_node_alloc.3 | 75 | ||||
| -rw-r--r-- | doc/man3/html_node_free.3 | 48 | ||||
| -rw-r--r-- | doc/man3/html_node_set_value.3 | 80 | ||||
| -rw-r--r-- | doc/man3/html_node_set_value_unescaped.3 | 81 | ||||
| -rw-r--r-- | doc/man3/html_serialize.3 | 52 | ||||
| -rw-r--r-- | doc/man3/http_alloc.3 | 62 | ||||
| -rw-r--r-- | doc/man3/http_cookie_create.3 | 68 | ||||
| -rw-r--r-- | doc/man3/http_encode_url.3 | 38 | ||||
| -rw-r--r-- | doc/man3/http_free.3 | 41 | ||||
| -rw-r--r-- | doc/man3/http_response_add_header.3 | 53 | ||||
| -rw-r--r-- | doc/man3/http_update.3 | 76 | ||||
| -rw-r--r-- | doc/man7/slweb_handler.7 | 229 | ||||
| -rw-r--r-- | doc/man7/slweb_html.7 | 178 | ||||
| -rw-r--r-- | doc/man7/slweb_http.7 | 649 |
21 files changed, 2246 insertions, 0 deletions
diff --git a/doc/man3/handler_add.3 b/doc/man3/handler_add.3 new file mode 100644 index 0000000..4c93f7a --- /dev/null +++ b/doc/man3/handler_add.3 @@ -0,0 +1,88 @@ +.TH HANDLER_ADD 3 2023-09-13 0.1.0 "slweb Library Reference" + +.SH NAME +handler_add \- add an endpoint to a web server handler object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/handler.h> +.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 + +.SH DESCRIPTION +The +.IR handler_add () +function adds an endpoint to a +.I struct handler +object previously allocated by +.IR handler_alloc (3), +pointed to by +.IR h . + +.I url +is a null-terminated string that defines the target resource. The +metacharacter +.B * +can be used to match any number of characters. For example, +.B "/user/*/file" +shall match resources such as +.B /user/alice/file +or +.BR /user/bob/nested/file . + +.I op +describes the HTTP/1.1 operation supported by the endpoint. See the +definition for +.I "enum http_op" +for an exhaustive list of supported operations. + +.I f +is a function pointer that shall be executed by +.I slweb +if an incoming request matches the resource and operation defined by +.I url +and +.IR op , +respectively. See +.IR slweb_handler (7) +for the definition for +.IR handler_fn . + +.I user +is an opaque pointer to a user-defined object that shall be passed to +the function pointed to by +.IR f . +.I user +can be a null pointer. + +.SH RETURN VALUE +On success, zero is returned. On error, a negative integer is returned, +and +.I errno +might be set by the internal calls to +.IR realloc (3) +or +.IR strdup (3). + +.SH ERRORS +Refer to +.IR malloc (3) +and +.IR strdup (3) +for a list of possible errors. + +.SH SEE ALSO +.BR handler_alloc (3), +.BR handler_free (3), +.BR handler_listen (3), +.BR slweb_handler (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/man3/handler_alloc.3 b/doc/man3/handler_alloc.3 new file mode 100644 index 0000000..e71b569 --- /dev/null +++ b/doc/man3/handler_alloc.3 @@ -0,0 +1,59 @@ +.TH HANDLER_ALLOC 3 2023-09-13 0.1.0 "slweb Library Reference" + +.SH NAME +handler_alloc \- allocate a web server handler object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/handler.h> +.P +struct handler *handler_alloc(const struct handler_cfg *\fIcfg\fP); +.fi + +.SH DESCRIPTION +The +.IR handler_alloc (3) +function allocates a +.I "struct handler" +object, containing the required data by +.I slweb +to handle a web server. This object is meant to be consumed by +other functions from +.IR slweb_handler (7). +.I cfg +defines the initial configuration, whose structure is defined by +.IR slweb_handler (7). + +.I "struct handler" +is an opaque object internal to +.I slweb +and therefore is not accessible to callers. + +.SH RETURN VALUE +On success, an opaque pointer to a +.I struct handler +object is returned. On error, +a null pointer is returned, and +.I errno +might be set by the internal call to +.IR malloc (3). + +.SH ERRORS +Refer to +.IR malloc (3) +for a list of possible errors. + +.SH SEE ALSO +.BR handler_free (3), +.BR handler_add (3), +.BR handler_listen (3), +.BR slweb_handler (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/man3/handler_free.3 b/doc/man3/handler_free.3 new file mode 100644 index 0000000..1a89fa9 --- /dev/null +++ b/doc/man3/handler_free.3 @@ -0,0 +1,40 @@ +.TH HANDLER_FREE 3 2023-09-14 0.1.0 "slweb Library Reference" + +.SH NAME +handler_free \- free a web server handler object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/handler.h> +.P +void handler_free(struct handler *\fIh\fP); +.fi + +.SH DESCRIPTION +The +.IR handler_free (3) +function frees the memory space pointed to by +.IR h , +which must have been returned by a previous call to +.IR handler_alloc (3). + +.SH RETURN VALUE +The +.IR handler_free (3) +function returns no value. + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR handler_alloc (3), +.BR slweb_handler (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/man3/handler_listen.3 b/doc/man3/handler_listen.3 new file mode 100644 index 0000000..cc2cfbb --- /dev/null +++ b/doc/man3/handler_listen.3 @@ -0,0 +1,73 @@ +.TH HANDLER_LISTEN 3 2023-09-14 0.1.0 "slweb Library Reference" + +.SH NAME +handler_listen \- listen to and handle incoming connections on a web +server + +.SH SYNOPSIS +.LP +.nf +#include <slweb/handler.h> +.P +int handler_listen(struct handler *\fIh\fP, unsigned short \fIport\fP); +.fi + +.SH DESCRIPTION +The +.IR handler_listen (3) +function listens for connections on the TCP port number given by +.I port +on a +.I struct handler +object pointed to by +.IR h , +which must be previously allocated by a call to +.IR handler_alloc (3). + +Also, the +.IR handler_listen (3) +function validates incoming requests and calls the configured +callbacks previously given by one or more calls to +.IR handler_add (3). + +The +.IR handler_listen (3) +function blocks until either +.I SIGTERM +or +.I SIGINT +are triggered. + +.SH RETURN VALUE +On success, zero is returned. On error, a negative integer is returned. + +.SH ERRORS +No errors are defined. + +.SH FUTURE DIRECTIONS +When no configured endpoint matches the incoming request, +.I slweb +shall respond with a +.B 404 Not Found +HTTP status code with no payload. Since some library users might want +to provide custom pages for such error condition, future versions of +this library shall replace the harcoded response with an additional +callback on +.IR "struct handler_cfg" , +similarly to its member +.IR length . + +.SH SEE ALSO +.BR handler_alloc (3), +.BR handler_free (3), +.BR handler_add (3), +.BR slweb_handler (7), +.BR signal (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/man3/html_node_add_attr.3 b/doc/man3/html_node_add_attr.3 new file mode 100644 index 0000000..d6d3bf0 --- /dev/null +++ b/doc/man3/html_node_add_attr.3 @@ -0,0 +1,77 @@ +.TH HTML_NODE_ADD_ATTR 3 2023-09-24 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_add_attr \- add attribute to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +int html_node_add_attr(struct html_node *\fIn\fP, const char *\fIattr\fP, const char *\fIval\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_add_attr (3) +function adds an attribute to a +.I struct html_node +object pointed to by +.IR n , +previously returned by +.IR html_node_alloc (3) +or +.IR html_node_add_child (3). +.I attr +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 +allocates copies of the null-terminated strings defined by +.I attr +and +.IR val . + +.SH RETURN VALUE +On success, +.IR html_node_add_attr (3) +returns zero. On failure, a negative integer is returned. + +.SH EXAMPLE +A +.I struct html_node +object with +.B example +as tag name, no value and +.B name +as its attribute with value +.B john +would be translated by the HTML +serializer to: + +.PP +.in +4n +.EX +<example name="john"/> +.EE +.in +.PP + +.SH ERRORS +No errors are defined. + +.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 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/man3/html_node_add_child.3 b/doc/man3/html_node_add_child.3 new file mode 100644 index 0000000..360f968 --- /dev/null +++ b/doc/man3/html_node_add_child.3 @@ -0,0 +1,124 @@ +.TH HTML_NODE_ADD_CHILD 3 2023-09-25 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_add_child \- add child to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +struct html_node *html_node_add_child(struct html_node *\fIn\fP, const char *\fIelem\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_add_child (3) +function allocates a child +.I struct html_node +object into another +.I struct html_node +object, previously allocated by a call to +.IR html_node_alloc (3) +or +.IR html_node_add_child (3), +and pointed to by +.IR n . +The tag name for the child node is defined by +.IR elem . + +.SH RETURN VALUE +On success, +.IR html_node_add_child (3) +returns zero. On failure, a negative integer is returned. + +.SH EXAMPLE + +The following example shall print a tree structure with a root node +and one child node: + +.PP +.in +4n +.EX +#include <dynstr.h> +#include <slweb/html.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) +{ + int ret = EXIT_FAILURE; + struct html_node *const root = html_node_alloc("root"), *child; + struct dynstr d; + + dynstr_init(&d); + + if (!root) + { + fprintf(stderr, "html_node_alloc failed\en"); + goto end; + } + else if (!(child = html_node_add_child(root, "child"))) + { + fprintf(stderr, "html_node_add_child failed\en"); + goto end; + } + else if (html_serialize(root, &d)) + { + fprintf(stderr, "html_serialize failed\en"); + goto end; + } + + printf("%s", d.str); + ret = EXIT_SUCCESS; + +end: + html_node_free(root); + dynstr_free(&d); + return ret; +} +.EE +.in +.PP + +The following results shall be written to the standard output: + +.PP +.in +4n +.EX +<root> + <child/> +</root> +.EE +.in +.PP + +.SH ERRORS +No errors are defined. + +.SH NOTES +Adding a child to an existing +.I struct html_node +object is an atomic operation, which means no changes are applied to it +if +.IR html_node_add_child (3) +fails. + +Internally, +.I slweb +calls +.IR html_node_add_sibling (3) +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). + +.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/man3/html_node_add_sibling.3 b/doc/man3/html_node_add_sibling.3 new file mode 100644 index 0000000..951242f --- /dev/null +++ b/doc/man3/html_node_add_sibling.3 @@ -0,0 +1,55 @@ +.TH HTML_NODE_ADD_SIBLING 3 2023-09-25 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_add_sibling \- add sibling to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +void html_node_add_sibling(struct html_node *\fIn\fP, struct html_node *\fIsibling\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_add_sibling (3) +function adds a sibling node, pointed to by +.IR sibling , +to a +.I struct html_node +object, previously allocated by a call to +.IR html_node_alloc (3) +or +.IR html_node_add_child (3), +and pointed to by +.IR n . + +.SH RETURN VALUE +The +.IR html_node_add_sibling (3) +function always succeeds. + +.SH ERRORS +No errors are defined. + +.SH NOTES +This function is mostly meant for internal use. Library users should +only need +.IR html_node_add_child (3) +to create tree structures. Nonetheless, +.IR html_node_add_sibling (3) +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). + +.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/man3/html_node_alloc.3 b/doc/man3/html_node_alloc.3 new file mode 100644 index 0000000..9551bd3 --- /dev/null +++ b/doc/man3/html_node_alloc.3 @@ -0,0 +1,75 @@ +.TH HTML_NODE_ALLOC 3 2023-09-15 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_alloc \- allocate a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +struct html_node *html_node_alloc(const char *\fIelement\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_alloc (3) +function allocates a +.I "struct html_node" +object, which represents a node in a HTML tree. +.I element +is the name of the HTML tag. + +.I "struct html_node" +is an opaque object internal to +.I slweb +and therefore is not accessible to callers. + +.SH RETURN VALUE +On success, an opaque pointer to a +.I struct html_node +object is returned. On error, +a null pointer is returned, and +.I errno +might be set by the internal call to +.IR malloc (3). + +.SH ERRORS +Refer to +.IR malloc (3) +for a list of possible errors. + +.SH EXAMPLE +A +.I struct html_node +object with +.B example +as +.I element +with no attributes or value would be translated by the HTML serializer +to +.BR <example/> . + +.SH NOTES +Typically, +.IR html_node_alloc (3) +is used to allocate the root node, whereas children can be appended to +it via +.IR html_node_add_child (3). + +.SH SEE ALSO +.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 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/man3/html_node_free.3 b/doc/man3/html_node_free.3 new file mode 100644 index 0000000..6efc9ed --- /dev/null +++ b/doc/man3/html_node_free.3 @@ -0,0 +1,48 @@ +.TH HTML_NODE_FREE 3 2023-09-16 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_free \- free a HTML node and its children + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +void html_node_free(struct html_node *\fIn\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_free (3) +function frees the memory space pointed to by +.IR n , +which must have been returned by a previous call to +.IR html_node_alloc (3). +Children nodes are freed recursively. + +.SH RETURN VALUE +The +.IR html_node_free () +function returns no value. + +.SH ERRORS +No errors are defined. + +.SH NOTES +Since +.IR html_node_free (3) +frees nodes recursively, library users must not attempt to call +.IR html_node_free (3) +for a child node. + +.SH SEE ALSO +.BR html_node_alloc (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/man3/html_node_set_value.3 b/doc/man3/html_node_set_value.3 new file mode 100644 index 0000000..bc6dc9c --- /dev/null +++ b/doc/man3/html_node_set_value.3 @@ -0,0 +1,80 @@ +.TH HTML_NODE_SET_VALUE 3 2023-09-24 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_set_value \- set value to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +int html_node_set_value(struct html_node *\fIn\fP, const char *\fIval\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_set_value (3) +function sets a value to a +.I struct html_node +object pointed to by +.IR n , +previously returned by +.IR html_node_alloc (3) +or +.IR html_node_add_child (3). +.I val +is a null-terminated string with the value to be assigned to the node. + +.I slweb +allocates a copy of the null-terminated string defined by +.IR val . + +As opposed to +.IR html_node_set_value_unescaped (3), +.IR html_node_set_value (3) +escapes characters that could case syntax errors, such as +.B < +.BR "" ( "LESS-THAN SIGN" ) +being translated to +.BR < . + +.SH RETURN VALUE +On success, +.IR html_node_set_value (3) +returns zero. On failure, a negative integer is returned. + +.SH EXAMPLE +A +.I struct html_node +object with +.B example +as tag name and +.B hello +as its value and no attributes would be translated by the HTML +serializer to: + +.PP +.in +4n +.EX +<example>hello</example> +.EE +.in +.PP + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR html_node_alloc (3), +.BR html_node_free (3), +.BR html_node_set_value_unescaped (3), +.BR html_node_add_attr (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/man3/html_node_set_value_unescaped.3 b/doc/man3/html_node_set_value_unescaped.3 new file mode 100644 index 0000000..7c3a897 --- /dev/null +++ b/doc/man3/html_node_set_value_unescaped.3 @@ -0,0 +1,81 @@ +.TH HTML_NODE_SET_VALUE_UNESCAPED 3 2023-09-24 0.1.0 "slweb Library Reference" + +.SH NAME +html_node_set_value_unescaped \- set value to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +int html_node_set_value_unescaped(struct html_node *\fIn\fP, const char *\fIval\fP); +.fi + +.SH DESCRIPTION +The +.IR html_node_set_value_unescaped (3) +function sets a value to a +.I struct html_node +object pointed to by +.IR n , +previously returned by +.IR html_node_alloc (3) +or +.IR html_node_add_child (3). +.I val +is a null-terminated string with the value to be assigned to the node. + +.I slweb +allocates a copy of the null-terminated string defined by +.IR val . + +As opposed to +.IR html_node_set_value (3), +.IR html_node_set_value_unescaped (3) +does not escape characters that could case syntax errors, such as +.BR < +.BR "" ( "LESS-THAN SIGN" ). +This might make +.IR html_node_set_value_unescaped (3) +interesting to insert serialized HTML nodes as a value. + +.SH RETURN VALUE +On success, +.IR html_node_set_value_unescaped (3) +returns zero. On failure, a negative integer is returned. + +.SH EXAMPLE +A +.I struct html_node +object with +.B example +as tag name and +.B hello +as its value and no attributes would be translated by the HTML +serializer to: + +.PP +.in +4n +.EX +<example>hello</example> +.EE +.in +.PP + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR html_node_alloc (3), +.BR html_node_free (3), +.BR html_node_set_value (3), +.BR html_node_add_attr (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/man3/html_serialize.3 b/doc/man3/html_serialize.3 new file mode 100644 index 0000000..59700f1 --- /dev/null +++ b/doc/man3/html_serialize.3 @@ -0,0 +1,52 @@ +.TH HTML_SERIALIZE 3 2023-09-24 0.1.0 "slweb Library Reference" + +.SH NAME +html_serialize \- add attribute to a HTML node + +.SH SYNOPSIS +.LP +.nf +#include <slweb/html.h> +.P +int html_serialize(const struct html_node *\fIn\fP, struct dynstr *\fId\fP); +.fi + +.SH DESCRIPTION +The +.IR html_serialize (3) +function takes a +.I struct html_node +object pointed to by +.I n +and serializes it as a HTML file, as well as all of its children nodes, +into a null-terminated string. +.I d +is a +.I struct dynstr +object that must be previously initialized by a call to +.IR dynstr_init (3), +to which the null-terminated string shall be written. + +.SH RETURN VALUE +On success, +.IR html_serialize (3) +returns zero. On failure, a negative integer is returned. + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR html_node_alloc (3), +.BR html_node_free (3), +.BR html_node_add_attr (3), +.BR html_node_set_value (3), +.BR html_node_set_value_unescaped (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/man3/http_alloc.3 b/doc/man3/http_alloc.3 new file mode 100644 index 0000000..4b9e19b --- /dev/null +++ b/doc/man3/http_alloc.3 @@ -0,0 +1,62 @@ +.TH HTTP_ALLOC 3 2023-09-06 0.1.0 "slweb Library Reference" + +.SH NAME +http_alloc \- allocate a HTTP context object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +struct http *http_alloc(const struct http_cfg *\fIcfg\fP); +.fi + +.SH DESCRIPTION +The +.IR http_alloc (3) +function allocates a +.I "struct http_ctx" +object, containing the required data by +.I slweb +to handle a HTTP connection. This object is meant to be consumed by +other functions from +.IR slweb . +.I cfg +defines the configuration for the HTTP context, whose structure is defined by +.IR slweb_http (7). + +.I "struct http_ctx" +is an opaque object internal to +.I slweb +and therefore is not accessible to callers. + +.SH RETURN VALUE +On success, an opaque pointer to a +.I struct http_ctx +object is returned. On error, +a null pointer is returned, and +.I errno +might be set by the internal call to +.IR malloc (3). + +.SH ERRORS +Refer to +.IR malloc (3) +for a list of possible errors. + +.SH NOTES +This function is designed for internal use by +\fIslweb\fR. + +.SH SEE ALSO +.BR http_free (3), +.BR http_update (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/man3/http_cookie_create.3 b/doc/man3/http_cookie_create.3 new file mode 100644 index 0000000..6587b24 --- /dev/null +++ b/doc/man3/http_cookie_create.3 @@ -0,0 +1,68 @@ +.TH HTTP_COOKIE_CREATE 3 2023-09-07 0.1.0 "slweb Library Reference" + +.SH NAME +http_cookie_create \- creates a HTTP/1.1 cookie + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +char *http_cookie_create(const char *\fIkey\fP, const char *\fIvalue\fP); +.fi + +.SH DESCRIPTION +The +.IR http_cookie_create () +function allocates a null-terminated string with a HTTP/1.1 cookie +defined by +.I key +and +.IR value , +which are null-terminated strings. + +.SH RETURN VALUE +On success, a null-terminated string with the newly HTTP/1.1 cookie is +returned. Otherwise, a null pointer is returned. + +.SH ERRORS +No errors are defined. + +.SH EXAMPLE +A successful call to +.IR http_cookie_create (3) +with +.I ExampleValue +as +.I key +and +.I ExampleValue +as +.I value +might return a null-terminated string such as the one below: + +.LP +.in +4n +.EX +ExampleHeader=ExampleValue; HttpOnly; Expires Wed, 07 Sep 2023 00:00:00 GMT +.EE +.in + +.SH FUTURE DIRECTIONS + +.I slweb +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). + +.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/man3/http_encode_url.3 b/doc/man3/http_encode_url.3 new file mode 100644 index 0000000..94bd7f8 --- /dev/null +++ b/doc/man3/http_encode_url.3 @@ -0,0 +1,38 @@ +.TH HTTP_ENCODE_URL 3 2023-09-07 0.1.0 "slweb Library Reference" + +.SH NAME +http_encode_url \- allocates a percent-encoded null-terminated string + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +char *http_encode_url(const char *\fIurl\fP); +.fi + +.SH DESCRIPTION +The +.IR http_encode_url () +function encodes the null-terminated string given by +.I url +using percent-encoding as defined by RFC 3986. + +.SH RETURN VALUE +On success, a valid pointer to a percent-encoded, null-terminated +string is returned. On failure, a null pointer is returned. + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR http_decode_url (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/man3/http_free.3 b/doc/man3/http_free.3 new file mode 100644 index 0000000..3b8b61d --- /dev/null +++ b/doc/man3/http_free.3 @@ -0,0 +1,41 @@ +.TH HTTP_FREE 3 2023-09-06 0.1.0 "slweb Library Reference" + +.SH NAME +http_free \- free a HTTP context object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +void http_free(struct http_ctx *\fIh\fP); +.fi + +.SH DESCRIPTION +The +.IR http_free (3) +function frees the memory space pointed to by +.IR h , +which must have been returned by a previous call to +.IR http_alloc (3). + +.SH RETURN VALUE +The +.IR http_free (3) +function returns no value. + +.SH ERRORS +No errors are defined. + +.SH SEE ALSO +.BR http_alloc (3), +.BR http_update (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/man3/http_response_add_header.3 b/doc/man3/http_response_add_header.3 new file mode 100644 index 0000000..4f033ea --- /dev/null +++ b/doc/man3/http_response_add_header.3 @@ -0,0 +1,53 @@ +.TH HTTP_RESPONSE_ADD_HEADER 3 2023-09-07 0.1.0 "slweb Library Reference" + +.SH NAME +http_response_add_header \- adds a HTTP/1.1 header to a response + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +int http_response_add_header(struct http_response *\fIr\fP, const char *\fIheader\fP, const char *\fIvalue\fP); +.fi + +.SH DESCRIPTION +The +.IR http_response_add_header () +function updates a +.I "struct http_response" +object pointed to by +.IR r +by adding a new HTTP response to it, defined by +.I header +and +.IR value , +which are null-terminated strings defining the key +and value for the HTTP header, respectively. + +.SH RETURN VALUE +On success, zero is returned. If a fatal error ocurrs, a negative +integer is returned, and +.I errno +might be set by the internal calls to +.IR realloc (3) +or +.IR strdup (3). + +.SH ERRORS +Refer to +.IR realloc (3) +and +.IR strdup (3) +for a list of possible errors. + +.SH SEE ALSO +.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/man3/http_update.3 b/doc/man3/http_update.3 new file mode 100644 index 0000000..7f54608 --- /dev/null +++ b/doc/man3/http_update.3 @@ -0,0 +1,76 @@ +.TH HTTP_UPDATE 3 2023-09-06 0.1.0 "slweb Library Reference" + +.SH NAME +http_update \- updates a HTTP context object + +.SH SYNOPSIS +.LP +.nf +#include <slweb/http.h> +.P +int http_update(struct http_ctx *\fIh\fP, bool *\fIwrite\fP, bool *\fIclose\fP); +.fi + +.SH DESCRIPTION +The +.IR http_update () +function updates a +.I "struct http_ctx" +object previously allocated by +.IR http_alloc (3), +handling any pending data to be received/sent from/to a client. +This function might call one or more of the callbacks defined by the +.I "struct http_cfg" +object given by the previous call to +.IR http_alloc (3). + +.I http_update +shall assign the +.I bool +object pointed to by +.I write +to +.I true +if there is pending data to be sent to the client. Otherwise, it shall +assigned to +.IR false . + +.IR http_update () +shall assign the +.I bool +object pointed to by +.I close +to +.I true +if the connection must be closed by the caller. Otherwise, it shall be +assigned to +.IR false . + +This function should be called anytime there is available data for +input or output. + +.SH RETURN VALUE +On success, zero is returned. If a fatal error ocurrs, a negative +integer is returned. If a non-fatal error caused by malformed client +input occurs, a positive integer is returned and the connection against +the client shall be closed. + +.SH ERRORS +No errors are defined. + +.SH NOTES +This function is designed for internal use by +.IR slweb . + +.SH SEE ALSO +.BR http_free (3), +.BR http_update (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_handler.7 b/doc/man7/slweb_handler.7 new file mode 100644 index 0000000..53fb156 --- /dev/null +++ b/doc/man7/slweb_handler.7 @@ -0,0 +1,229 @@ +.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 <slweb/handler.h> +.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 <slweb/handler.h> +#include <slweb/http.h> +#include <stddef.h> +#include <stdlib.h> + +static int hello(const struct http_payload *const pl, + struct http_response *const r, void *const user) +{ + static const char page[] = + { + "<html><body><p>Hello from slweb!</p></body></html>" + }; + + *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 new file mode 100644 index 0000000..db8e224 --- /dev/null +++ b/doc/man7/slweb_html.7 @@ -0,0 +1,178 @@ +.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 <slweb/html.h> +.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 <slweb/html.h> +#include <dynstr.h> +#include <stdlib.h> +#include <stdio.h> + +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 +<html> + <body>testing slweb</body> +</html> +.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 new file mode 100644 index 0000000..682c378 --- /dev/null +++ b/doc/man7/slweb_http.7 @@ -0,0 +1,649 @@ +.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 <slweb/http.h> +.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. |
