A minimal yet production-grade HTTP/1.1 server written in pure C (C11) using POSIX sockets.
- HTTP/1.1 Protocol Support: GET, POST, and HEAD methods
- Concurrent Connections: Uses epoll for efficient event-driven I/O
- Static File Serving: Serves files with proper MIME types
- Configurable: Port and root directory configurable via command-line
- Security: Path traversal prevention, input validation
- Graceful Shutdown: Handles SIGINT/SIGTERM signals
- Logging: Comprehensive request/response logging with verbose mode
- Modular Architecture: Clean separation of concerns (networking, parsing, routing, response)
The server is organized into modular components:
- http_server: Core networking and epoll event loop
- parser: HTTP request parsing and validation
- router: URL routing and request dispatching
- response: HTTP response generation and file serving
- logger: Logging system with multiple log levels
- Linux operating system
- GCC compiler with C11 support
- POSIX-compliant system libraries
# Build the server
make
# Build with debug symbols
make debug
# Build with optimizations
make release
# Clean build artifacts
make clean# Run with default settings (port 8080, ./public as root)
./http_server
# Specify custom port and root directory
./http_server -p 3000 -r /var/www/html
# Enable verbose logging
./http_server -v
# Show help
./http_server -h-p, --port PORT: Port to listen on (default: 8080)-r, --root DIR: Root directory for static files (default: ./public)-v, --verbose: Enable verbose logging-h, --help: Show help message
# Create test directory structure
make setup-test
# Run the server
make run
# In another terminal, test with curl
curl http://localhost:8080/
curl http://localhost:8080/style.css
curl -X POST -d "test=data" http://localhost:8080/api
# Test with browser
# Open http://localhost:8080 in your browser- Path Traversal Prevention: All file paths are sanitized and validated
- Input Validation: Request parsing includes bounds checking
- Directory Listing Prevention: Directories cannot be served directly
- Root Directory Enforcement: Files outside the configured root cannot be accessed
- All dynamically allocated memory is properly freed
- Request structures are cleaned up after handling
- No memory leaks in normal operation
The server handles SIGINT (Ctrl+C) and SIGTERM signals gracefully:
- Stops accepting new connections
- Completes in-flight requests
- Cleans up all resources
- Logs shutdown event
- HTTP/1.1 only (no HTTP/2 support)
- No HTTPS/TLS support
- No CGI/FastCGI support
- Simple POST handling (logs data, returns JSON response)
- Linux-only (uses epoll)
See LICENSE file for details.