Table of Contents
Webserv is a high-performance, non-blocking web server designed to replicate NGINX's functionality.
Developed in C++ for MacOS and Linux, it serves static websites, supports large file uploads and downloads, and is configurable to a high degree, just like NGINX.
It implements the HTTP protocol standards as defined in RFC 9112, RFC 9110, and RFC 3986.
- Multiple virtual servers IPv4 & IPv6 compatibles
- Customizable route serving, error pages, redirections, response codes
- Default index files for directory requests
- Limit on allowed request methods & client body size, directory listing on/off toggling
- CGI support for external program execution (RFC 3875)
- PHP and Perl interactive website examples with cookie and session management
- Multiple testers allowing a perfect CI flow
source configure && make install
You can change the installation directory with the INSTALLDIR
variable in the configure
file. By default, it is installed in $HOME/.local
.
webserv [configuration file]
Provide your own configuration file as first argument. Without it, $INSTALLDIR/etc/webserv/default.conf
is used as the default one.
The file default.conf
of this repository is used to run all the provided tests and examples.
The server root is the $INSTALLDIR/var/www/webserv
directory. After installation, it is a copy of the www
directory of this repository.
As with NGINX, use the root or alias directives in the virtual servers of your configuration file, to set a custom relative or absolute path for the files served in response to a request.
The requested are processed the same way as NGINX:
- Virtual servers listen to an
address[:port]
pair. If no port is given, they listen on port8000
. Without a given listen directive, they listen to*:8000
. - When a request reaches the web server through an
address[:port]
pair, the server_name directive selects which corresponding virtual server will serve it. If the request’sHost
header field does not match any virtual server name, the first virtual server with a matchingaddress[:port]
is used. - The selected virtual server searches for the most specific prefix location regardless of the listed order. Then it checks nested extension locations in the order listed. The first matching expression is the location used. If no expression matches the request, then the most specific prefix location found earlier is used.
The configuration file's structure is the same as the NGINX structure, with only the server{}
and location{}
blocks.
The directives are inherited: a child context inherits the settings of its parent level. For example, a server{}
block directive is inherited by all the location{}
blocks in it. However, when the same directive is defined again in a child context, it overrides the parent value.
Here are all the directives
Directive (links to NGINX version) |
Syntax | Default | Informations |
---|---|---|---|
listen | listen address[:port] ; |
listen *:8000; |
An address may be a hostname, a IPv4, or a IPv6 in square brackets (e.g.[::1] ). |
server_name | server_name name ... ; |
server_name ""; |
Names are case-insensitive. An IP is also a valid name. |
root | root path ; |
root html; |
Sets the root directory for requests. |
alias | alias path ; |
/ | Defines a replacement for the specified location. |
index | index file ; |
index index.html; |
Defines a file used as an index. |
return | return code [text] ; / return code URL ; / return URL ; |
/ | Specifies a redirect URL (for codes 301, 302, 303, 307, and 308) or the response body text (for other codes). A redirect URL can be a URI local to this server. |
error_page | error_page code ... uri ; |
/ | Defines the URI that will be shown for the specified error(s). |
cgi_pass | cgi_pass path ; |
/ | Defines a script to execute for requests at this specific location. |
client_max_body_size | client_max_body_size size ; |
/ | Sets the maximum allowed size of the client request body. |
ignore_except | ignore_except method ... ; |
/ | Ignores the location match for requests with the given method(s). |
limit_except | limit_except method ... ; |
/ | Returns 403 for requests with the given method(s). |
hide_limit_rule | hide_limit_rule on / off ; |
hide_limit_rule off; |
Returns 405 instead of 403 for requests hitting limit_except . |
autoindex | autoindex on / off ; |
autoindex off; |
Enables or disables the directory listing output. |
hide_directory | hide_directory on / off ; |
hide_directory off; |
Returns 404 instead of 403 for requests hitting a directory without autoindex . |
make debug
The compiled debug version is the webserv_debug
binary at the root of this repository. It has far more verbose and helpful logs.
Logs are stored in $INSTALLDIR/var/log/webserv.log
, and in /tmp/webserv.log
for the debug version.
If their size exceeds 20MB, they rotate in a new file, appending “.old“ to the previous one.
Three testing suites are provided:
- An extensive Python tester for HTTP protocol and configuration directives compliance
- A 42 tester for load stress-testing and large file exchanges with multiple clients
- A GoogleTest suite for configuration parsing and possible directives' values
Run the tests from the root of this repository with:
./tests/run_tests.sh
To enable the GoogleTest suite, you need to have CMake installed, then run:
make test
Important
To run correctly, the testers expect the default.conf
file of this repository, and $INSTALLDIR/var/www/webserv
to have at least the content of the www
directory of this repository.
Testers.mp4
Tip
source configure -u
This unsets the webserv-specific environment variables, cleans the PATH
variable if relevant, removes the installed binary, and all the webserv-related files (after asking for confirmation).
Caution
make uninstall
This removes the installed binary, the $INSTALLDIR/etc/webserv
configuration directory, and the $INSTALLDIR/var/www/webserv
directory serving your files (without asking for confirmation).
For more details on the HTTP protocol: