2023-10-10 23:21:35 +02:00
|
|
|
# libweb, a simple and lightweight web framework
|
2023-07-21 00:37:02 +02:00
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
`libweb` is a simple and lightweight implementation of a web server, written in
|
2023-08-01 02:23:14 +02:00
|
|
|
C99 plus POSIX.1-2008 extensions, that can be integrated into applications.
|
2023-07-21 00:37:02 +02:00
|
|
|
|
|
|
|
## Disclaimer
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
Intentionally, `libweb` does not share some of the philosophical views from the
|
2023-08-01 02:23:14 +02:00
|
|
|
[suckless project](https://suckless.org). However, it still strives towards
|
|
|
|
portability, minimalism, simplicity and efficiency.
|
2023-07-21 00:37:02 +02:00
|
|
|
|
|
|
|
## Features
|
|
|
|
|
|
|
|
- Small and portable HTTP/1.1 server implementation, with support for
|
|
|
|
`GET` and `POST`.
|
|
|
|
- Provides a interface to set up user-defined callbacks depending on
|
|
|
|
the operation (see example below).
|
|
|
|
- Transport-agnostic implementation.
|
|
|
|
- While a POSIX socket, TCP-based implementation is already
|
|
|
|
provided, the HTTP interface can be mapped to any other reliable
|
|
|
|
transport layer.
|
|
|
|
- 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.
|
2023-10-10 23:21:35 +02:00
|
|
|
- [A library](include/libweb/html.h) to write HTML programmatically.
|
2023-07-21 00:37:02 +02:00
|
|
|
|
|
|
|
### TLS
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
In order to maintain simplicity and reduce the risk for security bugs, `libweb`
|
2023-07-21 00:37:02 +02:00
|
|
|
does **not** implement TLS support. Instead, this should be provided by a
|
|
|
|
reverse proxy, such as [`caddy`](https://caddyserver.com/).
|
|
|
|
|
|
|
|
### Root permissions
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
`libweb` does not require root permissions. So, in order to avoid the
|
|
|
|
risk for security bugs, **please do not run `libweb` as `root`**.
|
2023-07-21 00:37:02 +02:00
|
|
|
|
|
|
|
## Requirements
|
|
|
|
|
|
|
|
- A POSIX environment.
|
2023-07-28 01:32:47 +02:00
|
|
|
- [`dynstr`](https://gitea.privatedns.org/xavi/dynstr)
|
2023-07-21 00:37:02 +02:00
|
|
|
(provided as a `git` submodule).
|
|
|
|
- CMake (optional).
|
|
|
|
|
|
|
|
### Ubuntu / Debian
|
|
|
|
|
|
|
|
#### Mandatory packages
|
|
|
|
|
|
|
|
```sh
|
|
|
|
sudo apt install build-essential
|
|
|
|
```
|
|
|
|
|
|
|
|
#### Optional packages
|
|
|
|
|
|
|
|
```sh
|
|
|
|
sudo apt install cmake
|
|
|
|
```
|
|
|
|
|
|
|
|
## How to use
|
|
|
|
### Build
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
Two build environments are provided for `libweb` - feel free to choose any of
|
2023-07-21 00:37:02 +02:00
|
|
|
them:
|
|
|
|
|
|
|
|
- A mostly POSIX-compliant [`Makefile`](Makefile).
|
|
|
|
- A [`CMakeLists.txt`](CMakeLists.txt).
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
`libweb` can be built using the standard build process:
|
2023-07-21 00:37:02 +02:00
|
|
|
|
|
|
|
#### Make
|
|
|
|
|
|
|
|
```sh
|
|
|
|
$ make
|
|
|
|
```
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
This would generate a static library, namely `libweb.a`, on the project
|
2023-07-28 01:27:19 +02:00
|
|
|
top-level directory. Applications can then call the top-level `Makefile` by
|
2023-10-10 23:21:35 +02:00
|
|
|
the use of recursive `make`. For example, assuming `libweb` is contained on a
|
2023-07-28 01:27:19 +02:00
|
|
|
subdirectory:
|
|
|
|
|
|
|
|
```make
|
2023-10-10 23:21:35 +02:00
|
|
|
libweb/libweb.a:
|
|
|
|
+cd libweb && $(MAKE)
|
2023-07-28 01:27:19 +02:00
|
|
|
```
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
Additionally, `libweb` can be installed using the `install` target. A
|
2023-09-27 21:55:13 +02:00
|
|
|
custom prefix can be assigned via the `PREFIX` variable:
|
|
|
|
|
|
|
|
```sh
|
2023-10-10 23:21:35 +02:00
|
|
|
$ make PREFIX=$HOME/libweb-prefix install
|
2023-09-27 21:55:13 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
By default, `PREFIX` is assigned to `/usr/local`.
|
|
|
|
|
2023-07-21 00:37:02 +02:00
|
|
|
#### CMake
|
|
|
|
|
|
|
|
```sh
|
|
|
|
$ mkdir build/
|
2023-08-09 00:31:40 +02:00
|
|
|
$ cd build/
|
2023-07-21 00:37:02 +02:00
|
|
|
$ cmake ..
|
|
|
|
$ cmake --build .
|
|
|
|
```
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
A CMake target, also called `libweb`, is created. This makes it possible
|
|
|
|
to integrate `libweb` into CMake projects via `add_subdirectory` and
|
2023-07-28 01:27:19 +02:00
|
|
|
`target_link_libraries`. For example:
|
|
|
|
|
|
|
|
```cmake
|
|
|
|
project(example)
|
|
|
|
add_executable(${PROJECT_NAME} main.c)
|
2023-10-10 23:21:35 +02:00
|
|
|
add_subdirectory(libweb)
|
|
|
|
target_link_libraries(${PROJECT_NAME} PRIVATE libweb)
|
2023-07-28 01:27:19 +02:00
|
|
|
```
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
Additionally, `libweb` can be installed using the standard procedure
|
2023-09-27 21:55:13 +02:00
|
|
|
in CMake. As usual, a custom prefix can be assigned via the
|
|
|
|
`CMAKE_INSTALL_PREFIX` variable:
|
|
|
|
|
|
|
|
```sh
|
2023-10-10 23:21:35 +02:00
|
|
|
$ cmake --install build/ -DCMAKE_INSTALL_PREFIX=$HOME/libweb-prefix
|
2023-09-27 21:55:13 +02:00
|
|
|
```
|
|
|
|
|
2023-08-06 16:43:57 +02:00
|
|
|
### Examples
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
[A directory](examples) with examples shows how `libweb` can be used by
|
2023-08-06 16:43:57 +02:00
|
|
|
applications. These can be built from the top-level directory with:
|
|
|
|
|
|
|
|
```sh
|
|
|
|
$ make examples
|
|
|
|
```
|
|
|
|
|
|
|
|
In the case of CMake builds, examples are built by default. This can be turned
|
|
|
|
off by assigning `BUILD_EXAMPLES` to `OFF` or `0`:
|
|
|
|
|
|
|
|
```sh
|
|
|
|
$ mkdir build/
|
|
|
|
$ cd build/
|
|
|
|
$ cmake .. -DBUILD_EXAMPLES=OFF
|
|
|
|
$ cmake --build .
|
|
|
|
```
|
|
|
|
|
2023-07-21 00:37:02 +02:00
|
|
|
## Why this project?
|
|
|
|
|
2023-10-10 23:21:35 +02:00
|
|
|
Originally, `libweb` was part of the
|
2023-07-21 00:37:02 +02:00
|
|
|
[`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
|
|
|
|
HTTP/1.1 server implementation and other surrounding utilities.
|
|
|
|
|
|
|
|
Therefore, it made sense to keep all these components on a separate
|
|
|
|
repository that `slcl` could depend on. Additionally, this would also
|
|
|
|
benefit other applications interested in this implementation.
|
|
|
|
|
|
|
|
### Seriously, why _yet another_ new HTTP/1.1 implementation?
|
|
|
|
|
|
|
|
- Popular web server implementations, such as
|
|
|
|
[`apache`](https://httpd.apache.org/) or [`nginx`](https://nginx.net) are
|
|
|
|
standalone applications that can be configured to run other
|
|
|
|
applications in order to generate dynamic content, via a standard
|
|
|
|
interface called
|
|
|
|
[Common Gateway Interface](https://en.wikipedia.org/wiki/Common_Gateway_Interface)
|
|
|
|
, or CGI for short.
|
|
|
|
- However, those are vastly complex tools with many features and
|
|
|
|
options, whereas simplicity was one of the key design goals for
|
|
|
|
`slcl`.
|
|
|
|
- Additionally, tools such as `apache` or `nginx` place
|
|
|
|
configuration files into `/etc`, which makes it harder to run
|
|
|
|
multiple instances on the same machine. While not a strict
|
|
|
|
requirement from `slcl`, it was desirable to keep configuration as
|
|
|
|
simple as possible for administrators.
|
|
|
|
- The [`onion`](https://github.com/davidmoreno/onion) project, which
|
|
|
|
does follow the HTTP library concept, was initially considered for
|
2023-10-10 23:21:35 +02:00
|
|
|
`slcl`, but has a larger scope than `libweb`, and again simplicity was
|
2023-07-21 00:37:02 +02:00
|
|
|
essential for `slcl`.
|
|
|
|
- And, after all, it was a good excuse to learn about HTTP/1.1.
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
```
|
2023-10-10 23:21:35 +02:00
|
|
|
libweb, a simple and lightweight web framework.
|
2023-07-21 00:37:02 +02:00
|
|
|
Copyright (C) 2023 Xavier Del Campo Romero
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
```
|
|
|
|
|
|
|
|
Also, see [`LICENSE`](LICENSE).
|