aboutsummaryrefslogtreecommitdiff
path: root/doc/man7
diff options
context:
space:
mode:
Diffstat (limited to 'doc/man7')
-rw-r--r--doc/man7/slweb_handler.7229
-rw-r--r--doc/man7/slweb_html.7178
-rw-r--r--doc/man7/slweb_http.7649
3 files changed, 1056 insertions, 0 deletions
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.