This project has been created as part of the 42 curriculum by fsmyth, mganchev and abelov.
Webserv is a custom HTTP server developed in C++ as part of the 42 curriculum. Its goal is to implement a fully functional web server capable of handling HTTP/1.1 requests, managing multiple connections, executing CGI scripts, and providing flexible configuration similar to Nginx. The project demonstrates low-level network programming, process management, and robust configuration parsing.
To compile the project, run:
makeThis will build the webserv binary in the root directory.
To start the server with the default configuration:
./webservYou can specify a custom configuration file:
./webserv path/to/config.confA Dockerfile and docker-compose.yaml are provided for containerized deployment. To build and run with Docker:
docker-compose up --build- RFC 2616 - HTTP/1.1 Specification
- Nginx Documentation
- Beej's Guide to Network Programming
- UNIX man pages: signal, waitpid, fork, execve
AI was used to assist with:
- Generating documentation and README structure
- Providing explanations for signal handling, process management, and configuration parsing
- Drafting usage instructions and Docker integration steps
- HTTP/1.1 request handling
- CGI script execution
- Configurable server and location blocks
- Static file serving
- Custom error pages
- Logging and debugging utilities
- Docker support
- Written in modern C++ with STL
- Custom parser for configuration files
- Multi-process model for handling connections
- Signal handling for graceful shutdown and child process management
After starting the server, visit http://localhost:8080 in your browser. Configuration files can be found in the resources/ directory.
"In this project bugs usually come from lifetime and ownership confusion, and storing references inside polymorphic objects is a great way to manufacture that confusion." (c)
echo -n "param1=val1¶m2=val2" | \
REQUEST_METHOD=POST \
CONTENT_TYPE=application/x-www-form-urlencoded \
CONTENT_LENGTH=23 \
SCRIPT_NAME=/doodle/cgi-bin/index.php \
SCRIPT_FILENAME=/www/doodle/cgi-bin/index.php \
REDIRECT_STATUS=200 \
php-cgichmod +x ubuntu_cgi_tester
curl -v -X POST http://127.0.0.1:8080/directory/youpi.bla \
-H "Content-Type: plain/text" \
--data "BODY IS HERE"
dd if=/dev/zero bs=1M count=100 status=none | \
curl -v -X POST --data-binary @- \
-H "Content-Type: application/octet-stream" \
--no-progress-meter \
http://127.0.0.1:8080/directory/youpi.bla | xxddd if=/dev/zero bs=100 count=2 status=none | \
curl -v -X POST --data-binary @- \
-H "Content-Type: application/octet-stream" \
--no-progress-meter \
http://127.0.0.1:8080/post_bodydocker exec -it -u root webserv-nginx-1 bashecho 12346 | dd bs=1 count=3 status=nonesudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-pluginRFC 7230 (HTTP/1.1 Message Syntax and Routing) 6.3.2. Pipelining
RFC 9112 (HTTP/1.1) 9.3.2. Pipelining
printf 'HEAD / HTTP/1.1\r\nHost: www.google.com\r\nConnection: keep-alive\r\n\r\nHEAD /teapot HTTP/1.1\r\nHost: www.google.com\r\nConnection: close\r\n\r\n' \
| nc -N google.com 80
printf '%s' \
$'HEAD / HTTP/1.1\r\n'\
$'Host: www.google.com\r\n'\
$'Connection: keep-alive\r\n'\
$'\r\n'\
$'HEAD /teapot HTTP/1.1\r\n'\
$'Host: www.google.com\r\n'\
$'Connection: close\r\n'\
$'\r\n' \
| nc -N google.com 80
cat <<'EOF' | nc -N google.com 80
HEAD / HTTP/1.1
Host: www.google.com
Connection: keep-alive
HEAD /teapot HTTP/1.1
Host: www.google.com
Connection: close
EOF
printf 'GET / HTTP/1.1\r\nHost: localhost\r\nConnection: keep-alive\r\n\r\nGET /teapot HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' \
| nc -N 127.1 8080
curl --http1.1 -v http://127.0.0.1:8080/ http://127.0.0.1:8080/teapot