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. --- CMakeLists.txt | 12 +- Makefile | 10 +- README.md | 50 +-- 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 ------------------------------- examples/hello/CMakeLists.txt | 2 +- examples/hello/Makefile | 10 +- examples/hello/README.md | 4 +- examples/hello/main.c | 8 +- examples/html/CMakeLists.txt | 2 +- examples/html/Makefile | 10 +- examples/html/README.md | 2 +- examples/html/main.c | 4 +- handler.c | 8 +- html.c | 2 +- http.c | 2 +- include/libweb/handler.h | 24 ++ include/libweb/html.h | 15 + include/libweb/http.h | 110 ++++++ include/libweb/server.h | 15 + include/libweb/wildcard_cmp.h | 8 + include/slweb/handler.h | 24 -- include/slweb/html.h | 15 - include/slweb/http.h | 110 ------ include/slweb/server.h | 15 - include/slweb/wildcard_cmp.h | 8 - libweb.pc | 11 + server.c | 2 +- slweb.pc | 11 - wildcard_cmp.c | 2 +- 53 files changed, 1381 insertions(+), 1381 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 create mode 100644 include/libweb/handler.h create mode 100644 include/libweb/html.h create mode 100644 include/libweb/http.h create mode 100644 include/libweb/server.h create mode 100644 include/libweb/wildcard_cmp.h delete mode 100644 include/slweb/handler.h delete mode 100644 include/slweb/html.h delete mode 100644 include/slweb/http.h delete mode 100644 include/slweb/server.h delete mode 100644 include/slweb/wildcard_cmp.h create mode 100644 libweb.pc delete mode 100644 slweb.pc diff --git a/CMakeLists.txt b/CMakeLists.txt index 41d2c8c..1a8bf44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.13.5) option(BUILD_EXAMPLES "Build examples" ON) -project(slweb C) +project(web C) add_library(${PROJECT_NAME} handler.c html.c @@ -11,12 +11,12 @@ add_subdirectory(dynstr) target_include_directories(${PROJECT_NAME} PUBLIC include) target_link_libraries(${PROJECT_NAME} PUBLIC dynstr) install(TARGETS ${PROJECT_NAME}) -install(DIRECTORY include/slweb TYPE INCLUDE) -file(READ ${CMAKE_CURRENT_LIST_DIR}/slweb.pc slweb_pc) -string(REPLACE /usr/local ${CMAKE_INSTALL_PREFIX} slweb_repl_pc ${slweb_pc}) -file(WRITE ${CMAKE_BINARY_DIR}/slweb.pc ${slweb_repl_pc}) +install(DIRECTORY include/libweb TYPE INCLUDE) +file(READ ${CMAKE_CURRENT_LIST_DIR}/libweb.pc libweb_pc) +string(REPLACE /usr/local ${CMAKE_INSTALL_PREFIX} libweb_repl_pc ${libweb_pc}) +file(WRITE ${CMAKE_BINARY_DIR}/libweb.pc ${libweb_repl_pc}) include(GNUInstallDirs) -install(FILES ${CMAKE_BINARY_DIR}/slweb.pc +install(FILES ${CMAKE_BINARY_DIR}/libweb.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) add_subdirectory(doc) diff --git a/Makefile b/Makefile index 246efdf..ceb27f6 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .POSIX: -PROJECT = libslweb.a +PROJECT = libweb.a PREFIX = /usr/local DST = $(PREFIX)/lib PC_DST = $(DST)/pkgconfig @@ -17,10 +17,10 @@ OBJECTS = \ all: $(PROJECT) -install: all $(PC_DST)/slweb.pc +install: all $(PC_DST)/libweb.pc mkdir -p $(PREFIX)/include - cp -R include/slweb $(PREFIX)/include - chmod 0644 $(PREFIX)/include/slweb/*.h + cp -R include/libweb $(PREFIX)/include + chmod 0644 $(PREFIX)/include/libweb/*.h mkdir -p $(DST) cp $(PROJECT) $(DST) chmod 0755 $(DST)/$(PROJECT) @@ -38,7 +38,7 @@ examples: FORCE $(PROJECT): $(OBJECTS) $(AR) $(ARFLAGS) $@ $(OBJECTS) -$(PC_DST)/slweb.pc: slweb.pc +$(PC_DST)/libweb.pc: libweb.pc mkdir -p $(PC_DST) sed -e 's,/usr/local,$(PREFIX),' $< > $@ chmod 0644 $@ diff --git a/README.md b/README.md index b608629..7fba559 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ -# slweb, a simple and lightweight web framework +# libweb, a simple and lightweight web framework -`slweb` is a simple and lightweight implementation of a web server, written in +`libweb` is a simple and lightweight implementation of a web server, written in C99 plus POSIX.1-2008 extensions, that can be integrated into applications. ## Disclaimer -Intentionally, `slweb` does not share some of the philosophical views from the +Intentionally, `libweb` does not share some of the philosophical views from the [suckless project](https://suckless.org). However, it still strives towards portability, minimalism, simplicity and efficiency. @@ -22,18 +22,18 @@ the operation (see example below). - Supports [`multiform/form-data`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST) , which makes it useful to transfer large amounts of data, such as binary files. -- [A library](include/slweb/html.h) to write HTML programmatically. +- [A library](include/libweb/html.h) to write HTML programmatically. ### TLS -In order to maintain simplicity and reduce the risk for security bugs, `slweb` +In order to maintain simplicity and reduce the risk for security bugs, `libweb` does **not** implement TLS support. Instead, this should be provided by a reverse proxy, such as [`caddy`](https://caddyserver.com/). ### Root permissions -`slweb` does not require root permissions. So, in order to avoid the -risk for security bugs, **please do not run `slweb` as `root`**. +`libweb` does not require root permissions. So, in order to avoid the +risk for security bugs, **please do not run `libweb` as `root`**. ## Requirements @@ -59,13 +59,13 @@ sudo apt install cmake ## How to use ### Build -Two build environments are provided for `slweb` - feel free to choose any of +Two build environments are provided for `libweb` - feel free to choose any of them: - A mostly POSIX-compliant [`Makefile`](Makefile). - A [`CMakeLists.txt`](CMakeLists.txt). -`slweb` can be built using the standard build process: +`libweb` can be built using the standard build process: #### Make @@ -73,21 +73,21 @@ them: $ make ``` -This would generate a static library, namely `libslweb.a`, on the project +This would generate a static library, namely `libweb.a`, on the project top-level directory. Applications can then call the top-level `Makefile` by -the use of recursive `make`. For example, assuming `slweb` is contained on a +the use of recursive `make`. For example, assuming `libweb` is contained on a subdirectory: ```make -slweb/libslweb.a: - +cd slweb && $(MAKE) +libweb/libweb.a: + +cd libweb && $(MAKE) ``` -Additionally, `slweb` can be installed using the `install` target. A +Additionally, `libweb` can be installed using the `install` target. A custom prefix can be assigned via the `PREFIX` variable: ```sh -$ make PREFIX=$HOME/slweb-prefix install +$ make PREFIX=$HOME/libweb-prefix install ``` By default, `PREFIX` is assigned to `/usr/local`. @@ -101,28 +101,28 @@ $ cmake .. $ cmake --build . ``` -A CMake target, also called `slweb`, is created. This makes it possible -to integrate `slweb` into CMake projects via `add_subdirectory` and +A CMake target, also called `libweb`, is created. This makes it possible +to integrate `libweb` into CMake projects via `add_subdirectory` and `target_link_libraries`. For example: ```cmake project(example) add_executable(${PROJECT_NAME} main.c) -add_subdirectory(slweb) -target_link_libraries(${PROJECT_NAME} PRIVATE slweb) +add_subdirectory(libweb) +target_link_libraries(${PROJECT_NAME} PRIVATE libweb) ``` -Additionally, `slweb` can be installed using the standard procedure +Additionally, `libweb` can be installed using the standard procedure in CMake. As usual, a custom prefix can be assigned via the `CMAKE_INSTALL_PREFIX` variable: ```sh -$ cmake --install build/ -DCMAKE_INSTALL_PREFIX=$HOME/slweb-prefix +$ cmake --install build/ -DCMAKE_INSTALL_PREFIX=$HOME/libweb-prefix ``` ### Examples -[A directory](examples) with examples shows how `slweb` can be used by +[A directory](examples) with examples shows how `libweb` can be used by applications. These can be built from the top-level directory with: ```sh @@ -141,7 +141,7 @@ $ cmake --build . ## Why this project? -Originally, `slweb` was part of the +Originally, `libweb` was part of the [`slcl`](https://gitea.privatedns.org/xavi92/slcl) project, a lightweight cloud solution also written in C99 plus POSIX extensions. However, there always was a clear separation between application logic and the underlying @@ -170,14 +170,14 @@ interface called simple as possible for administrators. - The [`onion`](https://github.com/davidmoreno/onion) project, which does follow the HTTP library concept, was initially considered for -`slcl`, but has a larger scope than `slweb`, and again simplicity was +`slcl`, but has a larger scope than `libweb`, and again simplicity was essential for `slcl`. - And, after all, it was a good excuse to learn about HTTP/1.1. ## License ``` -slweb, a simple and lightweight web framework. +libweb, a simple and lightweight web framework. Copyright (C) 2023 Xavier Del Campo Romero This program is free software: you can redistribute it and/or modify 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. diff --git a/examples/hello/CMakeLists.txt b/examples/hello/CMakeLists.txt index c22ab33..7d14ac6 100644 --- a/examples/hello/CMakeLists.txt +++ b/examples/hello/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 3.13) project(hello C) add_executable(hello main.c) -target_link_libraries(${PROJECT_NAME} PRIVATE slweb dynstr) +target_link_libraries(${PROJECT_NAME} PRIVATE web dynstr) diff --git a/examples/hello/Makefile b/examples/hello/Makefile index 217bccb..275fa5a 100644 --- a/examples/hello/Makefile +++ b/examples/hello/Makefile @@ -3,10 +3,10 @@ PROJECT = hello DEPS = \ main.o -SLWEB = ../../libslweb.a +LIBWEB = ../../libweb.a DYNSTR = ../../dynstr/libdynstr.a CFLAGS = -I ../../include -I ../../dynstr/include -SLWEB_FLAGS = -L ../../ -l slweb +LIBWEB_FLAGS = -L ../../ -l libweb DYNSTR_FLAGS = -L ../../dynstr -l dynstr all: $(PROJECT) @@ -16,10 +16,10 @@ clean: FORCE: -$(PROJECT): $(DEPS) $(SLWEB) $(DYNSTR) - $(CC) $(LDFLAGS) $(DEPS) $(SLWEB_FLAGS) $(DYNSTR_FLAGS) -o $@ +$(PROJECT): $(DEPS) $(LIBWEB) $(DYNSTR) + $(CC) $(LDFLAGS) $(DEPS) $(LIBWEB_FLAGS) $(DYNSTR_FLAGS) -o $@ -$(SLWEB): FORCE +$(LIBWEB): FORCE +cd ../../ && $(MAKE) $(DYNSTR): FORCE diff --git a/examples/hello/README.md b/examples/hello/README.md index 7c7cf74..24b747b 100644 --- a/examples/hello/README.md +++ b/examples/hello/README.md @@ -1,8 +1,8 @@ # "Hello world" example -This example shows a minimal setup for an application using `slweb`. When +This example shows a minimal setup for an application using `libweb`. When executed, it starts a HTTP/1.1 server on port `8080` and returns an example -website reading "Hello from slweb!" when either `/` or `/index.html` are +website reading "Hello from libweb!" when either `/` or `/index.html` are accessed by clients. ## How to build diff --git a/examples/hello/main.c b/examples/hello/main.c index d1a3206..59643ec 100644 --- a/examples/hello/main.c +++ b/examples/hello/main.c @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -30,7 +30,7 @@ static int hello(const struct http_payload *const pl, fprintf(stderr, "%s: html_node_add_child p failed\n", __func__); goto end; } - else if (html_node_set_value(p, "Hello from slweb!")) + else if (html_node_set_value(p, "Hello from libweb!")) { fprintf(stderr, "%s: html_node_set_value p failed\n", __func__); goto end; diff --git a/examples/html/CMakeLists.txt b/examples/html/CMakeLists.txt index bc4202d..410663b 100644 --- a/examples/html/CMakeLists.txt +++ b/examples/html/CMakeLists.txt @@ -1,4 +1,4 @@ cmake_minimum_required(VERSION 3.13) project(html C) add_executable(html main.c) -target_link_libraries(${PROJECT_NAME} PRIVATE slweb dynstr) +target_link_libraries(${PROJECT_NAME} PRIVATE web dynstr) diff --git a/examples/html/Makefile b/examples/html/Makefile index 77d94f8..87d27aa 100644 --- a/examples/html/Makefile +++ b/examples/html/Makefile @@ -3,10 +3,10 @@ PROJECT = html DEPS = \ main.o -SLWEB = ../../libslweb.a +LIBWEB = ../../libweb.a DYNSTR = ../../dynstr/libdynstr.a CFLAGS = -I ../../include -I ../../dynstr/include -SLWEB_FLAGS = -L ../../ -l slweb +LIBWEB_FLAGS = -L ../../ -l libweb DYNSTR_FLAGS = -L ../../dynstr -l dynstr all: $(PROJECT) @@ -16,10 +16,10 @@ clean: FORCE: -$(PROJECT): $(DEPS) $(SLWEB) $(DYNSTR) - $(CC) $(LDFLAGS) $(DEPS) $(SLWEB_FLAGS) $(DYNSTR_FLAGS) -o $@ +$(PROJECT): $(DEPS) $(LIBWEB) $(DYNSTR) + $(CC) $(LDFLAGS) $(DEPS) $(LIBWEB_FLAGS) $(DYNSTR_FLAGS) -o $@ -$(SLWEB): FORCE +$(LIBWEB): FORCE +cd ../../ && $(MAKE) $(DYNSTR): FORCE diff --git a/examples/html/README.md b/examples/html/README.md index ac89287..4d7544f 100644 --- a/examples/html/README.md +++ b/examples/html/README.md @@ -20,6 +20,6 @@ should be written to the standard output: - testing slweb + testing libweb ``` diff --git a/examples/html/main.c b/examples/html/main.c index c29e360..858aff7 100644 --- a/examples/html/main.c +++ b/examples/html/main.c @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -9,7 +9,7 @@ int main() struct dynstr d; struct html_node *const html = html_node_alloc("html"), *head, *meta, *body; - static const char text[] = "testing slweb"; + static const char text[] = "testing libweb"; dynstr_init(&d); diff --git a/handler.c b/handler.c index 49b9af9..61a2806 100644 --- a/handler.c +++ b/handler.c @@ -1,9 +1,9 @@ #define _POSIX_C_SOURCE 200809L -#include "slweb/handler.h" -#include "slweb/http.h" -#include "slweb/server.h" -#include "slweb/wildcard_cmp.h" +#include "libweb/handler.h" +#include "libweb/http.h" +#include "libweb/server.h" +#include "libweb/wildcard_cmp.h" #include #include #include diff --git a/html.c b/html.c index 482f133..5a92d77 100644 --- a/html.c +++ b/html.c @@ -1,6 +1,6 @@ #define _POSIX_C_SOURCE 200809L -#include "slweb/html.h" +#include "libweb/html.h" #include #include #include diff --git a/http.c b/http.c index 5bf5251..a475c64 100644 --- a/http.c +++ b/http.c @@ -1,6 +1,6 @@ #define _POSIX_C_SOURCE 200809L -#include "slweb/http.h" +#include "libweb/http.h" #include #include #include diff --git a/include/libweb/handler.h b/include/libweb/handler.h new file mode 100644 index 0000000..9cde129 --- /dev/null +++ b/include/libweb/handler.h @@ -0,0 +1,24 @@ +#ifndef HANDLER_H +#define HANDLER_H + +#include "libweb/http.h" +#include + +typedef int (*handler_fn)(const struct http_payload *p, + struct http_response *r, void *user); + +struct handler_cfg +{ + const char *tmpdir; + int (*length)(unsigned long long len, const struct http_cookie *c, + struct http_response *r, void *user); + void *user; +}; + +struct handler *handler_alloc(const struct handler_cfg *cfg); +void handler_free(struct handler *h); +int handler_add(struct handler *h, const char *url, enum http_op op, + handler_fn f, void *user); +int handler_listen(struct handler *h, unsigned short port); + +#endif /* HANDLER_H */ diff --git a/include/libweb/html.h b/include/libweb/html.h new file mode 100644 index 0000000..e62575e --- /dev/null +++ b/include/libweb/html.h @@ -0,0 +1,15 @@ +#ifndef HTML_H +#define HTML_H + +#include + +struct html_node *html_node_alloc(const char *element); +void html_node_free(struct html_node *n); +int html_node_set_value(struct html_node *n, const char *val); +int html_node_set_value_unescaped(struct html_node *n, const char *val); +int html_node_add_attr(struct html_node *n, const char *attr, const char *val); +struct html_node *html_node_add_child(struct html_node *n, const char *elem); +void html_node_add_sibling(struct html_node *n, struct html_node *sibling); +int html_serialize(const struct html_node *n, struct dynstr *d); + +#endif /* HTML_H */ diff --git a/include/libweb/http.h b/include/libweb/http.h new file mode 100644 index 0000000..68ffb9a --- /dev/null +++ b/include/libweb/http.h @@ -0,0 +1,110 @@ +#ifndef HTTP_H +#define HTTP_H + +#include +#include +#include + +struct http_payload +{ + enum http_op + { + HTTP_OP_GET, + HTTP_OP_POST, + HTTP_OP_HEAD + } op; + + const char *resource; + + struct http_cookie + { + const char *field, *value; + } cookie; + + union + { + struct http_post + { + bool expect_continue; + const char *data; + size_t nfiles, npairs; + + const struct http_post_pair + { + const char *name, *value; + } *pairs; + + const struct http_post_file + { + const char *name, *tmpname, *filename; + } *files; + } post; + } u; + + const struct http_arg + { + char *key, *value; + } *args; + + size_t n_args; +}; + +#define HTTP_STATUSES \ + X(CONTINUE, "Continue", 100) \ + X(OK, "OK", 200) \ + X(SEE_OTHER, "See other", 303) \ + X(BAD_REQUEST, "Bad Request", 400) \ + X(UNAUTHORIZED, "Unauthorized", 401) \ + X(FORBIDDEN, "Forbidden", 403) \ + X(NOT_FOUND, "Not found", 404) \ + X(PAYLOAD_TOO_LARGE, "Payload too large", 413) \ + X(INTERNAL_ERROR, "Internal Server Error", 500) + +struct http_response +{ + enum http_status + { +#define X(x, y, z) HTTP_STATUS_##x, + HTTP_STATUSES +#undef X + } status; + + struct http_header + { + char *header, *value; + } *headers; + + union + { + const void *ro; + void *rw; + } buf; + + FILE *f; + unsigned long long n; + size_t n_headers; + void (*free)(void *); +}; + +struct http_cfg +{ + int (*read)(void *buf , size_t n, void *user); + int (*write)(const void *buf, size_t n, void *user); + int (*payload)(const struct http_payload *p, struct http_response *r, + void *user); + int (*length)(unsigned long long len, const struct http_cookie *c, + struct http_response *r, void *user); + const char *tmpdir; + void *user; +}; + +struct http_ctx *http_alloc(const struct http_cfg *cfg); +void http_free(struct http_ctx *h); +int http_update(struct http_ctx *h, bool *write, bool *close); +int http_response_add_header(struct http_response *r, const char *header, + const char *value); +char *http_cookie_create(const char *key, const char *value); +char *http_encode_url(const char *url); +char *http_decode_url(const char *url, bool spaces); + +#endif /* HTTP_H */ diff --git a/include/libweb/server.h b/include/libweb/server.h new file mode 100644 index 0000000..74f06ae --- /dev/null +++ b/include/libweb/server.h @@ -0,0 +1,15 @@ +#ifndef SERVER_H +#define SERVER_H + +#include +#include + +struct server *server_init(unsigned short port); +struct server_client *server_poll(struct server *s, bool *io, bool *exit); +int server_read(void *buf, size_t n, struct server_client *c); +int server_write(const void *buf, size_t n, struct server_client *c); +int server_close(struct server *s); +int server_client_close(struct server *s, struct server_client *c); +void server_client_write_pending(struct server_client *c, bool write); + +#endif /* SERVER_H */ diff --git a/include/libweb/wildcard_cmp.h b/include/libweb/wildcard_cmp.h new file mode 100644 index 0000000..fa09913 --- /dev/null +++ b/include/libweb/wildcard_cmp.h @@ -0,0 +1,8 @@ +#ifndef WILDCARD_CMP_H +#define WILDCARD_CMP_H + +#include + +int wildcard_cmp(const char *s, const char *p, bool casecmp); + +#endif /* WILDCARD_CMP_H */ diff --git a/include/slweb/handler.h b/include/slweb/handler.h deleted file mode 100644 index 84a8073..0000000 --- a/include/slweb/handler.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef HANDLER_H -#define HANDLER_H - -#include "slweb/http.h" -#include - -typedef int (*handler_fn)(const struct http_payload *p, - struct http_response *r, void *user); - -struct handler_cfg -{ - const char *tmpdir; - int (*length)(unsigned long long len, const struct http_cookie *c, - struct http_response *r, void *user); - void *user; -}; - -struct handler *handler_alloc(const struct handler_cfg *cfg); -void handler_free(struct handler *h); -int handler_add(struct handler *h, const char *url, enum http_op op, - handler_fn f, void *user); -int handler_listen(struct handler *h, unsigned short port); - -#endif /* HANDLER_H */ diff --git a/include/slweb/html.h b/include/slweb/html.h deleted file mode 100644 index e62575e..0000000 --- a/include/slweb/html.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef HTML_H -#define HTML_H - -#include - -struct html_node *html_node_alloc(const char *element); -void html_node_free(struct html_node *n); -int html_node_set_value(struct html_node *n, const char *val); -int html_node_set_value_unescaped(struct html_node *n, const char *val); -int html_node_add_attr(struct html_node *n, const char *attr, const char *val); -struct html_node *html_node_add_child(struct html_node *n, const char *elem); -void html_node_add_sibling(struct html_node *n, struct html_node *sibling); -int html_serialize(const struct html_node *n, struct dynstr *d); - -#endif /* HTML_H */ diff --git a/include/slweb/http.h b/include/slweb/http.h deleted file mode 100644 index 68ffb9a..0000000 --- a/include/slweb/http.h +++ /dev/null @@ -1,110 +0,0 @@ -#ifndef HTTP_H -#define HTTP_H - -#include -#include -#include - -struct http_payload -{ - enum http_op - { - HTTP_OP_GET, - HTTP_OP_POST, - HTTP_OP_HEAD - } op; - - const char *resource; - - struct http_cookie - { - const char *field, *value; - } cookie; - - union - { - struct http_post - { - bool expect_continue; - const char *data; - size_t nfiles, npairs; - - const struct http_post_pair - { - const char *name, *value; - } *pairs; - - const struct http_post_file - { - const char *name, *tmpname, *filename; - } *files; - } post; - } u; - - const struct http_arg - { - char *key, *value; - } *args; - - size_t n_args; -}; - -#define HTTP_STATUSES \ - X(CONTINUE, "Continue", 100) \ - X(OK, "OK", 200) \ - X(SEE_OTHER, "See other", 303) \ - X(BAD_REQUEST, "Bad Request", 400) \ - X(UNAUTHORIZED, "Unauthorized", 401) \ - X(FORBIDDEN, "Forbidden", 403) \ - X(NOT_FOUND, "Not found", 404) \ - X(PAYLOAD_TOO_LARGE, "Payload too large", 413) \ - X(INTERNAL_ERROR, "Internal Server Error", 500) - -struct http_response -{ - enum http_status - { -#define X(x, y, z) HTTP_STATUS_##x, - HTTP_STATUSES -#undef X - } status; - - struct http_header - { - char *header, *value; - } *headers; - - union - { - const void *ro; - void *rw; - } buf; - - FILE *f; - unsigned long long n; - size_t n_headers; - void (*free)(void *); -}; - -struct http_cfg -{ - int (*read)(void *buf , size_t n, void *user); - int (*write)(const void *buf, size_t n, void *user); - int (*payload)(const struct http_payload *p, struct http_response *r, - void *user); - int (*length)(unsigned long long len, const struct http_cookie *c, - struct http_response *r, void *user); - const char *tmpdir; - void *user; -}; - -struct http_ctx *http_alloc(const struct http_cfg *cfg); -void http_free(struct http_ctx *h); -int http_update(struct http_ctx *h, bool *write, bool *close); -int http_response_add_header(struct http_response *r, const char *header, - const char *value); -char *http_cookie_create(const char *key, const char *value); -char *http_encode_url(const char *url); -char *http_decode_url(const char *url, bool spaces); - -#endif /* HTTP_H */ diff --git a/include/slweb/server.h b/include/slweb/server.h deleted file mode 100644 index 74f06ae..0000000 --- a/include/slweb/server.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef SERVER_H -#define SERVER_H - -#include -#include - -struct server *server_init(unsigned short port); -struct server_client *server_poll(struct server *s, bool *io, bool *exit); -int server_read(void *buf, size_t n, struct server_client *c); -int server_write(const void *buf, size_t n, struct server_client *c); -int server_close(struct server *s); -int server_client_close(struct server *s, struct server_client *c); -void server_client_write_pending(struct server_client *c, bool write); - -#endif /* SERVER_H */ diff --git a/include/slweb/wildcard_cmp.h b/include/slweb/wildcard_cmp.h deleted file mode 100644 index fa09913..0000000 --- a/include/slweb/wildcard_cmp.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef WILDCARD_CMP_H -#define WILDCARD_CMP_H - -#include - -int wildcard_cmp(const char *s, const char *p, bool casecmp); - -#endif /* WILDCARD_CMP_H */ diff --git a/libweb.pc b/libweb.pc new file mode 100644 index 0000000..8d3f0b9 --- /dev/null +++ b/libweb.pc @@ -0,0 +1,11 @@ +prefix=/usr/local +exec_prefix=${prefix} +includedir=${prefix}/include +libdir=${exec_prefix}/lib + +Name: libweb +Url: https://gitea.privatedns.org/xavi/libweb +Description: A simple and lightweight web framework +Version: 0.1.0 +Cflags: -I${includedir} +Libs: -L${libdir} -llibweb diff --git a/server.c b/server.c index b86a912..8cea044 100644 --- a/server.c +++ b/server.c @@ -6,7 +6,7 @@ #define _POSIX_C_SOURCE 200809L #endif -#include "slweb/server.h" +#include "libweb/server.h" #include #include #include diff --git a/slweb.pc b/slweb.pc deleted file mode 100644 index 3d79911..0000000 --- a/slweb.pc +++ /dev/null @@ -1,11 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -includedir=${prefix}/include -libdir=${exec_prefix}/lib - -Name: slweb -Url: https://gitea.privatedns.org/xavi/slweb -Description: A simple and lightweight web framework -Version: 0.1.0 -Cflags: -I${includedir} -Libs: -L${libdir} -lslweb diff --git a/wildcard_cmp.c b/wildcard_cmp.c index 1fcd451..e450190 100644 --- a/wildcard_cmp.c +++ b/wildcard_cmp.c @@ -1,4 +1,4 @@ -#include "slweb/wildcard_cmp.h" +#include "libweb/wildcard_cmp.h" #include #include #include -- cgit v1.2.3