A lightweight HTTP/1.1 web server written in C++98, built from scratch with no external dependencies.
42 School project β reimplementing core web server behavior from the ground up.
WebServ is a fully functional HTTP/1.1 server implemented in C++. It handles real browser requests, serves static content, and executes CGI scripts β all driven by a custom configuration file inspired by NGINX syntax.
Internally, it uses epoll (Linux) for I/O multiplexing, allowing the server to monitor multiple client connections simultaneously within a single thread β no blocking, no busy-waiting. Each event (new connection, incoming data, response ready) is dispatched through a non-blocking event loop, keeping the server responsive under concurrent load.
CGI processes are spawned via fork + execve, with communication handled through pipes (stdin/stdout). A timeout mechanism ensures hanging scripts don't stall the server indefinitely.
- β HTTP/1.1 β GET, POST, DELETE methods
- π Static file serving β HTML, CSS, JS, images, and more
- π£οΈ Static routes β define URL-to-directory mappings via config
- βοΈ CGI support β execute scripts (Python, PHP, etc.) on the server side
- π Config file β flexible server configuration (ports, hosts, routes, error pages...)
- π« Custom error pages β 404, 403, 500 and more
- π Redirections β HTTP 301/302 support
- π¦ No external dependencies β pure C++98 stdlib only
WebServ uses epoll (Linux) to handle multiple concurrent connections within a single thread. All sockets β server and clients β are set to non-blocking mode. The event loop monitors file descriptors and reacts only when data is actually ready, avoiding busy-waiting entirely.
epoll_wait() βββΊ event on fd
βββ server socket β accept() new client
βββ client socket β read request / send response
βββ CGI pipe β read script output
This means the server never blocks on a single slow client, and can handle many simultaneous connections efficiently without threading.
accept() β parse HTTP request β match location block
β serve file / redirect / exec CGI
β build HTTP response β send() β close or keep-alive
CGI scripts are launched via fork() + execve(). The server communicates with the child process through a pipe: request body is written to stdin, and the script's stdout is read back as the response body. A timeout mechanism kills stalled CGI processes to prevent the server from hanging.
clang++make- Unix-based OS (Linux / macOS)
git clone https://github.com/Biny17/webserv.git
cd webserv
make./webserv [config_file]If no config file is provided, the server uses a default configuration.
./webserv config/server.confThen open your browser at http://localhost:8080.
The config file follows an NGINX-inspired syntax. Here's a minimal example:
server {
listen 8080;
server_name localhost;
root ./www;
index index.html;
error_page 404 /errors/404.html;
location / {
allow_methods GET POST;
autoindex on;
}
location /upload {
allow_methods POST;
root ./www/uploads;
}
}| Directive | Description |
|---|---|
listen |
Port to listen on |
server_name |
Virtual host name |
root |
Root directory for file serving |
index |
Default file to serve |
error_page |
Custom error pages |
allow_methods |
Allowed HTTP methods per location |
autoindex |
Enable/disable directory listing |
return |
HTTP redirect |
cgi_extension |
Allowed CGI extensions |
client_max_body_size |
Max request body size |
WebServ can execute CGI scripts based on file extension.
location /cgi-bin {
allow_methods GET POST;
cgi_extension .py .sh .rb;
}CGI scripts receive request data via environment variables and stdin, and return their response through stdout β following the CGI/1.1 standard.
webserv/
βββ cgi-bin/ # CGI scripts
βββ config/ # Configuration files
βββ headers/ # Header files (.hpp)
βββ srcs/ # Source files (.cpp)
β βββ cgi/ # CGI execution (fork, pipe, env)
β βββ classes/ # Core classes (Server, Client, Request, Response...)
β βββ conf/ # Config file parser
β βββ handle_request/ # GET / DELETE response logic
β βββ network/ # Epoll event loop, client handling
β βββ utils/ # Helpers (autoindex, encoding, path...)
βββ www/ # Default web root
βββ Makefile
βββ README.md
| Name | GitHub |
|---|---|
| Anicet Gruet | @Anicet78 |
| Tom Pinton | @Snak00s |
| Tristan Biny | @Biny17 |