A high-performance HTTP/1.0 web server written in C++98 from scratch, featuring non-blocking I/O with poll, CGI support, and RFC 1945 compliance.
- Features
- Quick Start
- Installation
- Configuration
- Testing
- Performance
- Architecture
- Documentation
- Examples
- ✅ HTTP/1.0 Protocol - Full RFC 1945 compliance
- ✅ Multiple HTTP Methods - GET, POST, DELETE
- ✅ Non-Blocking I/O - Using poll for multiplexing
- ✅ Virtual Hosts - Multiple servers on different ports
- ✅ CGI Execution - Python, PHP, and other script support
- ✅ File Uploads - Multipart/form-data handling
- ✅ Static File Serving - With proper MIME type detection
- 🔒 Security - Path traversal protection
- 📁 Directory Listing - Configurable autoindex
- 🎯 Custom Routes - Flexible location-based configuration
- ⚙️ Configurable - Nginx-style configuration file
- 🚦 Error Pages - Custom 403, 404, 50x pages
- 📊 Performance - 4,400+ requests/second with 100 concurrent users
- 💾 Zero Memory Leaks - Verified with valgrind
# Clone the repository
git clone https://github.com/dragon-piece/Webserv.git
cd Webserv
# Compile
make
# Run with default configuration
./webserv test.conf
# Access the server
open http://localhost:8080- C++ Compiler with C++98 support (g++ or clang++)
- Make build system
- Python 3 (for CGI and tests)
make # Compile the server
make clean # Remove object files
make fclean # Remove all build artifacts
make re # Rebuild from scratchConfiguration uses an Nginx-style syntax. Here's a minimal example:
http {
server {
listen 8080;
server_name localhost;
root ./server_files;
index index.html;
client_max_body_size 10M;
location / {
allowed_methods GET POST;
autoindex on;
}
location /upload {
allowed_methods POST DELETE;
upload_path ./server_files/uploads;
}
location /cgi {
allowed_methods GET POST;
cgi_extension .py;
cgi_path /usr/bin/python3;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
}
}| Directive | Context | Description |
|---|---|---|
listen |
server | Port and host to bind to |
server_name |
server | Virtual host names |
root |
server, location | Document root directory |
index |
server, location | Default index files |
autoindex |
server, location | Enable directory listing |
allowed_methods |
location | Allowed HTTP methods |
client_max_body_size |
server, location | Maximum request body size |
upload_path |
location | Directory for file uploads |
cgi_extension |
location | CGI file extension |
cgi_path |
location | Path to CGI interpreter |
error_page |
server, location | Custom error pages |
See SERVER_SETUP.md for complete configuration examples.
The project includes a full test suite with 7 categories and 55+ individual tests:
cd tests
python3 run_all_tests.py- HTTP Methods - GET, POST, DELETE validation
- Static Files - File serving and MIME types
- File Upload - Multipart form data handling
- CGI Execution - Script execution and environment
- Error Handling - HTTP error codes (403, 404, 500, etc.)
- Configuration - Multi-port, routes, limits
- Stress Testing - Concurrent connections, load testing
cd tests
python3 menu.py # Interactive test menu# Test GET request
curl http://localhost:8080/
# Test file upload
curl -X POST -F "file=@test.txt" http://localhost:8080/upload
# Test CGI
curl http://localhost:8080/cgi/hello.py
# Test DELETE
curl -X DELETE http://localhost:8080/uploads/test.txt- Throughput: 4,416 requests/second
- Concurrency: 100 simultaneous users (99.56 average)
- Latency: 0.02s average response time
- Availability: 100% (no failed requests)
- Transactions: 121,939 successful in 27.61 seconds
- Memory: Zero leaks (valgrind verified)
- Stability: No crashes under load
Siege Benchmark:
Transactions: 121,939 hits
Availability: 100.00 %
Elapsed time: 27.61 secs
Data transferred: 122.13 MB
Response time: 0.02 secs
Transaction rate: 4,416.48 trans/sec
Throughput: 4.42 MB/sec
Concurrency: 99.56
Successful: 121,939
Failed: 0
webserv/
├── config/ # Configuration parser
│ ├── ConfigParser.cpp # Nginx-style config parser
│ ├── ServerConfig.cpp # Server configuration
│ └── Tokenizer.cpp # Lexical analyzer
├── src/ # Core server implementation
│ ├── main.cpp # Entry point and event loop
│ ├── handleClient.cpp # Request/response handling
│ └── classes/ # Request, Response, Client classes
├── server_files/ # Web content and assets
└── tests/ # Comprehensive test suite
- Event-Driven - Non-blocking I/O with poll multiplexing
- State Machine - Request parsing and processing
- Strategy Pattern - Different handlers for HTTP methods
- Factory Pattern - Response generation
Client Connection
↓
Accept & Add to poll
↓
Read Request (non-blocking)
↓
Parse HTTP Request
↓
Route Matching
↓
[Static File | CGI | Upload | Error]
↓
Generate Response
↓
Send Response (non-blocking)
↓
Close
Once the server is running, visit:
- Homepage: http://localhost:8080
- Documentation: http://localhost:8080/docs/
- Upload Interface: http://localhost:8080/upload.html
http {
server {
listen 8080;
root ./www;
index index.html;
location / {
allowed_methods GET;
autoindex on;
}
}
}http {
server {
listen 8080;
root ./server_files;
client_max_body_size 10M;
location /upload {
allowed_methods POST DELETE;
upload_path ./uploads;
}
location /uploads {
allowed_methods GET DELETE;
autoindex on;
}
}
}http {
server {
listen 8080;
root ./server_files;
location /cgi {
allowed_methods GET POST;
cgi_extension .py;
cgi_path /usr/bin/python3;
}
}
}http {
# Main server
server {
listen 8080;
server_name www.example.com;
root ./site1;
}
# Alternative server
server {
listen 8081;
server_name api.example.com;
root ./site2;
}
}- Path Traversal Protection - Blocks
..in URIs - Method Restrictions - Per-location HTTP method filtering
- Upload Size Limits - Configurable max body size
- Error Handling - No information leakage in errors
- Input Validation - Strict HTTP parsing
Built using C++98 | 4,400+ req/s | Zero memory leaks | 100% test coverage