This project has been created as part of the 42 curriculum by anamedin, dasalaza, cpujades.
Webserv is a custom-built HTTP server written in C++98 entirely from scratch, designed to emulate the core behavior of industry-standard servers like NGINX.
The primary goal of this project is to understand the underlying mechanics of the HTTP protocol by implementing a fully functional, non-blocking multiplexed server capable of handling multiple concurrent clients. It parses custom configuration files, serves static content, handles file uploads, executes Common Gateway Interface (CGI) scripts (such as Python, PHP, or Bash), and responds with precise HTTP status codes and custom error pages.
This project reinforces modern network programming paradigms, including strict adherence to I/O multiplexing (epoll), resilient socket management, and robust request/response parsing according to the RFC semantical definitions.
Below are some of the diagrams that guided the design and implementation of Webserv:
The development and testing of Webserv were supported by the following tools and environments:
- Operating Systems: Linux, macOS
- IDEs/Editors: CLion, Vim, Neovim
- Code Quality: SonarQube
- AI Tools: Gemini, Grok, NotebookLM
- A UNIX-like operating system (Linux).
c++compiler (orclang++/g++) supporting the C++98 standard.- Have installed
make.
To compile the project and generate the webserver executable, run the following command at the root of the repository:
makeOther available make rules:
make all: Default rule, compiles the executable.make clean: Removes all compiled object files and dependencies (builddirectory).make fclean: Executescleanand removes thewebserverexecutable.make re: Executesfcleanfollowed byallto completely recompile the project.make debug: Compiles the project with debugging symbols enabled.make leaks: Compiles the project with memory leak instrumentation (-fsanitize=leak).make optimized: Compiles the project with maximum optimization flags (-O3).
The server requires a configuration file to run. A default configuration is provided in the config/ directory.
Execute the server by passing the path to a configuration file as an argument:
./webserver config/default.confIf no file is provided, it will fallback to .config/default.conf if configured as default in the source.
Once running, you can access the configured servers via your web browser or command-line tools like curl:
curl -v http://localhost:8080Assuming you are using config/default.conf, here are some quick tests:
-
1. Basic homepage (static content)
curl -v http://localhost:8080/
-
2. Trigger a custom 404 error page
curl -v http://localhost:8080/does-not-exist
-
3. Test CGI execution
curl -v "http://localhost:8080/cgi-bin/hello.py?name=Webserv" -
4. Upload a file (if
/uploadsandupload_storeare enabled in the config)curl -v -X POST -F "file=@README.md" http://localhost:8080/uploads/ -
5. Delete a file (if allowed by the location)
curl -v -X DELETE http://localhost:8080/uploads/README.md
The configuration file follows an NGINX‑style hierarchy of server and location blocks.
Below is a simplified example derived from config/default.conf:
server {
listen 8080:0.0.0.0;
root ./www;
index index.html index.htm;
client_max_body_size 10485760;
error_page 403 /errors/403.html;
error_page 404 /errors/404.html;
error_page 500 502 503 504 /errors/500.html;
# Default location: static content + uploads
location / {
autoindex off;
allow_methods GET POST HEAD DELETE;
}
# CGI scripts
location /cgi-bin/ {
root ./www/cgi-bin;
cgi .py /usr/bin/python3;
cgi .sh /bin/bash;
allow_methods GET POST;
}
}This illustrates how:
- A
serverblock defines listening address, root, indexes, and global error pages. - Nested
locationblocks specialize behavior for subpaths (static files, uploads, CGI endpoints, redirects, etc.).
During the development of Webserv, the following resources were instrumental in understanding network programming and the HTTP protocol:
- RFC 9110: HTTP Semantics: The primary reference for HTTP/1.1 syntax, status codes, and methodology.
- RFC 3875: The Common Gateway Interface (CGI) Version 1.1: Essential for understanding how to pass environment variables and execute scripts dynamically.
- Beej's Guide to Network Programming: The classic, indispensable tutorial for understanding sockets,
bind,listen,accept, and multiplexing functions.
- NGINX Core Configuration Source: Reference material used to understand the structure and parameters of a real-world server configuration file.
- How To Install Nginx on Ubuntu 20.04: A practical guide that helped conceptualize server environments and standard installation practices.
- Understanding Nginx Server and Location Block Selection Algorithms: Essential reading for implementing the logic that matches incoming requests to the correct server and location blocks.
- Understanding the Nginx Location Directive: Specific insights into how the
locationdirective behaves and how modifiers affect routing.
- The Linux Programming Interface: A comprehensive guide to Linux system programming, essential for understanding
epoll, sockets, and process management. - NGINX Cookbook: Advanced recipes for high-performance load balancing and web serving, useful for understanding edge-case configurations.
- UNIX Network Programming, Volume 1: The classic “bible” by W. Richard Stevens on socket-level programming in UNIX, covering the socket API, buffer management,
send()semantics, and concurrency patterns withselect()/epollthat inspired our I/O model. - HTTP: The Definitive Guide: The key reference we used to understand the HTTP “language”: how requests and responses must be structured (as in our
HttpResponse::serialize), status code semantics (e.g.405plus theAllowheader), and header-level rules.
Artificial Intelligence tools (such as conversational LLMs like Gemini and Grok, and NotebookLM for organizing design notes and documentation) were utilized during this project as a supplemental aid, specifically for:
- Documentation & Comments: Helping to formalize and understand concepts of diverse parts of the project.
- RFC Clarification: Summarizing complex concepts from the RFC documentation into more digestible explanations.



