This project has been created as part of the 42 curriculum by mikkayma, atursun, yalp.
This is when you finally understand why URLs start with HTTP.
webserv is a custom HTTP server implemented in C++98, built from scratch for the 42 curriculum.
The project focuses on understanding core web infrastructure concepts by implementing the server side manually:
- TCP sockets and connection lifecycle
- non-blocking I/O with a single event loop (
poll) - HTTP request parsing and HTTP response generation
- route-based configuration (Nginx-like
serverandlocationblocks) - static file serving, uploads, CGI execution, deletion and redirections
The executable is launched as:
./webserv [configuration file]In this repository, the default configuration is default.conf.
- Build a resilient server that does not hang on malformed or partial requests.
- Keep all socket I/O non-blocking and event-driven.
- Support real browser usage, not only synthetic tests.
- Implement and validate status-code behavior (
200,301,403,404,405,413,500, etc.). - Compare behavior against NGINX whenever interpretation is unclear.
- Methods:
GET,POST,DELETE - Route matching with configurable
locationblocks - Method allow-list per route (
allow_methods) - URL decoding support for encoded paths
- Query-string aware request path handling
- Static website serving from
www/ - Per-route
rootandindexbehavior - Autoindex directory listing (
autoindex on) - Custom error pages from
www/error_page/
- Upload endpoint support via
POST - Multipart form-data file extraction and persistence
- Delete files via
DELETEon configured routes
- CGI execution through
fork,pipe,dup2,execve - Python CGI configured via
.pyextension - Additional CGI path for
.blaextension using./cgi_tester - Request headers propagated as CGI environment variables (
HTTP_*) - Query string and body forwarding to CGI process
- Multiple
serverblocks in a single config file - Concurrent listening on at least:
0.0.0.0:80800.0.0.0:8088
- Validate command-line argument count.
- Open and parse configuration file.
- Create and configure one listening socket per server block.
- Switch sockets to non-blocking mode.
- Enter the
pollevent loop.
- A single
pollvector tracks listening sockets and connected clients. - New clients are accepted and added dynamically.
- Incoming bytes are appended into per-client buffers.
- Parsing waits until request completeness is detected.
- After response write, client connection is cleaned up when needed.
- Receive bytes using
recv. - Detect header/body boundary.
- Validate body completion using
Content-Lengthor chunk terminator. - Decode URL path.
- Match
locationand check method policy. - Dispatch to
GET,POST, orDELETEhandlers. - Build and send an HTTP response.
- Detect CGI route by extension (
.py,.bla). - Build CGI environment variables.
- Create stdin/stdout pipes.
- Fork process.
- Child executes interpreter/script in correct working directory.
- Parent writes body to CGI stdin and reads CGI stdout.
- Convert CGI output to final HTTP response.
The project uses an Nginx-like syntax with server {} and location {} blocks.
Current repository config: default.conf
listenserver_namerooterror_pageclient_max_body_sizelocationindexallow_methodsautoindexupload_pathcgi_pathcgi_extreturn(redirect)
/-> static index page/cgi-bin-> Python CGI scripts inwww/cgi-bin/uploads-> upload and delete target/test-> directory listing enabled/old-page->301redirect to/new-page.pyand.bla-> extension-based CGI rules
- Unix-like runtime environment (Linux or macOS recommended)
- C++ compiler supporting C++98
make- Python 3 for
.pyCGI endpoints
Windows users should run with WSL or another Unix-compatible environment.
makeMakefile rules available:
make all
make clean
make fclean
make reCompilation flags used by this repository:
-Wall -Wextra -Werror -std=c++98 -g
./webserv default.confIf the config file is missing or unreadable, startup fails with an error.
Press Ctrl+C to stop the server gracefully.
- Open
http://localhost:8088/ - Open
http://localhost:8088/ - Open
http://localhost:8088/test/for autoindex - Open
http://localhost:8088/old-pageand verify redirect to/new-page
Static page:
curl -i http://localhost:8080/Method restriction check (405 expected on /):
curl -i -X POST http://localhost:8080/Small body endpoint (/post_body has low body limit):
curl -i -X POST http://localhost:8080/post_body -d "hello"Upload file:
curl -i -X POST -F "file=@README.md" http://localhost:8088/uploadsDelete uploaded file:
curl -i -X DELETE http://localhost:8088/uploads/README.mdPython CGI:
curl -i "http://localhost:8080/cgi-bin/test.py?name=webserv"
curl -i -X POST http://localhost:8080/cgi-bin/test.py -d "hello=cgi"Custom extension CGI (.bla):
curl -i -X POST http://localhost:8080/YoupiBanane/youpi.bla -d "test=1"- Repeated concurrent requests with
ab,hey, or custom scripts. - Upload + CGI + static requests mixed in parallel.
- Large request body attempts to verify
413handling.
- HTTP parser aims at project scope and does not implement full RFC surface.
- Multipart parsing is practical but not a complete MIME implementation.
- Behavior is optimized for required methods/features, not full production hardening.
- HTTPS/TLS is out of scope.
- RFC 9112 (HTTP/1.1): https://datatracker.ietf.org/doc/html/rfc9112
- RFC 9110 (HTTP Semantics): https://datatracker.ietf.org/doc/html/rfc9110
- RFC 3875 (CGI 1.1): https://datatracker.ietf.org/doc/html/rfc3875
- Beej's Guide to Network Programming: https://beej.us/guide/bgnet/
- Linux
poll(2)manual: https://man7.org/linux/man-pages/man2/poll.2.html - NGINX docs (behavior comparison): https://nginx.org/en/docs/
AI tools were used in a controlled and review-first way for support tasks, not as a substitute for understanding.
What AI was used for:
- Summarizing RFC sections and protocol terminology
- Brainstorming test scenarios and edge cases
- Refining documentation language and structure
What AI was not used for:
- Blindly generating core server logic without review
- Replacing manual debugging, peer discussion, or validation
- Avoiding ownership of implementation decisions
Every AI-assisted output was checked, discussed, and validated through code review, manual testing, and peer feedback before acceptance.